From 5a493e729d186a63d36782498c4c53b8802fffa1 Mon Sep 17 00:00:00 2001 From: Andrew Tatomyr Date: Fri, 18 Oct 2024 12:21:23 +0300 Subject: [PATCH] fix: wrong discriminator mapping when bundling with derefernce (#1666) * fix: wrong discriminator mapping when bundling with derefernce * add changeset --- .changeset/proud-chairs-lie.md | 6 ++ .../bundle/discriminator-mapping/bar.yaml | 6 ++ .../bundle/discriminator-mapping/foo.yaml | 6 ++ .../bundle/discriminator-mapping/main.yaml | 19 ++++ .../bundle/discriminator-mapping/redocly.yaml | 3 + .../bundle/discriminator-mapping/snapshot.js | 87 +++++++++++++++++++ __tests__/commands.test.ts | 11 +++ packages/core/src/bundle.ts | 14 ++- 8 files changed, 144 insertions(+), 8 deletions(-) create mode 100644 .changeset/proud-chairs-lie.md create mode 100644 __tests__/bundle/discriminator-mapping/bar.yaml create mode 100644 __tests__/bundle/discriminator-mapping/foo.yaml create mode 100644 __tests__/bundle/discriminator-mapping/main.yaml create mode 100644 __tests__/bundle/discriminator-mapping/redocly.yaml create mode 100644 __tests__/bundle/discriminator-mapping/snapshot.js diff --git a/.changeset/proud-chairs-lie.md b/.changeset/proud-chairs-lie.md new file mode 100644 index 0000000000..aaa10915cc --- /dev/null +++ b/.changeset/proud-chairs-lie.md @@ -0,0 +1,6 @@ +--- +"@redocly/openapi-core": patch +"@redocly/cli": patch +--- + +Fixed bundling with the `--dereferenced` option. Previously, references to external files were not substituted with references to components, causing them to become invalid. diff --git a/__tests__/bundle/discriminator-mapping/bar.yaml b/__tests__/bundle/discriminator-mapping/bar.yaml new file mode 100644 index 0000000000..37e18415f7 --- /dev/null +++ b/__tests__/bundle/discriminator-mapping/bar.yaml @@ -0,0 +1,6 @@ +type: object +properties: + discriminatedProp: + type: string + bar: + type: boolean diff --git a/__tests__/bundle/discriminator-mapping/foo.yaml b/__tests__/bundle/discriminator-mapping/foo.yaml new file mode 100644 index 0000000000..e488cb46dc --- /dev/null +++ b/__tests__/bundle/discriminator-mapping/foo.yaml @@ -0,0 +1,6 @@ +type: object +properties: + discriminatedProp: + type: string + foo: + type: string diff --git a/__tests__/bundle/discriminator-mapping/main.yaml b/__tests__/bundle/discriminator-mapping/main.yaml new file mode 100644 index 0000000000..8bdfb2353f --- /dev/null +++ b/__tests__/bundle/discriminator-mapping/main.yaml @@ -0,0 +1,19 @@ +openapi: 3.1.0 +info: {} +paths: + /test: + get: + responses: + default: + content: + application/json: + schema: + type: object + discriminator: + propertyName: discriminatedProp + mapping: + Foo: ./foo.yaml + Bar: ./bar.yaml + oneOf: + - $ref: ./foo.yaml + - $ref: ./bar.yaml diff --git a/__tests__/bundle/discriminator-mapping/redocly.yaml b/__tests__/bundle/discriminator-mapping/redocly.yaml new file mode 100644 index 0000000000..280dbebd44 --- /dev/null +++ b/__tests__/bundle/discriminator-mapping/redocly.yaml @@ -0,0 +1,3 @@ +apis: + main: + root: ./main.yaml diff --git a/__tests__/bundle/discriminator-mapping/snapshot.js b/__tests__/bundle/discriminator-mapping/snapshot.js new file mode 100644 index 0000000000..27519d914f --- /dev/null +++ b/__tests__/bundle/discriminator-mapping/snapshot.js @@ -0,0 +1,87 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`E2E bundle discriminator-mapping 1`] = ` +openapi: 3.1.0 +info: {} +paths: + /test: + get: + responses: + default: + content: + application/json: + schema: + type: object + discriminator: + propertyName: discriminatedProp + mapping: + Foo: '#/components/schemas/foo' + Bar: '#/components/schemas/bar' + oneOf: + - $ref: '#/components/schemas/foo' + - $ref: '#/components/schemas/bar' +components: + schemas: + foo: + type: object + properties: + discriminatedProp: + type: string + foo: + type: string + bar: + type: object + properties: + discriminatedProp: + type: string + bar: + type: boolean + +bundling ./main.yaml... +📦 Created a bundle for ./main.yaml at stdout ms. + +`; + +exports[`E2E bundle with option: dereferenced discriminator mapping should be replaced with correct references to components 1`] = ` +openapi: 3.1.0 +info: {} +paths: + /test: + get: + responses: + default: + content: + application/json: + schema: + type: object + discriminator: + propertyName: discriminatedProp + mapping: + Foo: '#/components/schemas/foo' + Bar: '#/components/schemas/bar' + oneOf: + - type: object + properties: &ref_0 + discriminatedProp: + type: string + foo: + type: string + - type: object + properties: &ref_1 + discriminatedProp: + type: string + bar: + type: boolean +components: + schemas: + foo: + type: object + properties: *ref_0 + bar: + type: object + properties: *ref_1 + +bundling main.yaml... +📦 Created a bundle for main.yaml at stdout ms. + +`; diff --git a/__tests__/commands.test.ts b/__tests__/commands.test.ts index b34bd618c6..9bad1cbfba 100644 --- a/__tests__/commands.test.ts +++ b/__tests__/commands.test.ts @@ -523,6 +523,17 @@ describe('E2E', () => { const result = getCommandOutput(args, folderPath); (expect(cleanupOutput(result))).toMatchSpecificSnapshot(join(folderPath, 'snapshot.js')); }); + + it('discriminator mapping should be replaced with correct references to components', () => { + const folderPath = join(__dirname, `bundle/discriminator-mapping`); + const args = getParams('../../../packages/cli/src/index.ts', 'bundle', [ + 'main.yaml', + '--dereferenced', + ]); + + const result = getCommandOutput(args, folderPath); + (expect(cleanupOutput(result))).toMatchSpecificSnapshot(join(folderPath, 'snapshot.js')); + }); }); describe('bundle with long description', () => { diff --git a/packages/core/src/bundle.ts b/packages/core/src/bundle.ts index ff80cdafb1..350651909e 100755 --- a/packages/core/src/bundle.ts +++ b/packages/core/src/bundle.ts @@ -427,11 +427,7 @@ function makeBundleVisitor( } const componentType = mapTypeToComponent('Schema', version)!; - if (dereference) { - saveComponent(componentType, resolved, ctx); - } else { - mapping[name] = saveComponent(componentType, resolved, ctx); - } + mapping[name] = saveComponent(componentType, resolved, ctx); } }, }; @@ -456,9 +452,11 @@ function makeBundleVisitor( components[componentType] = components[componentType] || {}; const name = getComponentName(target, componentType, ctx); components[componentType][name] = target.node; - if (version === SpecMajorVersion.OAS3) { - return `#/components/${componentType}/${name}`; - } else if (version === SpecMajorVersion.Async2 || version === SpecMajorVersion.Async3) { + if ( + version === SpecMajorVersion.OAS3 || + version === SpecMajorVersion.Async2 || + version === SpecMajorVersion.Async3 + ) { return `#/components/${componentType}/${name}`; } else { return `#/${componentType}/${name}`;