119 lines
3.2 KiB
TypeScript
119 lines
3.2 KiB
TypeScript
|
import { readFile } from "fs/promises";
|
||
|
import * as handlebars from 'handlebars';
|
||
|
import { join } from 'path';
|
||
|
import { Project } from "ts-morph";
|
||
|
import * as TJS from "typescript-json-schema";
|
||
|
import { IJsonSchema } from "../../types/IJSONSchema";
|
||
|
import { analyzeFiles, defaultClassFilter, defaultPropFilter } from "./analyzeTypescriptFiles";
|
||
|
import { createFile, createPath } from "./fileHelpers";
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Generate the Client Templates.
|
||
|
* @param options
|
||
|
*/
|
||
|
export async function generateSchemas(options: {
|
||
|
pathToTemplate: string,
|
||
|
tempDir: string,
|
||
|
inputDir: string,
|
||
|
tsConfigFilePath: string,
|
||
|
}) {
|
||
|
|
||
|
// Create the Output dir (if it doenst exists)
|
||
|
await createPath(options.tempDir);
|
||
|
|
||
|
// Function to Determine new project files.
|
||
|
const project = new Project({
|
||
|
tsConfigFilePath: options.tsConfigFilePath,
|
||
|
addFilesFromTsConfig: false,
|
||
|
});
|
||
|
|
||
|
project.addSourceFilesAtPaths(options.inputDir);
|
||
|
|
||
|
// Readin the Source-Files.
|
||
|
const sourceFiles = project.getSourceFiles();
|
||
|
|
||
|
// Generate the Files
|
||
|
const result = analyzeFiles(sourceFiles, {
|
||
|
classDecorator: 'exportsElementsToOpenAPI',
|
||
|
methodDecorator: 'exportMethodToOpenAPI',
|
||
|
propertyDecorator: 'exportPropertyToOpenAPI',
|
||
|
filterClasses: defaultClassFilter({
|
||
|
classDecorator: 'exportsElementsToOpenAPI',
|
||
|
classInterface: ''
|
||
|
}),
|
||
|
filterMethods: (cl, method) => {
|
||
|
return method.isImplementation && method.isAsync && method.params.filter(param => param.baseType === 'function').length === 0
|
||
|
},
|
||
|
filterProperties: defaultPropFilter({
|
||
|
propertyDecorator: 'exportPropertyToDispatcher',
|
||
|
propertyType: 'nopeObservable'
|
||
|
}),
|
||
|
checkImport: type => type !== 'nopeObservable'
|
||
|
}
|
||
|
);
|
||
|
|
||
|
// load the File.
|
||
|
const template = await readFile(options.pathToTemplate, {
|
||
|
encoding: 'utf-8'
|
||
|
})
|
||
|
|
||
|
// Renderfuncting
|
||
|
const render = handlebars.compile(template);
|
||
|
|
||
|
// Generate the Files.
|
||
|
const files: {
|
||
|
className: string,
|
||
|
name: string,
|
||
|
content: string,
|
||
|
}[] = result.map(item => {
|
||
|
return {
|
||
|
className: item.className,
|
||
|
name: item.className + 'Schema',
|
||
|
content: render(item)
|
||
|
}
|
||
|
});
|
||
|
|
||
|
for (const file of files) {
|
||
|
await createFile(
|
||
|
// Generate the Path.
|
||
|
join(options.tempDir, 'classes', file.name + '.ts'),
|
||
|
file.content
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// After all files has been written => Generate the Schemas:
|
||
|
const _settings: TJS.PartialArgs = {
|
||
|
required: true
|
||
|
};
|
||
|
|
||
|
// Options for the TJS.Compiler;
|
||
|
const compilerOptions: TJS.CompilerOptions = {
|
||
|
strictNullChecks: true,
|
||
|
skipLibCheck: true
|
||
|
};
|
||
|
|
||
|
const schemaMapping: { [index: string]: IJsonSchema } = {};
|
||
|
|
||
|
for (const file of files) {
|
||
|
const _program = TJS.getProgramFromFiles(
|
||
|
[join(options.tempDir, 'classes', file.name + '.ts')],
|
||
|
compilerOptions
|
||
|
);
|
||
|
|
||
|
// We can either get the schema for one file and one type...
|
||
|
const _schema = TJS.generateSchema(_program, "*", _settings);
|
||
|
// Receive the Element
|
||
|
schemaMapping[file.className] = JSON.parse(JSON.stringify(_schema)) as IJsonSchema;
|
||
|
|
||
|
// Write down the Schema:
|
||
|
await createFile(
|
||
|
// Generate the Path.
|
||
|
join(options.tempDir, 'schema', file.name + '.json'),
|
||
|
JSON.stringify(_schema, undefined, 4)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
return schemaMapping;
|
||
|
}
|