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 466b6404b..a78cdcbb7 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 @@ -22,6 +22,7 @@ import securitySchemeTypeRefractorPlugin from './refractor-plugins/security-sche import securityRequirementsEmptyRolesRefractorPlugin from './refractor-plugins/security-requirements-empty-roles'; import type { ConverterOptions } from '../../options'; import createToolbox from './toolbox'; +import infoSummaryRefractorPlugin from './refractor-plugins/info-summary'; // eslint-disable-next-line @typescript-eslint/naming-convention const openAPI3_0_3MediaTypes = [ @@ -63,6 +64,7 @@ class OpenAPI31ToOpenAPI30ConvertStrategy extends ConvertStrategy { webhooksRefractorPlugin({ annotations }), securitySchemeTypeRefractorPlugin({ annotations }), securityRequirementsEmptyRolesRefractorPlugin({ annotations }), + infoSummaryRefractorPlugin({ annotations }), ], { toolboxCreator: createToolbox, diff --git a/packages/apidom-converter/src/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/info-summary.ts b/packages/apidom-converter/src/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/info-summary.ts new file mode 100644 index 000000000..7aa984fd8 --- /dev/null +++ b/packages/apidom-converter/src/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/info-summary.ts @@ -0,0 +1,31 @@ +import { InfoElement } from '@swagger-api/apidom-ns-openapi-3-1'; +import { AnnotationElement } from '@swagger-api/apidom-core'; + +type InfoSummaryPluginOptions = { + annotations: AnnotationElement[]; +}; + +const infoSummaryRefractorPlugin = + ({ annotations }: InfoSummaryPluginOptions) => + () => { + const annotation = new AnnotationElement( + 'The "summary" field of Info Object is not supported in OpenAPI 3.0.3. It has been removed from the converted document.', + { classes: ['warning'] }, + { code: 'info-summary' }, + ); + + return { + visitor: { + InfoElement(element: InfoElement) { + if (!element.hasKey('summary')) return undefined; + + annotations.push(annotation); + element.remove('summary'); + + return undefined; + }, + }, + }; + }; + +export default infoSummaryRefractorPlugin; diff --git a/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/info-summary/__snapshots__/index.ts.snap b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/info-summary/__snapshots__/index.ts.snap new file mode 100644 index 000000000..5ba4b4489 --- /dev/null +++ b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/info-summary/__snapshots__/index.ts.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`converter strategies openapi-3-1-to-openapi-3-0-3 info-summary should remove Info.summary field 1`] = ` +{ + "openapi": "3.0.3", + "info": { + "version": "1.0.0", + "title": "A title" + } +} +`; diff --git a/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/info-summary/fixtures/info-summary.json b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/info-summary/fixtures/info-summary.json new file mode 100644 index 000000000..747f5ad73 --- /dev/null +++ b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/info-summary/fixtures/info-summary.json @@ -0,0 +1,8 @@ +{ + "openapi": "3.1.0", + "info": { + "version": "1.0.0", + "title": "A title", + "summary": "A short summary" + } +} \ No newline at end of file diff --git a/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/info-summary/index.ts b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/info-summary/index.ts new file mode 100644 index 000000000..69d8bef51 --- /dev/null +++ b/packages/apidom-converter/test/strategies/openapi-3-1-to-openapi-3-0-3/refractor-plugins/info-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('info-summary', function () { + const fixturePath = path.join(__dirname, 'fixtures', 'info-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 Info.summary field', async function () { + expect(toJSON(convertedParseResult.api!, undefined, 2)).toMatchSnapshot(); + }); + + specify('should create WARNING annotation', async function () { + const annotations = Array.from(convertedParseResult.annotations); + const annotation = annotations.find((a: AnnotationElement) => + a.code?.equals('info-summary'), + ); + + assert.isDefined(annotation); + assert.isTrue(includesClasses(['warning'], annotation)); + }); + }); + }); + }); +});