From e7cdd16f9010459735a62f9af5626174e22b6c21 Mon Sep 17 00:00:00 2001 From: Vladimir Gorej Date: Wed, 18 Oct 2023 10:50:49 +0200 Subject: [PATCH] feat(ns-openapi-2): add support for Parameters Definitions Object Refs #3097 --- packages/apidom-ns-openapi-2/README.md | 2 +- .../src/elements/ParametersDefinitions.ts | 10 ++++ packages/apidom-ns-openapi-2/src/index.ts | 2 + packages/apidom-ns-openapi-2/src/namespace.ts | 2 + .../apidom-ns-openapi-2/src/predicates.ts | 11 ++++ .../src/refractor/registration.ts | 9 +++ .../src/refractor/specification.ts | 4 ++ .../parameters-definitions/index.ts | 17 ++++++ .../src/traversal/visitor.ts | 1 + .../apidom-ns-openapi-2/test/predicates.ts | 58 +++++++++++++++++++ .../__snapshots__/index.ts.snap | 11 ++++ .../elements/ParametersDefinitions/index.ts | 19 ++++++ .../__snapshots__/index.ts.snap | 2 +- .../elements/SecurityDefinitions/index.ts | 2 +- 14 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 packages/apidom-ns-openapi-2/src/elements/ParametersDefinitions.ts create mode 100644 packages/apidom-ns-openapi-2/src/refractor/visitors/open-api-2/parameters-definitions/index.ts create mode 100644 packages/apidom-ns-openapi-2/test/refractor/elements/ParametersDefinitions/__snapshots__/index.ts.snap create mode 100644 packages/apidom-ns-openapi-2/test/refractor/elements/ParametersDefinitions/index.ts diff --git a/packages/apidom-ns-openapi-2/README.md b/packages/apidom-ns-openapi-2/README.md index 59cdb97f82..c65a7b0f6e 100644 --- a/packages/apidom-ns-openapi-2/README.md +++ b/packages/apidom-ns-openapi-2/README.md @@ -205,7 +205,7 @@ Only fully implemented specification objects should be checked here. - [x] [Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-schema-object) - [x] [XML Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-xml-object) - [ ] [Definitions Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-definitions-object) -- [ ] [Parameters Definitions Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-paramters-definitions-object) +- [x] [Parameters Definitions Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-paramters-definitions-object) - [ ] [Responses Definitions Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-responses-definitions-object) - [x] [Security Definitions Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-security-definitions-object) - [x] [Security Scheme Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-security-scheme-object) diff --git a/packages/apidom-ns-openapi-2/src/elements/ParametersDefinitions.ts b/packages/apidom-ns-openapi-2/src/elements/ParametersDefinitions.ts new file mode 100644 index 0000000000..3273cc2d48 --- /dev/null +++ b/packages/apidom-ns-openapi-2/src/elements/ParametersDefinitions.ts @@ -0,0 +1,10 @@ +import { ObjectElement, Attributes, Meta } from '@swagger-api/apidom-core'; + +class ParametersDefinitions extends ObjectElement { + constructor(content?: Record, meta?: Meta, attributes?: Attributes) { + super(content, meta, attributes); + this.element = 'parametersDefinitions'; + } +} + +export default ParametersDefinitions; diff --git a/packages/apidom-ns-openapi-2/src/index.ts b/packages/apidom-ns-openapi-2/src/index.ts index c28f1b60f1..ba9273661b 100644 --- a/packages/apidom-ns-openapi-2/src/index.ts +++ b/packages/apidom-ns-openapi-2/src/index.ts @@ -37,6 +37,7 @@ export { isReferenceElement, isSchemaElement, isXmlElement, + isParametersDefinitionsElement, isSecurityDefinitionsElement, isSecuritySchemeElement, isScopesElement, @@ -60,6 +61,7 @@ export { ReferenceElement, SchemaElement, XmlElement, + ParametersDefinitionsElement, SecurityDefinitionsElement, SecuritySchemeElement, ScopesElement, diff --git a/packages/apidom-ns-openapi-2/src/namespace.ts b/packages/apidom-ns-openapi-2/src/namespace.ts index 6be304bafc..a1734150f6 100644 --- a/packages/apidom-ns-openapi-2/src/namespace.ts +++ b/packages/apidom-ns-openapi-2/src/namespace.ts @@ -13,6 +13,7 @@ import TagElement from './elements/Tag'; import SchemaElement from './elements/Schema'; import XmlElement from './elements/Xml'; import ReferenceElement from './elements/Reference'; +import ParametersDefinitionsElement from './elements/ParametersDefinitions'; import SecurityDefinitionsElement from './elements/SecurityDefinitions'; import SecuritySchemeElement from './elements/SecurityScheme'; import ScopesElement from './elements/Scopes'; @@ -35,6 +36,7 @@ const openApi2 = { base.register('reference', ReferenceElement); base.register('schema', SchemaElement); base.register('xml', XmlElement); + base.register('parametersDefinitions', ParametersDefinitionsElement); base.register('securityDefinitions', SecurityDefinitionsElement); base.register('securityScheme', SecuritySchemeElement); base.register('scopes', ScopesElement); diff --git a/packages/apidom-ns-openapi-2/src/predicates.ts b/packages/apidom-ns-openapi-2/src/predicates.ts index 8e0f330926..6c9b099e67 100644 --- a/packages/apidom-ns-openapi-2/src/predicates.ts +++ b/packages/apidom-ns-openapi-2/src/predicates.ts @@ -13,6 +13,7 @@ import TagElement from './elements/Tag'; import ReferenceElement from './elements/Reference'; import SchemaElement from './elements/Schema'; import XmlElement from './elements/Xml'; +import ParametersDefinitionsElement from './elements/ParametersDefinitions'; import SecurityDefinitionsElement from './elements/SecurityDefinitions'; import SecuritySchemeElement from './elements/SecurityScheme'; import SecurityRequirementElement from './elements/SecurityRequirement'; @@ -157,6 +158,16 @@ export const isSecurityDefinitionsElement = createPredicate( }, ); +export const isParametersDefinitionsElement = createPredicate( + ({ hasBasicElementProps, isElementType, primitiveEq }) => { + return (element: unknown): element is ParametersDefinitionsElement => + element instanceof ParametersDefinitionsElement || + (hasBasicElementProps(element) && + isElementType('parametersDefinitions', element) && + primitiveEq('object', element)); + }, +); + export const isSecuritySchemeElement = createPredicate( ({ hasBasicElementProps, isElementType, primitiveEq }) => { return (element: unknown): element is SecuritySchemeElement => diff --git a/packages/apidom-ns-openapi-2/src/refractor/registration.ts b/packages/apidom-ns-openapi-2/src/refractor/registration.ts index 276bed55b1..6bd7bf9df2 100644 --- a/packages/apidom-ns-openapi-2/src/refractor/registration.ts +++ b/packages/apidom-ns-openapi-2/src/refractor/registration.ts @@ -11,6 +11,7 @@ import TagElement from '../elements/Tag'; import ReferenceElement from '../elements/Reference'; import SchemaElement from '../elements/Schema'; import XmlElement from '../elements/Xml'; +import ParametersDefinitionsElement from '../elements/ParametersDefinitions'; import SecurityDefinitionsElement from '../elements/SecurityDefinitions'; import SecuritySchemeElement from '../elements/SecurityScheme'; import ScopesElement from '../elements/Scopes'; @@ -73,6 +74,13 @@ ReferenceElement.refract = createRefractor([ ]); SchemaElement.refract = createRefractor(['visitors', 'document', 'objects', 'Schema', '$visitor']); XmlElement.refract = createRefractor(['visitors', 'document', 'objects', 'XML', '$visitor']); +ParametersDefinitionsElement.refract = createRefractor([ + 'visitors', + 'document', + 'objects', + 'ParametersDefinitions', + '$visitor', +]); SecurityDefinitionsElement.refract = createRefractor([ 'visitors', 'document', @@ -110,6 +118,7 @@ export { ReferenceElement, SchemaElement, XmlElement, + ParametersDefinitionsElement, SecurityDefinitionsElement, SecuritySchemeElement, ScopesElement, diff --git a/packages/apidom-ns-openapi-2/src/refractor/specification.ts b/packages/apidom-ns-openapi-2/src/refractor/specification.ts index 611bd77cfa..630f0dfb53 100644 --- a/packages/apidom-ns-openapi-2/src/refractor/specification.ts +++ b/packages/apidom-ns-openapi-2/src/refractor/specification.ts @@ -20,6 +20,7 @@ import SchemaItemsVisitor from './visitors/open-api-2/schema/ItemsVisitor'; import SchemaPropertiesVisitor from './visitors/open-api-2/schema/PropertiesVisitor'; import SchemaOrJSONReferenceVisitor from './visitors/open-api-2/schema/SchemaOrJSONReferenceVisitor'; import XmlVisitor from './visitors/open-api-2/xml'; +import ParametersDefinitionsVisitor from './visitors/open-api-2/parameters-definitions'; import SecurityDefinitionsVisitor from './visitors/open-api-2/security-definitions'; import SecuritySchemeVisitor from './visitors/open-api-2/security-scheme'; import ScopesVisitor from './visitors/open-api-2/scopes'; @@ -237,6 +238,9 @@ const specification = { wrapped: FallbackVisitor, }, }, + ParametersDefinitions: { + $visitor: ParametersDefinitionsVisitor, + }, SecurityDefinitions: { $visitor: SecurityDefinitionsVisitor, }, diff --git a/packages/apidom-ns-openapi-2/src/refractor/visitors/open-api-2/parameters-definitions/index.ts b/packages/apidom-ns-openapi-2/src/refractor/visitors/open-api-2/parameters-definitions/index.ts new file mode 100644 index 0000000000..189f4e2da1 --- /dev/null +++ b/packages/apidom-ns-openapi-2/src/refractor/visitors/open-api-2/parameters-definitions/index.ts @@ -0,0 +1,17 @@ +import stampit from 'stampit'; +import { always } from 'ramda'; + +import ParametersDefinitionsElement from '../../../../elements/ParametersDefinitions'; +import MapVisitor from '../../generics/MapVisitor'; +import FallbackVisitor from '../../FallbackVisitor'; + +const ParametersDefinitionsVisitor = stampit(MapVisitor, FallbackVisitor, { + props: { + specPath: always(['document', 'objects', 'Parameter']), + }, + init() { + this.element = new ParametersDefinitionsElement(); + }, +}); + +export default ParametersDefinitionsVisitor; diff --git a/packages/apidom-ns-openapi-2/src/traversal/visitor.ts b/packages/apidom-ns-openapi-2/src/traversal/visitor.ts index 66a197d140..e432e54f04 100644 --- a/packages/apidom-ns-openapi-2/src/traversal/visitor.ts +++ b/packages/apidom-ns-openapi-2/src/traversal/visitor.ts @@ -33,6 +33,7 @@ export const keyMap = { JSONReferenceElement: ['content'], SchemaElement: ['content'], XmlElement: ['content'], + ParametersDefinitionsElement: ['content'], SecurityDefinitionsElement: ['content'], SecuritySchemeElement: ['content'], ScopesElement: ['content'], diff --git a/packages/apidom-ns-openapi-2/test/predicates.ts b/packages/apidom-ns-openapi-2/test/predicates.ts index 97e0af75d2..700f60de7e 100644 --- a/packages/apidom-ns-openapi-2/test/predicates.ts +++ b/packages/apidom-ns-openapi-2/test/predicates.ts @@ -14,6 +14,7 @@ import { ReferenceElement, SchemaElement, XmlElement, + ParametersDefinitionsElement, SecurityDefinitionsElement, SecuritySchemeElement, ScopesElement, @@ -31,6 +32,7 @@ import { isReferenceElement, isSchemaElement, isXmlElement, + isParametersDefinitionsElement, isSecurityDefinitionsElement, isSecuritySchemeElement, isScopesElement, @@ -766,6 +768,62 @@ describe('predicates', function () { }); }); + context('isParametersDefinitionsElement', function () { + context('given ParametersDefinitionsElement instance value', function () { + specify('should return true', function () { + const element = new ParametersDefinitionsElement(); + + assert.isTrue(isParametersDefinitionsElement(element)); + }); + }); + + context('given subtype instance value', function () { + specify('should return true', function () { + class ParametersDefinitionsSubElement extends ParametersDefinitionsElement {} + + assert.isTrue(isParametersDefinitionsElement(new ParametersDefinitionsSubElement())); + }); + }); + + context('given non ParametersDefinitionsSubElement instance value', function () { + specify('should return false', function () { + assert.isFalse(isParametersDefinitionsElement(1)); + assert.isFalse(isParametersDefinitionsElement(null)); + assert.isFalse(isParametersDefinitionsElement(undefined)); + assert.isFalse(isParametersDefinitionsElement({})); + assert.isFalse(isParametersDefinitionsElement([])); + assert.isFalse(isParametersDefinitionsElement('string')); + }); + }); + + specify('should support duck-typing', function () { + const parametersDefinitionsElementDuck = { + _storedElement: 'parametersDefinitions', + _content: [], + primitive() { + return 'object'; + }, + get element() { + return this._storedElement; + }, + }; + + const parametersDefinitionsElementSwan = { + _storedElement: undefined, + _content: undefined, + primitive() { + return 'swan'; + }, + get length() { + return 0; + }, + }; + + assert.isTrue(isParametersDefinitionsElement(parametersDefinitionsElementDuck)); + assert.isFalse(isParametersDefinitionsElement(parametersDefinitionsElementSwan)); + }); + }); + context('isSecurityDefinitionsElement', function () { context('given SecurityDefinitionsElement instance value', function () { specify('should return true', function () { diff --git a/packages/apidom-ns-openapi-2/test/refractor/elements/ParametersDefinitions/__snapshots__/index.ts.snap b/packages/apidom-ns-openapi-2/test/refractor/elements/ParametersDefinitions/__snapshots__/index.ts.snap new file mode 100644 index 0000000000..6bd0b001bf --- /dev/null +++ b/packages/apidom-ns-openapi-2/test/refractor/elements/ParametersDefinitions/__snapshots__/index.ts.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`refractor elements ParametersDefinitionsElement should refract to semantic ApiDOM tree 1`] = ` +(ParametersDefinitionsElement + (MemberElement + (StringElement) + (ParameterElement)) + (MemberElement + (StringElement) + (ParameterElement))) +`; diff --git a/packages/apidom-ns-openapi-2/test/refractor/elements/ParametersDefinitions/index.ts b/packages/apidom-ns-openapi-2/test/refractor/elements/ParametersDefinitions/index.ts new file mode 100644 index 0000000000..447984ff2e --- /dev/null +++ b/packages/apidom-ns-openapi-2/test/refractor/elements/ParametersDefinitions/index.ts @@ -0,0 +1,19 @@ +import { expect } from 'chai'; +import { sexprs } from '@swagger-api/apidom-core'; + +import { ParametersDefinitionsElement } from '../../../../src'; + +describe('refractor', function () { + context('elements', function () { + context('ParametersDefinitionsElement', function () { + specify('should refract to semantic ApiDOM tree', function () { + const parametersDefinitionsElement = ParametersDefinitionsElement.refract({ + parameter1: {}, + parameter2: {}, + }); + + expect(sexprs(parametersDefinitionsElement)).toMatchSnapshot(); + }); + }); + }); +}); diff --git a/packages/apidom-ns-openapi-2/test/refractor/elements/SecurityDefinitions/__snapshots__/index.ts.snap b/packages/apidom-ns-openapi-2/test/refractor/elements/SecurityDefinitions/__snapshots__/index.ts.snap index 9c919f67c5..e2e07501b5 100644 --- a/packages/apidom-ns-openapi-2/test/refractor/elements/SecurityDefinitions/__snapshots__/index.ts.snap +++ b/packages/apidom-ns-openapi-2/test/refractor/elements/SecurityDefinitions/__snapshots__/index.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`refractor elements SecurityDefinitions should refract to semantic ApiDOM tree 1`] = ` +exports[`refractor elements SecurityDefinitionsElement should refract to semantic ApiDOM tree 1`] = ` (SecurityDefinitionsElement (MemberElement (StringElement) diff --git a/packages/apidom-ns-openapi-2/test/refractor/elements/SecurityDefinitions/index.ts b/packages/apidom-ns-openapi-2/test/refractor/elements/SecurityDefinitions/index.ts index 33092647d9..7c5be8b9ef 100644 --- a/packages/apidom-ns-openapi-2/test/refractor/elements/SecurityDefinitions/index.ts +++ b/packages/apidom-ns-openapi-2/test/refractor/elements/SecurityDefinitions/index.ts @@ -5,7 +5,7 @@ import { SecurityDefinitionsElement } from '../../../../src'; describe('refractor', function () { context('elements', function () { - context('SecurityDefinitions', function () { + context('SecurityDefinitionsElement', function () { specify('should refract to semantic ApiDOM tree', function () { const securityDefinitionsElement = SecurityDefinitionsElement.refract({ api_key: {},