Skip to content

Commit

Permalink
fix(parser): export service types from single namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
mrlubos committed Apr 11, 2024
1 parent 74d1e2f commit 674d2e7
Show file tree
Hide file tree
Showing 29 changed files with 1,465 additions and 1,653 deletions.
5 changes: 5 additions & 0 deletions .changeset/lovely-oranges-mate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hey-api/openapi-ts": patch
---

fix: export service types from single namespace
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export interface OnCancel {
(cancelHandler: () => void): void;
}

export class CancelablePromise<T> implements Promise<T> {
export class CancelablePromise<T = void> implements Promise<T> {
private _isResolved: boolean;
private _isRejected: boolean;
private _isCancelled: boolean;
Expand Down
27 changes: 13 additions & 14 deletions packages/openapi-ts/src/utils/handlebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,19 @@ export const nameOperationDataType = (
const path = `${exported}['${operation.path}']['${operation.method.toLocaleLowerCase()}']['${namespace}']`;
return name && typeof name === 'string' ? `${path}['${name}']` : path;
}
if (namespace === 'res') {
const path = `${exported}['${operation.path}']['${operation.method.toLocaleLowerCase()}']['${namespace}']`;
return name && typeof name === 'string' ? `${path}['${name}']` : path;
const results = operation.results.filter(result => result.code >= 200 && result.code < 300);
// TODO: we should return nothing when results don't exist
// can't remove this logic without removing request/name config
// as it complicates things
if (!results.length) {
return 'void';
}
return results
.map(result => {
const path = `${exported}['${operation.path}']['${operation.method.toLocaleLowerCase()}']['${namespace}'][${String(result.code)}]`;
return path;
})
.join(' | ');

Check warning on line 136 in packages/openapi-ts/src/utils/handlebars.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/utils/handlebars.ts#L119-L136

Added lines #L119 - L136 were not covered by tests
};

export const registerHandlebarHelpers = (): void => {
Expand Down Expand Up @@ -170,17 +179,7 @@ export const registerHandlebarHelpers = (): void => {
);

Handlebars.registerHelper('modelIsRequired', modelIsRequired);

Handlebars.registerHelper(
'nameOperationDataType',
function (
namespace: 'req' | 'res',
operation: Service['operations'][number],
name: string | undefined
) {
return nameOperationDataType(namespace, operation, name);
}
);
Handlebars.registerHelper('nameOperationDataType', nameOperationDataType);

Handlebars.registerHelper(
'notEquals',
Expand Down
149 changes: 62 additions & 87 deletions packages/openapi-ts/src/utils/write/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,126 +79,101 @@ const processModel = (client: Client, model: Model) => {
};

const processServiceTypes = (services: Service[]) => {
type ReqMap = Map<number, OperationParameter[]>;
type Base = string;
type MethodMap = Map<'req' | 'res', Base | ReqMap | OperationParameter[]>;
type ResMap = Map<number, string>;
type MethodMap = Map<'req' | 'res', ResMap | OperationParameter[]>;
type MethodKey = Service['operations'][number]['method'];
type PathMap = Map<MethodKey, MethodMap>;

const pathsMap = new Map<string, PathMap>();

services.forEach(service => {
service.operations.forEach(operation => {
let pathMap = pathsMap.get(operation.path);
if (!pathMap) {
pathsMap.set(operation.path, new Map());
pathMap = pathsMap.get(operation.path)!;
}
const hasReq = operation.parameters.length;
const hasRes = operation.results.length;

let methodMap = pathMap.get(operation.method);
if (!methodMap) {
pathMap.set(operation.method, new Map());
methodMap = pathMap.get(operation.method)!;
}
if (hasReq || hasRes) {
let pathMap = pathsMap.get(operation.path);
if (!pathMap) {
pathsMap.set(operation.path, new Map());
pathMap = pathsMap.get(operation.path)!;
}

if (operation.parameters.length) {
methodMap.set('req', operation.parameters);
}
let methodMap = pathMap.get(operation.method);
if (!methodMap) {
pathMap.set(operation.method, new Map());
methodMap = pathMap.get(operation.method)!;
}

// operation.results.forEach(result => {
// let reqMap = methodMap.get('req');
// if (!reqMap) {
// methodMap.set('req', new Map());
// reqMap = methodMap.get('req')!;
// }
if (hasReq) {
methodMap.set('req', sortByName([...operation.parameters]));
}

// if (typeof reqMap === 'string') {
// return;
// }
if (hasRes) {
let resMap = methodMap.get('res');
if (!resMap) {
methodMap.set('res', new Map());
resMap = methodMap.get('res')!;

Check warning on line 115 in packages/openapi-ts/src/utils/write/models.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/utils/write/models.ts#L82-L115

Added lines #L82 - L115 were not covered by tests
}

// reqMap.set(
// // result.code,
// 200,
// operation.parameters,
// );
// })
if (Array.isArray(resMap)) {
return;
}

methodMap.set(
'res',
!operation.results.length ? 'void' : operation.results.map(result => toType(result)).join(' | ')
);
operation.results.forEach(result => {
resMap.set(result.code, toType(result)!);
});
}
}
});
});

const properties = Array.from(pathsMap).map(([path, pathMap]) => {
const pathParameters = Array.from(pathMap).map(([method, methodMap]) => {
const methodParameters = Array.from(methodMap).map(([name, baseOrReqMap]) => {
if (typeof baseOrReqMap !== 'string') {
const reqParameters = Array.isArray(baseOrReqMap)
? baseOrReqMap
: Array.from(baseOrReqMap).map(([code, operationParameters]) => {
const value: Model = {
$refs: [],
base: '',
description: null,
enum: [],
enums: [],
export: 'interface',
imports: [],
isDefinition: false,
isNullable: false,
isReadOnly: false,
isRequired: true,
link: null,
name: String(code),
// TODO: move query params into separate query key
properties: sortByName([...operationParameters]),
template: null,
type: '',
};
return value;
});

const reqKey: Model = {
$refs: [],
base: '',
description: null,
enum: [],
enums: [],
export: 'interface',
imports: [],
isDefinition: false,
isNullable: false,
isReadOnly: false,
isRequired: true,
link: null,
name,
properties: reqParameters,
template: null,
type: '',
};
return reqKey;
}
const methodParameters = Array.from(methodMap).map(([name, baseOrResMap]) => {
const reqResParameters = Array.isArray(baseOrResMap)
? baseOrResMap
: Array.from(baseOrResMap).map(([code, base]) => {
const value: Model = {
$refs: [],
base,
description: null,
enum: [],
enums: [],
export: 'generic',
imports: [],
isDefinition: false,
isNullable: false,
isReadOnly: false,
isRequired: true,
link: null,
name: String(code),
// TODO: move query params into separate query key
properties: [],
template: null,
type: '',
};
return value;
});

const value: Model = {
const reqResKey: Model = {
$refs: [],
base: baseOrReqMap,
base: '',
description: null,
enum: [],
enums: [],
export: 'generic',
export: 'interface',
imports: [],
isDefinition: false,
isNullable: false,
isReadOnly: false,
isRequired: true,
link: null,
name,
properties: [],
properties: reqResParameters,
template: null,
type: '',
};
return value;
return reqResKey;
});
const methodKey: Model = {
$refs: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export interface OnCancel {
(cancelHandler: () => void): void;
}

export class CancelablePromise<T> implements Promise<T> {
export class CancelablePromise<T = void> implements Promise<T> {
private _isResolved: boolean;
private _isRejected: boolean;
private _isCancelled: boolean;
Expand Down
Loading

0 comments on commit 674d2e7

Please sign in to comment.