From 3246c9fba6d3b5fd3ca74e0d41432dbedd344891 Mon Sep 17 00:00:00 2001 From: Patryk Rosiak Date: Tue, 5 Mar 2024 08:30:48 +0100 Subject: [PATCH] feat(apidom-converter): add reference summary and description plugins (#3885) This plugin removes the summary and description fields of Reference Object. Refs #3697 --- .../openapi-3-1-to-openapi-3-0-3/index.ts | 4 ++ .../reference-description.ts | 29 ++++++++++++ .../refractor-plugins/reference-summary.ts | 29 ++++++++++++ .../__snapshots__/index.ts.snap | 25 ++++++++++ .../fixtures/reference-description.json | 22 +++++++++ .../reference-description/index.ts | 46 +++++++++++++++++++ .../__snapshots__/index.ts.snap | 25 ++++++++++ .../fixtures/reference-summary.json | 22 +++++++++ .../reference-summary/index.ts | 46 +++++++++++++++++++ 9 files changed, 248 insertions(+) create mode 100644 packages/apidom-converter/src/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-description.ts create mode 100644 packages/apidom-converter/src/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-summary.ts create mode 100644 packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-description/__snapshots__/index.ts.snap create mode 100644 packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-description/fixtures/reference-description.json create mode 100644 packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-description/index.ts create mode 100644 packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-summary/__snapshots__/index.ts.snap create mode 100644 packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-summary/fixtures/reference-summary.json create mode 100644 packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-summary/index.ts diff --git a/packages/apidom-converter/src/strategies/openapi-3-1-to-openapi-3-0-3/index.ts b/packages/apidom-converter/src/strategies/openapi-3-1-to-openapi-3-0-3/index.ts index a4c76b15a..8a10c1d9c 100644 --- a/packages/apidom-converter/src/strategies/openapi-3-1-to-openapi-3-0-3/index.ts +++ b/packages/apidom-converter/src/strategies/openapi-3-1-to-openapi-3-0-3/index.ts @@ -24,6 +24,8 @@ import type { ConverterOptions } from '../../options'; import createToolbox from './toolbox'; import infoSummaryRefractorPlugin from './refractor-plugins/info-summary'; import licenseIdentifierRefractorPlugin from './refractor-plugins/license-identifier'; +import referenceDescriptionRefractorPlugin from './refractor-plugins/reference-description'; +import referenceSummaryRefractorPlugin from './refractor-plugins/reference-summary'; // eslint-disable-next-line @typescript-eslint/naming-convention const openAPI3_0_3MediaTypes = [ @@ -67,6 +69,8 @@ class OpenAPI31ToOpenAPI30ConvertStrategy extends ConvertStrategy { securityRequirementsEmptyRolesRefractorPlugin({ annotations }), infoSummaryRefractorPlugin({ annotations }), licenseIdentifierRefractorPlugin({ annotations }), + referenceDescriptionRefractorPlugin({ annotations }), + referenceSummaryRefractorPlugin({ annotations }), ], { toolboxCreator: createToolbox, diff --git a/packages/apidom-converter/src/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-description.ts b/packages/apidom-converter/src/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-description.ts new file mode 100644 index 000000000..dfc04d56f --- /dev/null +++ b/packages/apidom-converter/src/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-description.ts @@ -0,0 +1,29 @@ +import { ReferenceElement } from '@swagger-api/apidom-ns-openapi-3-1'; +import { AnnotationElement } from '@swagger-api/apidom-core'; + +type ReferenceDescriptionPluginOptions = { + annotations: AnnotationElement[]; +}; + +const referenceDescriptionRefractorPlugin = + ({ annotations }: ReferenceDescriptionPluginOptions) => + () => { + const annotation = new AnnotationElement( + 'The "description" field of Reference Object is not supported in OpenAPI 3.0.3. It has been removed from the converted document.', + { classes: ['warning'] }, + { code: 'reference-description' }, + ); + + return { + visitor: { + ReferenceElement(element: ReferenceElement) { + if (element.hasKey('description')) { + annotations.push(annotation); + element.remove('description'); + } + }, + }, + }; + }; + +export default referenceDescriptionRefractorPlugin; diff --git a/packages/apidom-converter/src/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-summary.ts b/packages/apidom-converter/src/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-summary.ts new file mode 100644 index 000000000..db7897d8d --- /dev/null +++ b/packages/apidom-converter/src/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-summary.ts @@ -0,0 +1,29 @@ +import { ReferenceElement } from '@swagger-api/apidom-ns-openapi-3-1'; +import { AnnotationElement } from '@swagger-api/apidom-core'; + +type ReferenceSummaryPluginOptions = { + annotations: AnnotationElement[]; +}; + +const referenceSummaryRefractorPlugin = + ({ annotations }: ReferenceSummaryPluginOptions) => + () => { + const annotation = new AnnotationElement( + 'The "summary" field of Reference Object is not supported in OpenAPI 3.0.3. It has been removed from the converted document.', + { classes: ['warning'] }, + { code: 'reference-summary' }, + ); + + return { + visitor: { + ReferenceElement(element: ReferenceElement) { + if (element.hasKey('summary')) { + annotations.push(annotation); + element.remove('summary'); + } + }, + }, + }; + }; + +export default referenceSummaryRefractorPlugin; diff --git a/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-description/__snapshots__/index.ts.snap b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-description/__snapshots__/index.ts.snap new file mode 100644 index 000000000..2da27c154 --- /dev/null +++ b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-description/__snapshots__/index.ts.snap @@ -0,0 +1,25 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`converter strategies openapi-3-1-to-openapi-3-0-3 reference-description should remove Reference.description field 1`] = ` +{ + "openapi": "3.0.3", + "paths": { + "/path": { + "get": { + "responses": { + "default": { + "$ref": "#/components/responses/default" + } + } + } + } + }, + "components": { + "responses": { + "default": { + "description": "first response object" + } + } + } +} +`; diff --git a/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-description/fixtures/reference-description.json b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-description/fixtures/reference-description.json new file mode 100644 index 000000000..65cd14a5d --- /dev/null +++ b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-description/fixtures/reference-description.json @@ -0,0 +1,22 @@ +{ + "openapi": "3.1.0", + "paths": { + "/path": { + "get": { + "responses": { + "default": { + "$ref": "#/components/responses/default", + "description": "example description" + } + } + } + } + }, + "components": { + "responses": { + "default": { + "description": "first response object" + } + } + } +} diff --git a/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-description/index.ts b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-description/index.ts new file mode 100644 index 000000000..649c43306 --- /dev/null +++ b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-description/index.ts @@ -0,0 +1,46 @@ +import path from 'node:path'; +import { expect, assert } from 'chai'; +import { mediaTypes as openAPI31MediaTypes } from '@swagger-api/apidom-parser-adapter-openapi-json-3-1'; +import { mediaTypes as openAPI30MediaTypes } from '@swagger-api/apidom-parser-adapter-openapi-json-3-0'; +import { + AnnotationElement, + ParseResultElement, + toJSON, + includesClasses, +} from '@swagger-api/apidom-core'; + +import convert from '../../../../../src'; + +describe('converter', function () { + context('strategies', function () { + context('openapi-3-1-to-openapi-3-0-3', function () { + context('reference-description', function () { + const fixturePath = path.join(__dirname, 'fixtures', 'reference-description.json'); + let convertedParseResult: ParseResultElement; + + beforeEach(async function () { + convertedParseResult = await convert(fixturePath, { + convert: { + sourceMediaType: openAPI31MediaTypes.findBy('3.1.0', 'json'), + targetMediaType: openAPI30MediaTypes.findBy('3.0.3', 'json'), + }, + }); + }); + + specify('should remove Reference.description field', async function () { + expect(toJSON(convertedParseResult.api!, undefined, 2)).toMatchSnapshot(); + }); + + specify('should create WARNING annotation for description field', async function () { + const annotations = Array.from(convertedParseResult.annotations); + const annotation = annotations.find((a: AnnotationElement) => + a.code?.equals('reference-description'), + ); + + assert.isDefined(annotation); + assert.isTrue(includesClasses(['warning'], annotation)); + }); + }); + }); + }); +}); diff --git a/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-summary/__snapshots__/index.ts.snap b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-summary/__snapshots__/index.ts.snap new file mode 100644 index 000000000..cf1da3654 --- /dev/null +++ b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-summary/__snapshots__/index.ts.snap @@ -0,0 +1,25 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`converter strategies openapi-3-1-to-openapi-3-0-3 reference-summary should remove Reference.summary field 1`] = ` +{ + "openapi": "3.0.3", + "paths": { + "/path": { + "get": { + "responses": { + "default": { + "$ref": "#/components/responses/default" + } + } + } + } + }, + "components": { + "responses": { + "default": { + "description": "first response object" + } + } + } +} +`; diff --git a/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-summary/fixtures/reference-summary.json b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-summary/fixtures/reference-summary.json new file mode 100644 index 000000000..6d3a1f842 --- /dev/null +++ b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-summary/fixtures/reference-summary.json @@ -0,0 +1,22 @@ +{ + "openapi": "3.1.0", + "paths": { + "/path": { + "get": { + "responses": { + "default": { + "$ref": "#/components/responses/default", + "summary": "example summary" + } + } + } + } + }, + "components": { + "responses": { + "default": { + "description": "first response object" + } + } + } +} diff --git a/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-summary/index.ts b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-summary/index.ts new file mode 100644 index 000000000..93142c948 --- /dev/null +++ b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/reference-summary/index.ts @@ -0,0 +1,46 @@ +import path from 'node:path'; +import { expect, assert } from 'chai'; +import { mediaTypes as openAPI31MediaTypes } from '@swagger-api/apidom-parser-adapter-openapi-json-3-1'; +import { mediaTypes as openAPI30MediaTypes } from '@swagger-api/apidom-parser-adapter-openapi-json-3-0'; +import { + AnnotationElement, + ParseResultElement, + toJSON, + includesClasses, +} from '@swagger-api/apidom-core'; + +import convert from '../../../../../src'; + +describe('converter', function () { + context('strategies', function () { + context('openapi-3-1-to-openapi-3-0-3', function () { + context('reference-summary', function () { + const fixturePath = path.join(__dirname, 'fixtures', 'reference-summary.json'); + let convertedParseResult: ParseResultElement; + + beforeEach(async function () { + convertedParseResult = await convert(fixturePath, { + convert: { + sourceMediaType: openAPI31MediaTypes.findBy('3.1.0', 'json'), + targetMediaType: openAPI30MediaTypes.findBy('3.0.3', 'json'), + }, + }); + }); + + specify('should remove Reference.summary field', async function () { + expect(toJSON(convertedParseResult.api!, undefined, 2)).toMatchSnapshot(); + }); + + specify('should create WARNING annotation for summary field', async function () { + const annotations = Array.from(convertedParseResult.annotations); + const annotation = annotations.find((a: AnnotationElement) => + a.code?.equals('reference-summary'), + ); + + assert.isDefined(annotation); + assert.isTrue(includesClasses(['warning'], annotation)); + }); + }); + }); + }); +});