Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for injecting MD files. Any extension starts with 'x-md… #327

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ node widdershins --search false --language_tabs 'ruby:Ruby' 'python:Python' --su
| --omitHeader | options.omitHeader | `boolean` | `false` | Omit the header / YAML front-matter in the generated Markdown file. |
| --resolve | options.resolve | `boolean` | `false` | Resolve external $refs, using the `source` parameter or the input file as the base location. |
| --shallowSchemas | options.shallowSchemas | `boolean` | `false` | When referring to a schema with a $ref, don't show the full contents of the schema. |
| --loadMdPrefix | options.loadMdPrefix | `string` | `x-md-`| Prefix of OpenAPI extension that indicates MD files paths to load and can be injected anywhere in the output MD
| N/A | options.source | `string` | None | The absolute location or URL of the source file to use as the base to resolve relative references ($refs) from; required if options.resolve is set to true. For CLI commands, Widdershins uses the input file as the base for the $refs. |
| --summary | options.tocSummary | `boolean` | `false` | Use the operation summary as the TOC entry instead of the ID. |
| --useBodyName | options.useBodyName | `boolean` | Use original param name for OpenAPI 2.0 body parameter. |
Expand Down
19 changes: 17 additions & 2 deletions lib/common.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';

const fs = require('fs');

const jptr = require('reftools/lib/jptr.js').jptr;
const sampler = require('openapi-sampler');
const safejson = require('fast-safe-stringify');
Expand Down Expand Up @@ -526,6 +525,21 @@ function html(markdown,header,options) {
return preface+md.render(markdown);
}

function loadMD(sourceSection, destSection, mdFieldPrefix) {
for (let field in sourceSection) {
if (field.startsWith(mdFieldPrefix)) {
//Replacing '-' so that field can be used in dot templates
let newFieldName = field.split("-").join("_");
try {
destSection[newFieldName] = md.render(fs.readFileSync(sourceSection[field],'utf8'));
}
catch (ex) {
console.log(ex.message);
}
}
}
}

module.exports = {
statusCodes : statusCodes,
doContentType : doContentType,
Expand All @@ -541,6 +555,7 @@ module.exports = {
schemaToArray : schemaToArray,
removeDupeBlankLines: removeDupeBlankLines,
toPrimitive: toPrimitive,
html : html
html : html,
loadMD: loadMD
};

20 changes: 16 additions & 4 deletions lib/openapi3.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ const swagger2openapi = require('swagger2openapi');
const common = require('./common.js');

let templates;
let loadMdPrefix;

function convertToToc(source, data) {
let resources = {};
resources[data.translations.defaultTag] = { count: 0, methods: {} };
if (source.tags) {
for (let tag of source.tags) {
resources[tag.name] = { count: 0, methods: {}, description: tag.description, externalDocs: tag.externalDocs };
//Load MD for tags
common.loadMD(tag, resources[tag.name], loadMdPrefix);
}
}
for (var p in source.paths) {
Expand All @@ -36,6 +39,8 @@ function convertToToc(source, data) {
if ((m !== 'parameters') && (m !== 'summary') && (m !== 'description') && (!m.startsWith('x-'))) {
var method = {};
method.operation = source.paths[p][m];
///load operation level MD
common.loadMD(method.operation, method.operation, loadMdPrefix);
method.pathItem = source.paths[p];
method.verb = m;
method.path = p;
Expand All @@ -57,6 +62,8 @@ function convertToToc(source, data) {
}
resources[tagName].count++;
resources[tagName].methods[sMethodUniqueName] = method;
//load MD for paths
common.loadMD(source.paths[p], resources[tagName], loadMdPrefix);
}
}
}
Expand Down Expand Up @@ -275,9 +282,11 @@ function getParameters(data) {
for (let ess of effSecurity) {
if (data.api.components.securitySchemes[ess]) {
let secScheme = data.api.components.securitySchemes[ess];
let authHeader = {};
//load Security Scheme level MD
common.loadMD(secScheme, authHeader, loadMdPrefix);
if (!existingAuth && ((secScheme.type === 'oauth2') || (secScheme.type === 'openIdConnect') ||
((secScheme.type === 'http') && (secScheme.scheme === 'bearer')))) {
let authHeader = {};
authHeader.name = 'Authorization';
authHeader.type = 'string';
authHeader.in = 'header';
Expand All @@ -288,7 +297,6 @@ function getParameters(data) {
data.allHeaders.push(authHeader);
}
else if ((secScheme.type === 'apiKey') && (secScheme.in === 'header')) {
let authHeader = {};
authHeader.name = secScheme.name;
authHeader.type = 'string';
authHeader.in = 'header';
Expand Down Expand Up @@ -456,6 +464,8 @@ function getResponses(data) {
}
entry.content = response.content;
entry.links = response.links;
//load response level MD
common.loadMD(response, entry, loadMdPrefix);
responses.push(entry);
}
}
Expand Down Expand Up @@ -615,10 +625,10 @@ function convertInner(api, options) {
defaults.theme = 'darkula';
defaults.headings = 2;
defaults.templateCallback = function (template, stage, data) { return data; };
defaults.loadMdPrefix = 'x-md-';
defaults.sample = true;

options = Object.assign({}, defaults, options);

loadMdPrefix = options.loadMdPrefix;
let data = {};
if (options.verbose) console.warn('starting deref', api.info.title);
if (api.components) {
Expand All @@ -633,6 +643,8 @@ function convertInner(api, options) {
if (data.api.components && data.api.components.schemas && data.api.components.schemas["x-widdershins-oldRef"]) {
delete data.api.components.schemas["x-widdershins-oldRef"];
}
//Load root level MD
common.loadMD(api, data, loadMdPrefix);

if (typeof templates === 'undefined') {
templates = dot.process({ path: path.join(__dirname, '..', 'templates', 'openapi3') });
Expand Down
4 changes: 4 additions & 0 deletions widdershins.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ var argv = require('yargs')
.describe('lang','Generate the list of languages for code samples based on the languages used in the source file\'s `x-code-samples` examples.')
.array('language_tabs')
.describe('language_tabs', 'List of language tabs for code samples using "language[:label[:client]]" format, such as `javascript:JavaScript:request`.')
.string('loadMdPrefix')
.describe('loadMdPrefix', 'Prefix of OpenAPI extension that indicates MD files paths to load and can be injected anywhere in the output MD')
.default('loadMdPrefix', 'x-md')
.number('maxLevel')
.alias('m','maxDepth')
.describe('maxDepth','Maximum depth to show for schema examples.')
Expand Down Expand Up @@ -166,6 +169,7 @@ options.customApiKeyValue = argv.customApiKeyValue;
options.html = argv.html;
options.respec = argv.respec;
options.useBodyName = argv.useBodyName;
options.loadMdPrefix = argv.loadMdPrefix;
if (argv.search === false) options.search = false;
if (argv.includes) options.includes = argv.includes.split(',');
if (argv.respec) {
Expand Down