Skip to content

Commit

Permalink
add aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
pyramation committed May 25, 2024
1 parent 55775a4 commit 0d78ec2
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 87 deletions.
6 changes: 5 additions & 1 deletion __fixtures__/output/swagger-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12327,7 +12327,11 @@ export class KubernetesClient extends APIClient {
const path = `/api/v1/persistentvolumes/${params.path.name}/status`;
return await this.patch<PersistentVolume>(path, params.body);
}
async listCoreV1PodForAllNamespaces(params: ListCoreV1PodForAllNamespacesRequest): Promise<PodList> {
async getPods(params: ListCoreV1PodForAllNamespacesRequest): Promise<PodList> {
const path = `/api/v1/pods`;
return await this.get<PodList>(path);
}
async listPods(params: ListCoreV1PodForAllNamespacesRequest): Promise<PodList> {
const path = `/api/v1/pods`;
return await this.get<PodList>(path);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25674,7 +25674,11 @@ export class KubernetesClient extends APIClient {
const path = \`/api/v1/persistentvolumes/\${params.path.name}/status\`;
return await this.patch<PersistentVolume>(path, params.body);
}
async listCoreV1PodForAllNamespaces(params: ListCoreV1PodForAllNamespacesRequest): Promise<PodList> {
async getPods(params: ListCoreV1PodForAllNamespacesRequest): Promise<PodList> {
const path = \`/api/v1/pods\`;
return await this.get<PodList>(path);
}
async listPods(params: ListCoreV1PodForAllNamespacesRequest): Promise<PodList> {
const path = \`/api/v1/pods\`;
return await this.get<PodList>(path);
}
Expand Down
11 changes: 10 additions & 1 deletion packages/schema-sdk/__tests__/openapi.generate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getDefaultSchemaSDKOptions } from '../src/types';

it('swagger', () => {
const options = getDefaultSchemaSDKOptions({
clientName: 'KubernetesClient',
includeSwaggerUrl: true,
exclude: [
'*.v1beta1.*',
Expand All @@ -17,7 +18,14 @@ it('swagger', () => {
});
const code = generateOpenApiClient({
...options,
// version: 'v1',
operationNamingStrategy: {
aliases: {
listCoreV1PodForAllNamespaces: 'getPods'
},
renameMap: {
listCoreV1PodForAllNamespaces: 'listPods'
}
},
paths: {
exclude: [
'*flowschema*',
Expand Down Expand Up @@ -58,6 +66,7 @@ it('merged', () => {
// include: [
// '*.v1.*'
// ],
clientName: 'KubernetesClient',
includeSwaggerUrl: true,
includeMethodComments: true,
namingStrategy: {
Expand Down
192 changes: 121 additions & 71 deletions packages/schema-sdk/src/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ export function generateOpenApiParams(options: OpenAPIOptions, path: string, pat
}
});

const typeName = toPascalCase(getOperationMethodName(operation, method, path)) + 'Request';
const typeName = getOperationTypeName(options, operation, method, path) + 'Request';
const paramsInterface = t.tsInterfaceDeclaration(
t.identifier(typeName),
null,
Expand Down Expand Up @@ -361,12 +361,115 @@ export function generateOpenApiTypes(options: OpenAPIOptions, schema: OpenAPISpe
return interfaces.map(i => t.exportNamedDeclaration(i));
}

const getOperationMethodName = (operation: Operation, method: string, path: string) => {
const methodName = operation.operationId || toCamelCase(method + path.replace(/\W/g, '_'));
const getOperationMethodName = (
options: OpenAPIOptions,
operation: Operation,
method: string,
path: string
) => {
const defaultMethodName = toCamelCase(method + path.replace(/\W/g, '_'));
const methodName = operation.operationId || defaultMethodName;

if (options?.operationNamingStrategy?.renameMap) {
return options.operationNamingStrategy.renameMap[methodName] || methodName;
}

return methodName;
};

export function generateMethods(options: OpenAPIOptions, schema: OpenAPISpec): t.ClassMethod[] {
const getOperationTypeName = (
options: OpenAPIOptions,
operation: Operation,
method: string,
path: string
) => {
const defaultMethodName = toCamelCase(method + path.replace(/\W/g, '_'));
const methodName = operation.operationId || defaultMethodName;

if (!options?.operationNamingStrategy?.renameTypes) {
return toPascalCase(methodName);
}

if (options?.operationNamingStrategy?.renameMap) {
return toPascalCase(options.operationNamingStrategy.renameMap[methodName] || methodName);
}

return methodName;
};

export const createOperation = (
options: OpenAPIOptions,
operation: Operation,
path: string,
method: string,
alias?: string
): t.ClassMethod => {
const typeName = getOperationTypeName(options, operation, method, path) + 'Request';
const id = t.identifier('params');
id.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier(typeName)));
const params = [id];

const returnType = getOperationReturnType(options, operation, method);
const methodName = getOperationMethodName(options, operation, method, path);

const callMethod = t.callExpression(
t.memberExpression(
t.thisExpression(),
t.identifier(method)
),
['post', 'put', 'patch', 'formData'].includes(method) ?
[
t.identifier('path'),
t.memberExpression(
t.identifier('params'),
t.identifier('body')
)
] : [
t.identifier('path')
]
);
callMethod.typeParameters = t.tsTypeParameterInstantiation([
returnType
]);

const methodFunction = t.classMethod(
'method',
t.identifier(alias ? toCamelCase(alias) : methodName),
params,
t.blockStatement([
t.variableDeclaration('const', [
t.variableDeclarator(
t.identifier('path'),
createPathTemplateLiteral(options, path)
)
]),
t.returnStatement(
t.awaitExpression(
callMethod
)
)
]),
false,
false,
false,
true
);
methodFunction.returnType = t.tsTypeAnnotation(
t.tsTypeReference(
t.identifier('Promise'),
t.tsTypeParameterInstantiation([
returnType
])
)
);

return methodFunction;
};

export function generateMethods(
options: OpenAPIOptions,
schema: OpenAPISpec
): t.ClassMethod[] {
const methods: t.ClassMethod[] = [];

// Iterate through each path and each method in the path
Expand All @@ -380,67 +483,11 @@ export function generateMethods(options: OpenAPIOptions, schema: OpenAPISpec): t
const operation: Operation = pathItem[method];
if (!shouldIncludeOperation(options, pathItem, path, method as any)) return;


const typeName = toPascalCase(getOperationMethodName(operation, method, path)) + 'Request';
const id = t.identifier('params');
id.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier(typeName)));
const params = [id];

const returnType = getOperationReturnType(options, operation, method);
const methodName = getOperationMethodName(operation, method, path);



const callMethod = t.callExpression(
t.memberExpression(
t.thisExpression(),
t.identifier(method)
),
['post', 'put', 'patch', 'formData'].includes(method) ?
[
t.identifier('path'),
t.memberExpression(
t.identifier('params'),
t.identifier('body')
)
] : [
t.identifier('path')
]
);
callMethod.typeParameters = t.tsTypeParameterInstantiation([
returnType
]);
const methodFunction = t.classMethod(
'method',
t.identifier(methodName),
params,
t.blockStatement([
t.variableDeclaration('const', [
t.variableDeclarator(
t.identifier('path'),
createPathTemplateLiteral(options, path)
)
]),
t.returnStatement(
t.awaitExpression(
callMethod
)
)
]),
false,
false,
false,
true
);
methodFunction.returnType = t.tsTypeAnnotation(
t.tsTypeReference(
t.identifier('Promise'),
t.tsTypeParameterInstantiation([
returnType
])
)
);
methods.push(methodFunction);
const alias = options.operationNamingStrategy?.aliases?.[operation.operationId];
if (alias) {
methods.push(createOperation(options, operation, path, method, alias));
}
methods.push(createOperation(options, operation, path, method));
}

});
Expand Down Expand Up @@ -476,7 +523,10 @@ export const getSwaggerJSONMethod = (): t.ClassMethod => {
);
};

export function generateOpenApiClient(options: OpenAPIOptions, schema: OpenAPISpec): string {
export function generateOpenApiClient(
options: OpenAPIOptions,
schema: OpenAPISpec
): string {
const methods = [];
if (options.includeSwaggerUrl) {
methods.push(getSwaggerJSONMethod());
Expand All @@ -498,21 +548,21 @@ export function generateOpenApiClient(options: OpenAPIOptions, schema: OpenAPISp
]);

const clientClass = t.exportNamedDeclaration(t.classDeclaration(
t.identifier('KubernetesClient'),
t.identifier(options.clientName),
t.identifier('APIClient'),
classBody,
[]
));

//// INTERFACES
const kubeSchema = {
title: 'Kubernetes',
const apiSchema = {
title: options.clientName,
definitions: schema.definitions
};

const types = generateTypeScriptTypes(kubeSchema, {
const types = generateTypeScriptTypes(apiSchema, {
...(options as any),
exclude: ['Kubernetes', ...(options.exclude ?? [])]
exclude: [options.clientName, ...(options.exclude ?? [])]
});
const openApiTypes = generateOpenApiTypes(options, schema);

Expand Down
41 changes: 28 additions & 13 deletions packages/schema-sdk/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,41 @@ import type { DeepPartial } from 'schema-typescript';
import { defaultSchemaTSOptions, SchemaTSOptions } from 'schema-typescript';

export interface OpenAPIOptions extends SchemaTSOptions {
version?: 'v1' | 'v1beta1' | 'v2beta1' | 'v2beta2';
mergedParams?: boolean;
includeSwaggerUrl?: boolean;
paths?: {
// Include/Exclude types
include?: string[];
exclude?: string[];
clientName: string;
version?: 'v1' | 'v1beta1' | 'v2beta1' | 'v2beta2';
mergedParams?: boolean;
includeSwaggerUrl?: boolean;
operationNamingStrategy?: {
renameTypes?: boolean;
renameMap?: {
[originalName: string]: string;
};
aliases?: {
[originalName: string]: string;
};
}
paths?: {
// Include/Exclude types
include?: string[];
exclude?: string[];

includeTags?: string[];
excludeTags?: string[];
includeTags?: string[];
excludeTags?: string[];

includeRequests?: string[];
excludeRequests?: string[];
}
includeRequests?: string[];
excludeRequests?: string[];
}
}

export const defaultSchemaSDKOptions: OpenAPIOptions = {
export const defaultSchemaSDKOptions: Partial<OpenAPIOptions> = {
...defaultSchemaTSOptions,
clientName: 'Client',
mergedParams: false,
includeSwaggerUrl: false,
operationNamingStrategy: {
renameMap: {},
aliases: {}
},
paths: {
include: [],
exclude: [],
Expand Down

0 comments on commit 0d78ec2

Please sign in to comment.