113 lines
3.5 KiB
TypeScript
113 lines
3.5 KiB
TypeScript
|
import { copyFile, readFile } from "fs/promises";
|
||
|
import * as handlebars from 'handlebars';
|
||
|
import { join } from 'path';
|
||
|
import { Project } from "ts-morph";
|
||
|
import { IExportMethodToOpenAPIParameters } from "../openapi/nopeOpenAPIDecorators";
|
||
|
import { DecoratorInformation, MethodInformation } from "./analyzeTypescriptFiles";
|
||
|
import { createFile } from "./fileHelpers";
|
||
|
import { generateSchemas } from "./generateSchemas";
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Generate the Client Templates.
|
||
|
* @param options
|
||
|
*/
|
||
|
export async function generateOpenAPI(options: {
|
||
|
pathToSchemaTemplate: string,
|
||
|
pathToApiTemplate: string,
|
||
|
tempDir: string,
|
||
|
inputDir: string,
|
||
|
tsConfigFilePath: string,
|
||
|
}) {
|
||
|
|
||
|
// Create the Output dir (if it doenst exists)
|
||
|
const { schemaMapping, analysis } = await generateSchemas(options)
|
||
|
|
||
|
// load the File.
|
||
|
const typescriptTemplate = await readFile(options.pathToApiTemplate, {
|
||
|
encoding: 'utf-8'
|
||
|
})
|
||
|
|
||
|
// Renderfuncting
|
||
|
const renderAPI = handlebars.compile(typescriptTemplate);
|
||
|
|
||
|
const methods: (IExportMethodToOpenAPIParameters & MethodInformation & DecoratorInformation & {
|
||
|
className: string,
|
||
|
baseUri: string,
|
||
|
methodUri: string,
|
||
|
useCustomParameters: boolean,
|
||
|
useDefaultParameters: boolean,
|
||
|
customParameters: string,
|
||
|
inputSchema: string,
|
||
|
outputSchema: string
|
||
|
})[] = []
|
||
|
|
||
|
// Firstly copy the nopeDispatcher
|
||
|
await copyFile(
|
||
|
join(__dirname, '..', '..', '..', 'lib', 'dispatcher', 'nopeDispatcher.ts'),
|
||
|
join(options.tempDir, 'api', 'nopeDispatcher.ts')
|
||
|
);
|
||
|
|
||
|
for (const relevantClass of analysis) {
|
||
|
for (const method of relevantClass.methods) {
|
||
|
const settings: {
|
||
|
className: string,
|
||
|
baseUri: string,
|
||
|
methodUri: string,
|
||
|
useCustomParameters: boolean,
|
||
|
useDefaultParameters: boolean,
|
||
|
customParameters: string,
|
||
|
inputSchema: string,
|
||
|
outputSchema: string
|
||
|
} = {
|
||
|
className: relevantClass.className,
|
||
|
baseUri: relevantClass.classDecorator.decoratorSettings.exportsElementsToOpenAPI.uri || relevantClass.className,
|
||
|
methodUri: method.decoratorSettings.exportMethodToOpenAPI.uri || method.name,
|
||
|
customParameters: JSON.stringify(method.decoratorSettings.exportMethodToOpenAPI.parameters || [], undefined, 4),
|
||
|
useCustomParameters: Array.isArray(method.decoratorSettings.exportMethodToOpenAPI.parameters),
|
||
|
useDefaultParameters: method.params.length > 0,
|
||
|
inputSchema: JSON.stringify(schemaMapping[relevantClass.className], undefined, 4),
|
||
|
outputSchema: JSON.stringify(schemaMapping[relevantClass.className], undefined, 4)
|
||
|
}
|
||
|
|
||
|
const item = Object.assign(
|
||
|
method,
|
||
|
{
|
||
|
method: method.params.length > 0 ? 'POST' : 'GET'
|
||
|
},
|
||
|
settings,
|
||
|
method.decoratorSettings.exportMethodToOpenAPI as IExportMethodToOpenAPIParameters
|
||
|
);
|
||
|
|
||
|
methods.push(item);
|
||
|
|
||
|
const fileName = join(options.tempDir, 'api', item.baseUri, item.methodUri + '.ts');
|
||
|
|
||
|
// Write down the Schema:
|
||
|
await createFile(
|
||
|
// Generate the Path.
|
||
|
fileName,
|
||
|
renderAPI(item)
|
||
|
);
|
||
|
|
||
|
// Function to Determine new project files.
|
||
|
const project = new Project({
|
||
|
tsConfigFilePath: options.tsConfigFilePath,
|
||
|
addFilesFromTsConfig: false,
|
||
|
});
|
||
|
|
||
|
project.addSourceFileAtPath(fileName);
|
||
|
|
||
|
// Readin the Source-Files.
|
||
|
const sourceFiles = project.getSourceFiles();
|
||
|
|
||
|
for (const file of sourceFiles) {
|
||
|
file.formatText();
|
||
|
await file.save();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return schemaMapping;
|
||
|
}
|