@svengroup/openapi-to-pdf
Version:
Create PDF API reference documentation from OpenAPI 3.0.x specification files.
244 lines (243 loc) • 10.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = generateEndpointsMarkdown;
exports.getActualTags = getActualTags;
exports.getTagObject = getTagObject;
exports.getOperationsFromPath = getOperationsFromPath;
exports.generateTagMarkdown = generateTagMarkdown;
exports.generateOperationsWithTagsMarkdown = generateOperationsWithTagsMarkdown;
exports.generateUntaggedOperationsMarkdown = generateUntaggedOperationsMarkdown;
exports.generateOperationMarkdown = generateOperationMarkdown;
exports.generateOperationTitleMarkdown = generateOperationTitleMarkdown;
exports.getParameters = getParameters;
exports.generateOperationSecurityMarkdown = generateOperationSecurityMarkdown;
exports.generateMediaTypeMarkdown = generateMediaTypeMarkdown;
const request_1 = require("../../markdown/endpoints/request");
const schema_1 = require("../../markdown/schema");
const response_1 = require("../../markdown/endpoints/response");
const merge_1 = require("../../utils/merge");
const toc_1 = require("../../markdown/toc");
const http_1 = require("../../utils/http");
let untagged_operations = {};
function generateEndpointsMarkdown(schema, config) {
let endpoints_str = "";
endpoints_str += `# ${config?.headings?.endpoints ?? 'Endpoints'}`;
endpoints_str += "\n\n";
const tags = schema.tags;
const paths = schema.paths;
const actual_tags = getActualTags(paths);
if (actual_tags.length > 0) {
endpoints_str += generateOperationsWithTagsMarkdown(paths, actual_tags, tags, config);
}
else {
endpoints_str += generateOperationsMarkdown(paths);
}
untagged_operations = {};
return endpoints_str;
}
function getActualTags(paths) {
let actual_tags = [];
for (const key_value of Object.entries(paths)) {
const path_item = key_value[1];
for (const [key, value] of Object.entries(path_item)) {
if ((0, http_1.isMethod)(key)) {
/** @ts-expect-error http method key always operation obj */
if (value.tags) {
/** @ts-expect-error http method key always operation obj */
actual_tags = [...actual_tags, ...value.tags];
}
}
}
}
actual_tags = [...new Set(actual_tags)];
return actual_tags;
}
function getTagObject(name, tags) {
if (!tags) {
return null;
}
for (const tag of tags) {
if (tag.name === name) {
return tag;
}
}
return null;
}
function getOperationsFromPath(path_item, tag, find_no_tag) {
const operations = {};
for (const [key, value] of Object.entries(path_item)) {
if ((0, http_1.isMethod)(key)) {
if (find_no_tag) {
/** @ts-expect-error http method key always operation obj */
if (!value.tags) {
/** @ts-expect-error http method key always operation obj */
operations[key] = value;
}
}
else if (tag) {
/** @ts-expect-error http method key always operation obj */
if (value.tags?.includes(tag)) {
/** @ts-expect-error http method key always operation obj */
operations[key] = value;
}
}
else {
/** @ts-expect-error http method key always operation obj */
operations[key] = value;
}
}
}
return operations;
}
function generateTagMarkdown(actual_tag, tags) {
let endpoints_str = "";
endpoints_str += `## ${actual_tag}`;
endpoints_str += "\n\n";
const tag = getTagObject(actual_tag, tags);
if (tag?.description) {
endpoints_str += tag.description;
endpoints_str += "\n\n";
}
if (tag?.externalDocs?.url) {
endpoints_str += `Read more about this category here: [${tag?.externalDocs?.url}](${tag?.externalDocs?.url})`;
endpoints_str += "\n\n";
}
return endpoints_str;
}
function generateOperationsMarkdown(paths, actual_tag) {
let endpoints_str = "";
const h = actual_tag ? "#" : ""; // prefix for headers (if tag is used or not)
let operations_toc = [];
for (const [path, path_item] of Object.entries(paths)) {
const operations = getOperationsFromPath(path_item, actual_tag);
if (actual_tag) {
const untagged_operations_of_path = getOperationsFromPath(path_item, undefined, true);
if (Object.keys(untagged_operations_of_path).length > 0) {
if (untagged_operations[path]) {
untagged_operations[path] = { ...untagged_operations[path], ...untagged_operations_of_path };
}
else {
untagged_operations[path] = untagged_operations_of_path;
}
}
}
for (const [method, operation] of Object.entries(operations)) {
const operation_title = generateOperationTitleMarkdown(h, path, method, operation);
operations_toc = [...operations_toc, ...(0, toc_1.getToc)(operation_title)];
endpoints_str += operation_title;
endpoints_str += generateOperationMarkdown(h, operation, path_item);
}
}
const toc_markdown = (0, toc_1.generateSubSectionTocMarkdown)(operations_toc);
return toc_markdown + endpoints_str;
}
function generateOperationsWithTagsMarkdown(paths, actual_tags, tags, config) {
let endpoints_str = "";
for (const actual_tag of actual_tags) {
/* TAG */
endpoints_str += generateTagMarkdown(actual_tag, tags);
/* OPERATIONS */
endpoints_str += generateOperationsMarkdown(paths, actual_tag);
}
/* UNTAGGED */
endpoints_str += generateUntaggedOperationsMarkdown(tags, config);
/* TAGS TOC */
const tags_toc = (0, toc_1.getToc)(endpoints_str, [2]);
const tags_toc_str = (0, toc_1.generateSubSectionTocMarkdown)(tags_toc);
return tags_toc_str + endpoints_str;
}
;
function generateUntaggedOperationsMarkdown(tags, config) {
let endpoints_str = "";
if (Object.keys(untagged_operations).length > 0) {
let operations_toc = [];
for (const [path, operations] of Object.entries(untagged_operations)) {
for (const [method, operation] of Object.entries(operations)) {
const operation_title = generateOperationTitleMarkdown("#", path, method, operation);
operations_toc = [...operations_toc, ...(0, toc_1.getToc)(operation_title)];
endpoints_str += operation_title;
endpoints_str += generateOperationMarkdown("#", operation);
}
}
const toc_markdown = (0, toc_1.generateSubSectionTocMarkdown)(operations_toc);
const tag_title_markdown = generateTagMarkdown(config?.headings?.untagged_endpoints ?? "Uncategorized", tags);
endpoints_str = tag_title_markdown + toc_markdown + endpoints_str;
}
return endpoints_str;
}
function generateOperationMarkdown(h, operation, path_item) {
let endpoints_str = "";
if (operation.summary) {
endpoints_str += operation.summary;
endpoints_str += "\n\n";
}
if (operation.description) {
endpoints_str += operation.description;
endpoints_str += "\n\n";
}
if (operation.externalDocs?.url) {
endpoints_str += `Read more about this API endpoint here: [${operation.externalDocs.url}](${operation.externalDocs.url})`;
endpoints_str += "\n\n";
}
endpoints_str += generateOperationSecurityMarkdown(h, operation.security);
/** @ts-expect-error we resolve all references */
const parameters = getParameters(path_item?.parameters, operation.parameters);
endpoints_str += (0, request_1.generateParametersMarkdown)(h, 'path', parameters);
endpoints_str += (0, request_1.generateParametersMarkdown)(h, 'query', parameters);
endpoints_str += (0, request_1.generateParametersMarkdown)(h, 'header', parameters);
endpoints_str += (0, request_1.generateParametersMarkdown)(h, 'cookie', parameters);
/** @ts-expect-error we resolve all references */
endpoints_str += (0, request_1.generateRequestBodyMarkdown)(h, operation.requestBody);
endpoints_str += (0, response_1.generateResponsesMarkdown)(h, operation.responses);
return endpoints_str;
}
function generateOperationTitleMarkdown(h, path, method, operation) {
let endpoints_str = "";
endpoints_str += `${h}## \`${method.toUpperCase()} ${path}\`${operation.operationId ? `(${operation.operationId})` : ''}`;
endpoints_str += "\n\n";
return endpoints_str;
}
function getParameters(path_parameters, operation_parameters) {
if (path_parameters && !operation_parameters) {
return path_parameters;
}
else if (!path_parameters && operation_parameters) {
return operation_parameters;
}
else if (path_parameters && operation_parameters) {
return (0, merge_1.deepMerge)(operation_parameters, path_parameters);
}
return [];
}
function generateOperationSecurityMarkdown(h, security_requirements) {
if (!security_requirements) {
return "";
}
let endpoints_str = "";
endpoints_str += `${h}### Required Scopes`;
endpoints_str += "\n\n";
endpoints_str += `This endpoint requires the following scopes:\n\n`;
for (const security_requirement of security_requirements) {
for (const security_items of Object.entries(security_requirement)) {
for (const security_item of security_items[1]) {
endpoints_str += `- \`${security_item}\`\n`;
}
}
}
endpoints_str += "\n\n";
return endpoints_str;
}
function generateMediaTypeMarkdown(media_type, obj, display_for) {
let endpoints_str = "";
endpoints_str += `Media Type: \`${media_type}\``;
endpoints_str += "\n\n";
if (obj.encoding) {
endpoints_str += `Encoding: ${obj.encoding}`;
endpoints_str += "\n\n";
}
if (obj.schema) {
/** @ts-expect-error we resolve all references */
endpoints_str += (0, schema_1.generateSchemaMarkdown)(obj.schema, display_for);
}
return endpoints_str;
}