diff --git a/README.md b/README.md index bf879406..c8e832a7 100644 --- a/README.md +++ b/README.md @@ -247,6 +247,7 @@ You can use all of the following options with standalone version on tag * **selector**: selector of the element to be used for specifying the offset. The distance from the top of the page to the element's bottom will be used as offset. * **function**: A getter function. Must return a number representing the offset (in pixels). * `showExtensions` - show vendor extensions ("x-" fields). Extensions used by ReDoc are ignored. Can be boolean or an array of `string` with names of extensions to display. +* `showSchemas` - Show all top-level Schemas under group in menu, default `false`. * `sortPropsAlphabetically` - sort properties alphabetically. * `suppressWarnings` - if set, warnings are not rendered at the top of documentation (they still are logged to the console). * `payloadSampleIdx` - if set, payload sample will be inserted at this index or last. Indexes start from 0. diff --git a/e2e/integration/menu.e2e.ts b/e2e/integration/menu.e2e.ts index e1b053d1..26203aea 100644 --- a/e2e/integration/menu.e2e.ts +++ b/e2e/integration/menu.e2e.ts @@ -42,4 +42,18 @@ describe('Menu', () => { cy.contains('[role=menuitem].-depth1', 'store').click({ force: true }); petItem().should('not.have.class', 'active'); }); + + it('should omit Schemas group when showSchemas == false, which is default', () => { + cy.get('.menu-content').should('exist'); + cy.get('[data-item-id="section/Schemas"]').should('not.exist'); + cy.get('[type=section] [title=HoneyBee]').should('not.exist'); + }); + + it('should include Schemas group and sections when showSchemas == true', () => { + cy.visit('e2e/showSchemas.html'); + + cy.get('.menu-content').should('exist'); + cy.get('[data-item-id="section/Schemas"]').should('exist'); + cy.get('[type=section] [title=HoneyBee]').should('exist'); + }); }); diff --git a/e2e/showSchemas.html b/e2e/showSchemas.html new file mode 100644 index 00000000..62e16242 --- /dev/null +++ b/e2e/showSchemas.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/services/MenuBuilder.ts b/src/services/MenuBuilder.ts index 339ba6cf..44e9e574 100644 --- a/src/services/MenuBuilder.ts +++ b/src/services/MenuBuilder.ts @@ -62,6 +62,22 @@ export class MenuBuilder { } else { items.push(...MenuBuilder.getTagsItems(parser, tagsMap, undefined, undefined, options)); } + + if (options.showSchemas && spec.components?.schemas) { + // Ignore entries that are side-effects of Swagger 2 conversion + const titles = Object.keys(spec.components?.schemas).filter((title) => { + return !/^schema[0-9]*$/.test(title); + }); + + let markdown = '# Schemas\n\n'; + titles.sort(); + for (const title of titles) { + markdown += `## ${title}\n`; + markdown += `\n\n`; + } + items.push(...MenuBuilder.addMarkdownItems(markdown, undefined, 1, options)); + } + return items; } diff --git a/src/services/RedocNormalizedOptions.ts b/src/services/RedocNormalizedOptions.ts index 126e313a..66191e7b 100644 --- a/src/services/RedocNormalizedOptions.ts +++ b/src/services/RedocNormalizedOptions.ts @@ -41,6 +41,7 @@ export interface RedocRawOptions { expandDefaultServerVariables?: boolean; maxDisplayedEnumValues?: number; ignoreNamedSchemas?: string[] | string; + showSchemas?: boolean; } function argValueToBoolean(val?: string | boolean, defaultValue?: boolean): boolean { @@ -86,6 +87,10 @@ export class RedocNormalizedOptions { return !!value; } + static normalizeShowSchemas(value: RedocRawOptions['showSchemas']): boolean { + return !!value; + } + static normalizeScrollYOffset(value: RedocRawOptions['scrollYOffset']): () => number { // just number is not valid selector and leads to crash so checking if isNumeric here if (typeof value === 'string' && !isNumeric(value)) { @@ -194,6 +199,7 @@ export class RedocNormalizedOptions { maxDisplayedEnumValues?: number; ignoreNamedSchemas: Set; + showSchemas: boolean; constructor(raw: RedocRawOptions, defaults: RedocRawOptions = {}) { raw = { ...defaults, ...raw }; @@ -252,5 +258,6 @@ export class RedocNormalizedOptions { this.maxDisplayedEnumValues = argValueToNumber(raw.maxDisplayedEnumValues); const ignoreNamedSchemas = Array.isArray(raw.ignoreNamedSchemas) ? raw.ignoreNamedSchemas : raw.ignoreNamedSchemas?.split(',').map(s => s.trim()); this.ignoreNamedSchemas = new Set(ignoreNamedSchemas); + this.showSchemas = RedocNormalizedOptions.normalizeShowSchemas(raw.showSchemas); } }