diff --git a/src/services/MenuBuilder.ts b/src/services/MenuBuilder.ts index 38f104e5..daa248d5 100644 --- a/src/services/MenuBuilder.ts +++ b/src/services/MenuBuilder.ts @@ -11,6 +11,8 @@ import { SECURITY_DEFINITIONS_COMPONENT_NAME, setSecuritySchemePrefix, JsonPointer, + extractContent, + removeContent, } from '../utils'; import { MarkdownRenderer } from './MarkdownRenderer'; import { GroupModel, OperationModel } from './models'; @@ -52,6 +54,14 @@ export class MenuBuilder { const items: ContentItemModel[] = []; const tagsMap = MenuBuilder.getTagsWithOperations(spec); + + var setionToTheEnd = ''; + + options.sectionsAtTheEnd.forEach(function(s) { + setionToTheEnd += extractContent(spec.info.description || '', s); + spec.info.description = removeContent(spec.info.description || '', s); + }); + items.push(...MenuBuilder.addMarkdownItems(spec.info.description || '', undefined, 1, options)); if (spec['x-tagGroups'] && spec['x-tagGroups'].length > 0) { items.push( @@ -60,6 +70,9 @@ export class MenuBuilder { } else { items.push(...MenuBuilder.getTagsItems(parser, tagsMap, undefined, undefined, options)); } + + items.push(...MenuBuilder.addMarkdownItems(setionToTheEnd, undefined, 1, options)); + return items; } diff --git a/src/services/RedocNormalizedOptions.ts b/src/services/RedocNormalizedOptions.ts index a9952529..978d2727 100644 --- a/src/services/RedocNormalizedOptions.ts +++ b/src/services/RedocNormalizedOptions.ts @@ -27,6 +27,7 @@ export interface RedocRawOptions { hideSchemaTitles?: boolean | string; payloadSampleIdx?: number; expandSingleSchemaField?: boolean | string; + sectionsAtTheEnd?: string | string[]; unstable_ignoreMimeParameters?: boolean; @@ -126,6 +127,14 @@ export class RedocNormalizedOptions { } } + static normalizeSectionsAtTheEnd(value: RedocRawOptions['sectionsAtTheEnd']): string[] { + if (typeof value === 'undefined' || typeof value !== 'string') { + return new Array(0); + } + + return value.split(',').map(ext => ext.trim()); + } + static normalizePayloadSampleIdx(value: RedocRawOptions['payloadSampleIdx']): number { if (typeof value === 'number') { return Math.max(0, value); // always greater or equal than 0 @@ -169,6 +178,7 @@ export class RedocNormalizedOptions { hideSchemaTitles: boolean; payloadSampleIdx: number; expandSingleSchemaField: boolean; + sectionsAtTheEnd: string[]; /* tslint:disable-next-line */ unstable_ignoreMimeParameters: boolean; @@ -222,6 +232,7 @@ export class RedocNormalizedOptions { this.hideSchemaTitles = argValueToBoolean(raw.hideSchemaTitles); this.payloadSampleIdx = RedocNormalizedOptions.normalizePayloadSampleIdx(raw.payloadSampleIdx); this.expandSingleSchemaField = argValueToBoolean(raw.expandSingleSchemaField); + this.sectionsAtTheEnd = RedocNormalizedOptions.normalizeSectionsAtTheEnd(raw.sectionsAtTheEnd); // eslint-disable-next-line @typescript-eslint/camelcase this.unstable_ignoreMimeParameters = argValueToBoolean(raw.unstable_ignoreMimeParameters); diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index d84217a9..3d474527 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -82,6 +82,29 @@ export function appendToMdHeading(md: string, heading: string, content: string) } } +export function extractContent(md: string, heading: string): string { + // return the content of section with given heading + const testRegex = new RegExp(`(^|\\n)#\\s?${heading}\\s*\\n`, 'i'); + const replaceRegex = new RegExp(`((\\n|^)#\\s*${heading}\\s*(\\n|$)(?:.|\\n)*?)(?=\\n#|$)`, 'i'); + if (testRegex.test(md)) { + var extractedContent = replaceRegex.exec(md); + return extractedContent != null ? extractedContent[0] : ''; + } + + return ''; +} + +export function removeContent(md: string, heading: string): string { + // remove the content of section with given heading + const testRegex = new RegExp(`(^|\\n)#\\s?${heading}\\s*\\n`, 'i'); + const replaceRegex = new RegExp(`((\\n|^)#\\s*${heading}\\s*(\\n|$)(?:.|\\n)*?)(?=\\n#|$)`, 'i'); + if (testRegex.test(md)) { + return md.replace(replaceRegex, ''); + } + + return md; +} + // credits https://stackoverflow.com/a/46973278/1749888 export const mergeObjects = (target: any, ...sources: any[]): any => { if (!sources.length) {