diff --git a/src/components/Redoc/Redoc.tsx b/src/components/Redoc/Redoc.tsx index 410a1a71..cc70ec88 100644 --- a/src/components/Redoc/Redoc.tsx +++ b/src/components/Redoc/Redoc.tsx @@ -56,8 +56,8 @@ export class Redoc extends React.Component { {store.spec.info.title} {(!options.disableSearch && ( diff --git a/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap b/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap index a5e76a74..b845aad4 100644 --- a/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap +++ b/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap @@ -76,7 +76,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "minItems": undefined, "options": RedocNormalizedOptions { "allowedMdComponents": Object {}, - "customOptions": Object {}, + "backNavigationPath": undefined, "disableSearch": false, "downloadDefinitionUrl": undefined, "downloadFileName": undefined, @@ -92,6 +92,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "hideSchemaTitles": false, "hideSecuritySection": false, "hideSingleRequestSampleTab": false, + "ignoreIncompatibleTypes": false, "ignoreNamedSchemas": Set {}, "jsonSampleExpandLevel": 2, "maxDisplayedEnumValues": undefined, @@ -111,6 +112,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, + "siteTitle": undefined, "sortEnumValuesAlphabetically": false, "sortOperationsAlphabetically": false, "sortPropsAlphabetically": false, @@ -407,7 +409,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "minItems": undefined, "options": RedocNormalizedOptions { "allowedMdComponents": Object {}, - "customOptions": Object {}, + "backNavigationPath": undefined, "disableSearch": false, "downloadDefinitionUrl": undefined, "downloadFileName": undefined, @@ -423,6 +425,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "hideSchemaTitles": false, "hideSecuritySection": false, "hideSingleRequestSampleTab": false, + "ignoreIncompatibleTypes": false, "ignoreNamedSchemas": Set {}, "jsonSampleExpandLevel": 2, "maxDisplayedEnumValues": undefined, @@ -442,6 +445,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, + "siteTitle": undefined, "sortEnumValuesAlphabetically": false, "sortOperationsAlphabetically": false, "sortPropsAlphabetically": false, @@ -725,7 +729,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "minItems": undefined, "options": RedocNormalizedOptions { "allowedMdComponents": Object {}, - "customOptions": Object {}, + "backNavigationPath": undefined, "disableSearch": false, "downloadDefinitionUrl": undefined, "downloadFileName": undefined, @@ -741,6 +745,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "hideSchemaTitles": false, "hideSecuritySection": false, "hideSingleRequestSampleTab": false, + "ignoreIncompatibleTypes": false, "ignoreNamedSchemas": Set {}, "jsonSampleExpandLevel": 2, "maxDisplayedEnumValues": undefined, @@ -760,6 +765,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, + "siteTitle": undefined, "sortEnumValuesAlphabetically": false, "sortOperationsAlphabetically": false, "sortPropsAlphabetically": false, @@ -1105,7 +1111,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "minItems": undefined, "options": RedocNormalizedOptions { "allowedMdComponents": Object {}, - "customOptions": Object {}, + "backNavigationPath": undefined, "disableSearch": false, "downloadDefinitionUrl": undefined, "downloadFileName": undefined, @@ -1121,6 +1127,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "hideSchemaTitles": false, "hideSecuritySection": false, "hideSingleRequestSampleTab": false, + "ignoreIncompatibleTypes": false, "ignoreNamedSchemas": Set {}, "jsonSampleExpandLevel": 2, "maxDisplayedEnumValues": undefined, @@ -1140,6 +1147,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, + "siteTitle": undefined, "sortEnumValuesAlphabetically": false, "sortOperationsAlphabetically": false, "sortPropsAlphabetically": false, @@ -1448,7 +1456,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "minItems": undefined, "options": RedocNormalizedOptions { "allowedMdComponents": Object {}, - "customOptions": Object {}, + "backNavigationPath": undefined, "disableSearch": false, "downloadDefinitionUrl": undefined, "downloadFileName": undefined, @@ -1464,6 +1472,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "hideSchemaTitles": false, "hideSecuritySection": false, "hideSingleRequestSampleTab": false, + "ignoreIncompatibleTypes": false, "ignoreNamedSchemas": Set {}, "jsonSampleExpandLevel": 2, "maxDisplayedEnumValues": undefined, @@ -1483,6 +1492,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, + "siteTitle": undefined, "sortEnumValuesAlphabetically": false, "sortOperationsAlphabetically": false, "sortPropsAlphabetically": false, @@ -1762,7 +1772,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "minItems": undefined, "options": RedocNormalizedOptions { "allowedMdComponents": Object {}, - "customOptions": Object {}, + "backNavigationPath": undefined, "disableSearch": false, "downloadDefinitionUrl": undefined, "downloadFileName": undefined, @@ -1778,6 +1788,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "hideSchemaTitles": false, "hideSecuritySection": false, "hideSingleRequestSampleTab": false, + "ignoreIncompatibleTypes": false, "ignoreNamedSchemas": Set {}, "jsonSampleExpandLevel": 2, "maxDisplayedEnumValues": undefined, @@ -1797,6 +1808,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, + "siteTitle": undefined, "sortEnumValuesAlphabetically": false, "sortOperationsAlphabetically": false, "sortPropsAlphabetically": false, @@ -2101,7 +2113,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView ], "options": RedocNormalizedOptions { "allowedMdComponents": Object {}, - "customOptions": Object {}, + "backNavigationPath": undefined, "disableSearch": false, "downloadDefinitionUrl": undefined, "downloadFileName": undefined, @@ -2117,6 +2129,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "hideSchemaTitles": false, "hideSecuritySection": false, "hideSingleRequestSampleTab": false, + "ignoreIncompatibleTypes": false, "ignoreNamedSchemas": Set {}, "jsonSampleExpandLevel": 2, "maxDisplayedEnumValues": undefined, @@ -2136,6 +2149,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, + "siteTitle": undefined, "sortEnumValuesAlphabetically": false, "sortOperationsAlphabetically": false, "sortPropsAlphabetically": false, @@ -2470,7 +2484,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "minItems": undefined, "options": RedocNormalizedOptions { "allowedMdComponents": Object {}, - "customOptions": Object {}, + "backNavigationPath": undefined, "disableSearch": false, "downloadDefinitionUrl": undefined, "downloadFileName": undefined, @@ -2486,6 +2500,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "hideSchemaTitles": false, "hideSecuritySection": false, "hideSingleRequestSampleTab": false, + "ignoreIncompatibleTypes": false, "ignoreNamedSchemas": Set {}, "jsonSampleExpandLevel": 2, "maxDisplayedEnumValues": undefined, @@ -2505,6 +2520,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, + "siteTitle": undefined, "sortEnumValuesAlphabetically": false, "sortOperationsAlphabetically": false, "sortPropsAlphabetically": false, @@ -2801,7 +2817,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "minItems": undefined, "options": RedocNormalizedOptions { "allowedMdComponents": Object {}, - "customOptions": Object {}, + "backNavigationPath": undefined, "disableSearch": false, "downloadDefinitionUrl": undefined, "downloadFileName": undefined, @@ -2817,6 +2833,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "hideSchemaTitles": false, "hideSecuritySection": false, "hideSingleRequestSampleTab": false, + "ignoreIncompatibleTypes": false, "ignoreNamedSchemas": Set {}, "jsonSampleExpandLevel": 2, "maxDisplayedEnumValues": undefined, @@ -2836,6 +2853,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, + "siteTitle": undefined, "sortEnumValuesAlphabetically": false, "sortOperationsAlphabetically": false, "sortPropsAlphabetically": false, @@ -3119,7 +3137,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "minItems": undefined, "options": RedocNormalizedOptions { "allowedMdComponents": Object {}, - "customOptions": Object {}, + "backNavigationPath": undefined, "disableSearch": false, "downloadDefinitionUrl": undefined, "downloadFileName": undefined, @@ -3135,6 +3153,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "hideSchemaTitles": false, "hideSecuritySection": false, "hideSingleRequestSampleTab": false, + "ignoreIncompatibleTypes": false, "ignoreNamedSchemas": Set {}, "jsonSampleExpandLevel": 2, "maxDisplayedEnumValues": undefined, @@ -3154,6 +3173,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "showWebhookVerb": false, "sideNavStyle": "summary-only", "simpleOneOfTypeLabel": false, + "siteTitle": undefined, "sortEnumValuesAlphabetically": false, "sortOperationsAlphabetically": false, "sortPropsAlphabetically": false, diff --git a/src/services/OpenAPIParser.ts b/src/services/OpenAPIParser.ts index 1542cf7e..e306a151 100644 --- a/src/services/OpenAPIParser.ts +++ b/src/services/OpenAPIParser.ts @@ -242,7 +242,12 @@ export class OpenAPIParser { ...otherConstraints } = subSchema; - if (receiver.type !== type && receiver.type !== undefined && type !== undefined) { + if ( + receiver.type !== type && + receiver.type !== undefined && + type !== undefined && + !this.options.ignoreIncompatibleTypes + ) { console.warn(`Incompatible types in allOf at "${$ref}": "${receiver.type}" and "${type}"`); } diff --git a/src/services/RedocNormalizedOptions.ts b/src/services/RedocNormalizedOptions.ts index f1a25545..0ae2ff7e 100644 --- a/src/services/RedocNormalizedOptions.ts +++ b/src/services/RedocNormalizedOptions.ts @@ -6,12 +6,6 @@ import { setRedocLabels } from './Labels'; import { SideNavStyleEnum } from './types'; import type { LabelsConfigRaw, MDXComponentMeta } from './types'; -// Custom options needed by DOP. Add any custom options here. -interface CustomOptions { - backNavigationPath?: string; - siteTitle?: string; -} - export interface RedocRawOptions { theme?: ThemeInterface; scrollYOffset?: number | string | (() => number); @@ -63,8 +57,10 @@ export interface RedocRawOptions { minCharacterLengthToInitSearch?: number; showWebhookVerb?: boolean; - // Custom options specific to DOP's use case - customOptions?: CustomOptions; + // Custom options specific to DOP's use case. Options expected by the CLI should be added here. + backNavigationPath?: string; + ignoreIncompatibleTypes?: boolean | string; + siteTitle?: string; } export function argValueToBoolean(val?: string | boolean, defaultValue?: boolean): boolean { @@ -268,7 +264,11 @@ export class RedocNormalizedOptions { nonce?: string; - customOptions?: CustomOptions; + // Normalized custom options for DOP. Add custom options here if they are expected to + // be used by the component elsewhere. + backNavigationPath?: string; + ignoreIncompatibleTypes: boolean; + siteTitle?: string; constructor(raw: RedocRawOptions, defaults: RedocRawOptions = {}) { raw = { ...defaults, ...raw }; @@ -347,7 +347,9 @@ export class RedocNormalizedOptions { this.minCharacterLengthToInitSearch = argValueToNumber(raw.minCharacterLengthToInitSearch) || 3; this.showWebhookVerb = argValueToBoolean(raw.showWebhookVerb); - // No normalization needed for custom options at the moment. Expand if needed - this.customOptions = raw.customOptions || {}; + // Normalization of custom DOP options + this.backNavigationPath = raw.backNavigationPath; + this.ignoreIncompatibleTypes = argValueToBoolean(raw.ignoreIncompatibleTypes); + this.siteTitle = raw.siteTitle; } } diff --git a/src/services/__tests__/fixtures/oneOfIncompatibleTypes.json b/src/services/__tests__/fixtures/oneOfIncompatibleTypes.json new file mode 100644 index 00000000..56053411 --- /dev/null +++ b/src/services/__tests__/fixtures/oneOfIncompatibleTypes.json @@ -0,0 +1,46 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0", + "title": "Foo" + }, + "paths": { + "/test": { + "get": { + "summary": "This schema should invoke a warning because of incompatible types.", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/Schema1" + } + ] + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Schema1": { + "type": "object", + "properties": { + "foo": { + "type": "object", + "oneOf": [ + { + "type": "string" + } + ] + } + } + } + } + } +} diff --git a/src/services/__tests__/models/Schema.test.ts b/src/services/__tests__/models/Schema.test.ts index 558c2c1b..839901a5 100644 --- a/src/services/__tests__/models/Schema.test.ts +++ b/src/services/__tests__/models/Schema.test.ts @@ -45,6 +45,32 @@ describe('Models', () => { expect(schema.displayType).toBe('(Array of strings or numbers) or string'); }); + describe('incompatible type warnings', () => { + const spec = require('../fixtures/oneOfIncompatibleTypes.json'); + let consoleWarnMock: jest.SpyInstance; + + beforeEach(() => { + consoleWarnMock = jest.spyOn(global.console, 'warn').mockImplementation(); + }); + + afterEach(() => { + consoleWarnMock.mockClear(); + }); + + test('warnings are displayed in the console', () => { + parser = new OpenAPIParser(spec, undefined, opts); + new SchemaModel(parser, spec.components.schemas.Schema1, '', opts); + expect(consoleWarnMock).toBeCalled(); + }); + + test('warnings are suppressed', () => { + const opts = new RedocNormalizedOptions({ ignoreIncompatibleTypes: true }); + parser = new OpenAPIParser(spec, undefined, opts); + new SchemaModel(parser, spec.components.schemas.Schema1, '', opts); + expect(consoleWarnMock).not.toBeCalled(); + }); + }); + test('schemaDefinition should resolve double ref', () => { const spec = require('../fixtures/3.1/schemaDefinition.json'); parser = new OpenAPIParser(spec, undefined, opts);