diff --git a/src/generate.ts b/src/generate.ts index e5f09cae..13ee7e8f 100644 --- a/src/generate.ts +++ b/src/generate.ts @@ -1,15 +1,48 @@ import {DefaultCodeGenerator} from '@oas3/codegen/ts/generator'; const fs = require('fs'); -export function generate() { - const filePath = './oasTestSpecs.json'; - const dataStr = fs.readFileSync(filePath, 'utf-8').toString(); - const data = JSON.parse(dataStr); - const codeGenerator = new DefaultCodeGenerator(data); - codeGenerator.generate({ - targetFolderPath: './generated-files', - predefinedFolderPaths: [['booking', 'core']], +type OutputPath = string[]; + +export type GenerateConfig = { + type: 'oas3'; + getSpecification: () => Promise; + outputFolderPath: string; + importRootAlias?: string; + predefinedFolderOutputPaths?: OutputPath[]; +}; + +export function generate(config: GenerateConfig) { + switch (config.type) { + case 'oas3': + // eslint-disable-next-line no-case-declarations + config.getSpecification().then(data => { + const codeGenerator = new DefaultCodeGenerator(data); + codeGenerator.generate({ + outputFolderPath: config.outputFolderPath, + predefinedFolderOutputPaths: config.predefinedFolderOutputPaths, + }); + }); + break; + default: + console.error(''); + } +} + +// todo: move this code to the outside of the package +export function usePackage() { + generate({ + type: 'oas3', + getSpecification: () => { + return new Promise(resolve => { + const filePath = './oasTestSpecs.json'; + const dataStr = fs.readFileSync(filePath, 'utf-8').toString(); + const data = JSON.parse(dataStr); + resolve(data); + }); + }, + outputFolderPath: './generated-files', + predefinedFolderOutputPaths: [['booking', 'core']], }); } -generate(); +usePackage(); diff --git a/src/oas3/codegen/ts/core.ts b/src/oas3/codegen/ts/core.ts index 79b8d6f3..60f26139 100644 --- a/src/oas3/codegen/ts/core.ts +++ b/src/oas3/codegen/ts/core.ts @@ -37,6 +37,13 @@ export function areOutputPathsEqual(a: OutputPath, b: OutputPath): boolean { ); } +export function containsOutputPath( + outputPaths: OutputPath[], + outputPath: OutputPath +): boolean { + return !!outputPaths.find(p => areOutputPathsEqual(p, outputPath)); +} + export function doesOutputPathStartWithOtherOutputPath( outputPath: OutputPath, otherOutputPath: OutputPath diff --git a/src/oas3/codegen/ts/endpoint.ts b/src/oas3/codegen/ts/endpoint.ts index b2a1b279..0db5bc20 100644 --- a/src/oas3/codegen/ts/endpoint.ts +++ b/src/oas3/codegen/ts/endpoint.ts @@ -1,11 +1,7 @@ import {CodeGenerator, OutputType, OutputPath, DefinitionOutput} from './core'; import {Request} from '@oas3/specification'; import {applyResponseByStatusCodeMap} from './response'; -import { - templateRequestHandlerType, - templateRequestResultType, - templateRequestType, -} from './template'; +import {templateRequestResultType, templateRequestType} from './template'; export const responseOutputPathPart = 'response6b3a7814'; export const requestResultOutputPathPart = 'requestResult6b3a7814'; @@ -95,7 +91,6 @@ export function applyEndpointCallerFunction( endpointIdConstDefinition.path, templateRequestType.path, requestResultTypeDefinition.path, - templateRequestHandlerType.path, ], }; codeGenerator.addOutput(funcDefinition); diff --git a/src/oas3/codegen/ts/generator.ts b/src/oas3/codegen/ts/generator.ts index 68306773..2581b817 100644 --- a/src/oas3/codegen/ts/generator.ts +++ b/src/oas3/codegen/ts/generator.ts @@ -93,9 +93,9 @@ const componentResponsesFileNameOutputPathPart = 'responses6b3a7814'; const componentSchemasFileNameOutputPathPart = 'schemas6b3a7814'; type GenerateConfig = { - targetFolderPath: string; + outputFolderPath: string; importRootAlias?: string; - predefinedFolderPaths?: OutputPath[]; + predefinedFolderOutputPaths?: OutputPath[]; }; export class DefaultCodeGenerator implements CodeGenerator { @@ -124,7 +124,7 @@ export class DefaultCodeGenerator implements CodeGenerator { } private initializeOperationFolderOutputPaths(config: GenerateConfig) { - this.operationFolderOutputPaths = config.predefinedFolderPaths ?? []; + this.operationFolderOutputPaths = config.predefinedFolderOutputPaths ?? []; for (const path in this.oas3Specs.paths) { const requestByMethodMap = this.oas3Specs.paths[path]; for (const method in requestByMethodMap) { @@ -141,7 +141,7 @@ export class DefaultCodeGenerator implements CodeGenerator { fileOutputByFilePath: FileOutputByFilePath, config: GenerateConfig ) { - const cleanTargetFolderPath = cleanUpFolderPath(config.targetFolderPath); + const cleanTargetFolderPath = cleanUpFolderPath(config.outputFolderPath); fs.cpSync(__dirname + '../../../../templates/ts', cleanTargetFolderPath, { recursive: true, }); diff --git a/src/oas3/codegen/ts/response.ts b/src/oas3/codegen/ts/response.ts index a51e608f..144258a3 100644 --- a/src/oas3/codegen/ts/response.ts +++ b/src/oas3/codegen/ts/response.ts @@ -9,6 +9,7 @@ import { OutputType, OutputPath, DefinitionOutput, + containsOutputPath, } from './core'; import {applyComponentRefSchema, applySchema} from './schema'; import { @@ -58,15 +59,29 @@ export function applyResponseByStatusCodeMap( path: OutputPath ): DefinitionOutput { const statusCodeResponseOutputs: CodeGenerationOutput[] = []; + const requiredOutputPaths: OutputPath[] = []; for (const statusCode in schema) { const responseOutputPath: OutputPath = [...path, statusCode]; const responseOrRef = schema[statusCode]; if (isResponseComponentRef(responseOrRef)) { - const responseBodyOutput = applyComponentRefSchema( + const jsonResponseBody = applyComponentRefSchema( codeGenerator, responseOrRef, [...responseOutputPath, 'body'] ); + if (!containsOutputPath(requiredOutputPaths, templateResponseType.path)) { + requiredOutputPaths.push(templateResponseType.path); + } + if ( + !containsOutputPath(requiredOutputPaths, templateStatusCodeEnum.path) + ) { + requiredOutputPaths.push(templateStatusCodeEnum.path); + } + if ( + !containsOutputPath(requiredOutputPaths, templateStatusCodeEnum.path) + ) { + requiredOutputPaths.push(jsonResponseBody.path); + } const responseOutput: CodeGenerationOutput = { createCode: referencingPath => { const responseType = templateResponseType.createName(path); @@ -74,14 +89,14 @@ export function applyResponseByStatusCodeMap( const statusCodeEnumEntry = getTemplateResponseStatusCodeEnumEntry( parseInt(statusCode) ); - const bodyCode = responseBodyOutput.createCode(referencingPath); + const bodyCode = jsonResponseBody.createCode(referencingPath); return `${responseType}<${statusCodeEnum}.${statusCodeEnumEntry}, ${bodyCode}>`; }, path: responseOutputPath, requiredOutputPaths: [ templateResponseType.path, templateStatusCodeEnum.path, - responseBodyOutput.path, + jsonResponseBody.path, ], }; statusCodeResponseOutputs.push(responseOutput); @@ -98,6 +113,9 @@ export function applyResponseByStatusCodeMap( parseInt(statusCode), jsonResponseBody ); + if (!containsOutputPath(requiredOutputPaths, statusCodeResponseType.path)) { + requiredOutputPaths.push(statusCodeResponseType.path); + } statusCodeResponseOutputs.push({ createCode: referencingPath => { return statusCodeResponseType.createName(referencingPath); @@ -123,7 +141,7 @@ export function applyResponseByStatusCodeMap( }); return `${codeParts.join('\n')}`; }, - requiredOutputPaths: statusCodeResponseOutputs.map(o => o.path), + requiredOutputPaths, }; codeGenerator.addOutput(responseTypeDefinition); return responseTypeDefinition;