feat: replace route markdown with openapi

This commit is contained in:
Rainer Killinger
2021-07-06 10:51:05 +02:00
parent a1e820336f
commit f4bf7abc89
9 changed files with 262 additions and 129 deletions

View File

@@ -15,10 +15,12 @@
import {Logger} from '@openstapps/logger';
import {Command} from 'commander';
import {existsSync, readFileSync, writeFileSync} from 'fs';
import {copy} from 'fs-extra';
import got from 'got';
import {join, resolve} from 'path';
import {join, relative, resolve} from 'path';
import {exit} from 'process';
import {
capitalize,
getProjectReflection,
mkdirPromisified,
readFilePromisified,
@@ -26,9 +28,10 @@ import {
} from './common';
import {generateTemplate} from './mapping';
import {pack} from './pack';
import {openapi3Template} from './resources/openapi-303-template';
import {
gatherRouteInformation,
generateDocumentationForRoute,
generateOpenAPIForRoute,
getNodeMetaInformationMap,
} from './routes';
import {Converter, getValidatableTypesFromReflection} from './schema';
@@ -55,33 +58,68 @@ commander
).version);
commander
.command('routes <srcPath> <mdPath>')
.action(async (relativeSrcPath, relativeMdPath) => {
.command('openapi <srcPath> <outDirPath>')
.action(async (relativeSrcPath, relativeOutDirPath) => {
// get absolute paths
const srcPath = resolve(relativeSrcPath);
const mdPath = resolve(relativeMdPath);
const outDirPath = resolve(relativeOutDirPath);
const outDirSchemasPath = join(outDirPath, 'schemas');
// get project reflection
const projectReflection = getProjectReflection(srcPath);
// get information about routes
const routes = await gatherRouteInformation(projectReflection);
routes.sort((a, b) => a.route.urlFragment.localeCompare(b.route.urlFragment));
// initialize markdown output
let output = '# Routes\n\n';
// change url path parameters to openapi notation
routes.forEach((routeWithMetaInformation) => {
routeWithMetaInformation.route.urlFragment = routeWithMetaInformation.route.urlFragment.replace(/:\w+/g, (match) => `{${match.replace(':','')}}`);
});
// keep openapi tags for routes that actually share url fragments
let tagsToKeep = routes.map((routeWithMetaInformation) => capitalize(routeWithMetaInformation.route.urlFragment.split('/')[1]));
tagsToKeep = tagsToKeep.filter((element, i, array) => array.indexOf(element) === i && array.lastIndexOf(element) !== i);
// initialize json output
const output = openapi3Template;
// names of the schemas to copy
const schemasToCopy: string[] = [];
// generate documentation for all routes
routes.forEach((routeWithMetaInformation) => {
output += generateDocumentationForRoute(
routeWithMetaInformation.tags = [capitalize(routeWithMetaInformation.route.urlFragment.split('/')[1])];
output.paths[routeWithMetaInformation.route.urlFragment] = generateOpenAPIForRoute(
routeWithMetaInformation,
getNodeMetaInformationMap(projectReflection),
relative(relativeOutDirPath,outDirSchemasPath),
schemasToCopy,
tagsToKeep,
);
});
// write documentation to file
writeFileSync(mdPath, output);
// copy schema json schema files
try {
if (!existsSync(outDirSchemasPath)){
await mkdirPromisified(outDirSchemasPath, {
recursive: true,
});
}
for (const fileName of schemasToCopy) {
await copy(join(srcPath, 'schema', `${fileName}.json`), join(outDirSchemasPath, `${fileName}.json`));
}
} catch (error) {
await Logger.error(error);
// tslint:disable-next-line: no-magic-numbers
process.exit(-2);
}
Logger.ok(`Route documentation written to ${mdPath}.`);
// write openapi object to file (prettified)
// tslint:disable-next-line: no-magic-numbers
writeFileSync(join(outDirPath, 'openapi.json'), JSON.stringify(output, null, 2));
Logger.ok(`OpenAPI representation resources written to ${outDirPath} .`);
});
commander