mfdoc
Version:
Auto generate JS SDK and HTTP API documentation
192 lines • 7.57 kB
JavaScript
import assert from 'assert';
import fse from 'fs-extra';
import { forEach, get, last, set } from 'lodash-es';
import { posix } from 'path';
import { getEndpointsFromSrcPath } from './getEndpointsFromSrcPath.js';
import { kMfdocHttpHeaderItems } from './headers.js';
import { mfdocConstruct, } from './mfdoc.js';
import { kMfdocHttpResponseItems } from './response.js';
import { filterEndpoints, getEndpointNames } from './utils.js';
function generateEndpointInfoFromEndpoints(params) {
const { endpoints, includeTags, ignoreTags, includeTagsRegExp, ignoreTagsRegExp, includePaths, ignorePaths, includePathsRegExp, ignorePathsRegExp, includeNames, ignoreNames, includeNamesRegExp, ignoreNamesRegExp, } = params;
const infoMap = new Map();
const pickedEndpoints = filterEndpoints(endpoints, {
includeTags,
ignoreTags,
includeTagsRegExp,
ignoreTagsRegExp,
includePaths,
ignorePaths,
includePathsRegExp,
ignorePathsRegExp,
includeNames,
ignoreNames,
includeNamesRegExp,
ignoreNamesRegExp,
});
forEach(pickedEndpoints, endpoint => {
const inf = mfdocConstruct.constructHttpEndpointDefinition({
...endpoint,
errorResponseHeaders: endpoint.errorResponseHeaders ??
kMfdocHttpHeaderItems.responseHeaders_JsonContentType,
errorResponseBody: endpoint.errorResponseBody ?? kMfdocHttpResponseItems.errorResponseBody,
});
infoMap.set(endpoint, JSON.stringify(inf, /** replacer */ undefined, /** spaces */ 4));
});
return infoMap;
}
async function writeEndpointInfoToFile(endpointPath, info) {
await fse.ensureFile(endpointPath);
console.log('endpoint:', endpointPath);
return fse.writeFile(endpointPath, info, { encoding: 'utf-8' });
}
async function writeTableOfContentToFile(tableOfContent, outputPath, filename) {
const tableOfContentPath = posix.normalize(outputPath + '/' + filename);
await fse.ensureFile(tableOfContentPath);
console.log('table of content:', tableOfContentPath);
return fse.writeFile(tableOfContentPath, JSON.stringify(tableOfContent, /** replacer */ undefined, /** spaces */ 4), { encoding: 'utf-8' });
}
function setEndpointInTableOfContent(params) {
const { tableOfContent, endpointNames, endpointFilepath, backfillParents } = params;
const p = endpointNames.join('.children.');
const basename = last(endpointNames);
assert.ok(basename, 'basename is required');
const existing = get(tableOfContent.children, p);
const item = {
basename,
filepath: endpointFilepath,
names: endpointNames,
children: existing?.children ?? {},
};
set(tableOfContent.children, p, item);
if (backfillParents) {
endpointNames.forEach((name, index) => {
if (index < endpointNames.length - 1) {
setEndpointInTableOfContent({
tableOfContent,
endpointNames: endpointNames.slice(0, index + 1),
endpointFilepath: undefined,
backfillParents: false,
});
}
});
}
}
export async function genHttpApiEndpointsInfo(params) {
const { endpoints, includeTags, ignoreTags, includeTagsRegExp, ignoreTagsRegExp, includePaths, ignorePaths, includePathsRegExp, ignorePathsRegExp, includeNames, ignoreNames, includeNamesRegExp, ignoreNamesRegExp, outputPath, } = params;
const infoMap = generateEndpointInfoFromEndpoints({
endpoints,
includeTags,
ignoreTags,
includeTagsRegExp,
ignoreTagsRegExp,
includePaths,
ignorePaths,
includePathsRegExp,
ignorePathsRegExp,
includeNames,
ignoreNames,
includeNamesRegExp,
ignoreNamesRegExp,
});
const promises = [];
const tableOfContent = {
basename: '',
names: [],
children: {},
};
await fse.remove(outputPath);
infoMap.forEach((info, endpoint) => {
const names = getEndpointNames(endpoint);
const method = endpoint.method;
const namesWithMethod = [
...names.slice(0, -1),
`${names[names.length - 1]}__${method}`,
];
const filepath = `${namesWithMethod.join('/')}.json`;
const endpointPath = posix.normalize(outputPath + '/' + filepath);
promises.push(writeEndpointInfoToFile(endpointPath, info));
setEndpointInTableOfContent({
tableOfContent,
endpointNames: namesWithMethod,
endpointFilepath: filepath,
backfillParents: true,
});
});
await Promise.all(promises);
await writeTableOfContentToFile(Object.values(tableOfContent.children), outputPath, 'table-of-content.json');
}
export async function genHttpApiEndpointsInfoCmd(params) {
const { srcPath, includeTags, ignoreTags, includeTagsRegExp, ignoreTagsRegExp, includePaths, ignorePaths, includePathsRegExp, ignorePathsRegExp, includeNames, ignoreNames, includeNamesRegExp, ignoreNamesRegExp, outputPath, } = params;
const endpoints = await getEndpointsFromSrcPath({ srcPath });
const filteredEndpoints = filterEndpoints(endpoints, {
includeTags,
ignoreTags,
includeTagsRegExp,
ignoreTagsRegExp,
includePaths,
ignorePaths,
includePathsRegExp,
ignorePathsRegExp,
includeNames,
ignoreNames,
includeNamesRegExp,
ignoreNamesRegExp,
});
console.log('endpoints count', filteredEndpoints.length);
if (includeTags && includeTags.length > 0) {
console.log('includeTags', includeTags);
}
if (ignoreTags && ignoreTags.length > 0) {
console.log('ignoreTags', ignoreTags);
}
if (includeTagsRegExp && includeTagsRegExp.length > 0) {
console.log('includeTagsRegExp', includeTagsRegExp);
}
if (ignoreTagsRegExp && ignoreTagsRegExp.length > 0) {
console.log('ignoreTagsRegExp', ignoreTagsRegExp);
}
if (includePaths && includePaths.length > 0) {
console.log('includePaths', includePaths);
}
if (ignorePaths && ignorePaths.length > 0) {
console.log('ignorePaths', ignorePaths);
}
if (includePathsRegExp && includePathsRegExp.length > 0) {
console.log('includePathsRegExp', includePathsRegExp);
}
if (ignorePathsRegExp && ignorePathsRegExp.length > 0) {
console.log('ignorePathsRegExp', ignorePathsRegExp);
}
if (includeNames && includeNames.length > 0) {
console.log('includeNames', includeNames);
}
if (ignoreNames && ignoreNames.length > 0) {
console.log('ignoreNames', ignoreNames);
}
if (includeNamesRegExp && includeNamesRegExp.length > 0) {
console.log('includeNamesRegExp', includeNamesRegExp);
}
if (ignoreNamesRegExp && ignoreNamesRegExp.length > 0) {
console.log('ignoreNamesRegExp', ignoreNamesRegExp);
}
console.log('outputPath', outputPath);
console.log('--------------------------------');
await genHttpApiEndpointsInfo({
endpoints: filteredEndpoints,
includeTags,
ignoreTags,
includeTagsRegExp,
ignoreTagsRegExp,
includePaths,
ignorePaths,
includePathsRegExp,
ignorePathsRegExp,
includeNames,
ignoreNames,
includeNamesRegExp,
ignoreNamesRegExp,
outputPath,
});
}
//# sourceMappingURL=genHttpApiEndpointsInfo.js.map