From dadb5233b8167c44d36cbff0325f0c02fb93f076 Mon Sep 17 00:00:00 2001 From: Vladimir Gorej Date: Fri, 19 Feb 2021 13:47:00 +0100 Subject: [PATCH 1/4] feat(ns-openapi-3-1): complete key mapping for namespace visiting Refs https://github.com/swagger-api/oss-planning/issues/133 --- .../apidom-ns-openapi-3-1/src/predicates.ts | 78 +++++++++++++++++++ .../src/refractor/index.ts | 7 +- .../src/traversal/visitor.ts | 64 ++++++++++++++- 3 files changed, 142 insertions(+), 7 deletions(-) diff --git a/apidom/packages/apidom-ns-openapi-3-1/src/predicates.ts b/apidom/packages/apidom-ns-openapi-3-1/src/predicates.ts index cca4e4a4d1..c07938d5f4 100644 --- a/apidom/packages/apidom-ns-openapi-3-1/src/predicates.ts +++ b/apidom/packages/apidom-ns-openapi-3-1/src/predicates.ts @@ -1,6 +1,7 @@ import { allPass, either, is } from 'ramda'; import { createPredicate } from 'apidom'; +import CallbackElement from './elements/Callback'; import ComponentsElement from './elements/Components'; import ContactElement from './elements/Contact'; import InfoElement from './elements/Info'; @@ -14,6 +15,11 @@ import PathsElement from './elements/Paths'; import PathItemElement from './elements/PathItem'; import OperationElement from './elements/Operation'; import ReferenceElement from './elements/Reference'; +import ExternalDocumentationElement from './elements/ExternalDocumentation'; +import ParameterElement from './elements/Parameter'; +import RequestBodyElement from './elements/RequestBody'; +import ResponsesElement from './elements/Responses'; +import SecurityRequirementElement from './elements/SecurityRequirement'; export const isOpenApiApi3_1Element = createPredicate( ({ hasBasicElementProps, isElementType, primitiveEq, hasClass }) => { @@ -88,6 +94,30 @@ export const isComponentsElement = createPredicate( }, ); +export const isCallbackElement = createPredicate( + ({ hasBasicElementProps, isElementType, primitiveEq }) => { + const isElementTypeComponents = isElementType('callback'); + const primitiveEqObject = primitiveEq('object'); + + return either( + is(CallbackElement), + allPass([hasBasicElementProps, isElementTypeComponents, primitiveEqObject]), + ); + }, +); + +export const isExternalDocumentationElement = createPredicate( + ({ hasBasicElementProps, isElementType, primitiveEq }) => { + const isElementTypeComponents = isElementType('externalDocumentation'); + const primitiveEqObject = primitiveEq('object'); + + return either( + is(ExternalDocumentationElement), + allPass([hasBasicElementProps, isElementTypeComponents, primitiveEqObject]), + ); + }, +); + export const isSchemaElement = createPredicate( ({ hasBasicElementProps, isElementType, primitiveEq }) => { const isElementTypeSchema = isElementType('schema'); @@ -160,6 +190,18 @@ export const isOperationElement = createPredicate( }, ); +export const isParameterElement = createPredicate( + ({ hasBasicElementProps, isElementType, primitiveEq }) => { + const isElementTypeOperation = isElementType('parameter'); + const primitiveEqObject = primitiveEq('object'); + + return either( + is(ParameterElement), + allPass([hasBasicElementProps, isElementTypeOperation, primitiveEqObject]), + ); + }, +); + export const isReferenceElement = createPredicate( ({ hasBasicElementProps, isElementType, primitiveEq }) => { const isElementTypeReference = isElementType('reference'); @@ -171,3 +213,39 @@ export const isReferenceElement = createPredicate( ); }, ); + +export const isRequestBodyElement = createPredicate( + ({ hasBasicElementProps, isElementType, primitiveEq }) => { + const isElementTypeReference = isElementType('requestBody'); + const primitiveEqObject = primitiveEq('object'); + + return either( + is(RequestBodyElement), + allPass([hasBasicElementProps, isElementTypeReference, primitiveEqObject]), + ); + }, +); + +export const isResponsesBodyElement = createPredicate( + ({ hasBasicElementProps, isElementType, primitiveEq }) => { + const isElementTypeReference = isElementType('responses'); + const primitiveEqObject = primitiveEq('object'); + + return either( + is(ResponsesElement), + allPass([hasBasicElementProps, isElementTypeReference, primitiveEqObject]), + ); + }, +); + +export const isSecurityRequirementElement = createPredicate( + ({ hasBasicElementProps, isElementType, primitiveEq }) => { + const isElementTypeReference = isElementType('securityRequirement'); + const primitiveEqObject = primitiveEq('object'); + + return either( + is(SecurityRequirementElement), + allPass([hasBasicElementProps, isElementTypeReference, primitiveEqObject]), + ); + }, +); diff --git a/apidom/packages/apidom-ns-openapi-3-1/src/refractor/index.ts b/apidom/packages/apidom-ns-openapi-3-1/src/refractor/index.ts index 2e28bd352e..2f0c518a7e 100644 --- a/apidom/packages/apidom-ns-openapi-3-1/src/refractor/index.ts +++ b/apidom/packages/apidom-ns-openapi-3-1/src/refractor/index.ts @@ -7,13 +7,10 @@ import specification from './specification'; const refract = ( value: any, - { - specPath = ['visitors', 'document', 'objects', 'OpenApi', '$visitor'], - specObj = specification, - } = {}, + { specPath = ['visitors', 'document', 'objects', 'OpenApi', '$visitor'] } = {}, ): T => { const element = baseRefract(value); - const resolvedSpec = dereference(specObj); + const resolvedSpec = dereference(specification); const visitor = invokeArgs(specPath, [], resolvedSpec); // @ts-ignore diff --git a/apidom/packages/apidom-ns-openapi-3-1/src/traversal/visitor.ts b/apidom/packages/apidom-ns-openapi-3-1/src/traversal/visitor.ts index f25a99a560..2eb17ba897 100644 --- a/apidom/packages/apidom-ns-openapi-3-1/src/traversal/visitor.ts +++ b/apidom/packages/apidom-ns-openapi-3-1/src/traversal/visitor.ts @@ -5,12 +5,72 @@ import { keyMap as keyMapBase, getNodeType as getNodeTypeBase, } from 'apidom'; -import { isReferenceElement } from '../predicates'; +import { + isCallbackElement, + isComponentsElement, + isContactElement, + isExternalDocumentationElement, + isInfoElement, + isLicenseElement, + isOpenapiElement, + isOpenApiApi3_1Element, + isOperationElement, + isParameterElement, + isPathItemElement, + isPathsElement, + isReferenceElement, + isRequestBodyElement, + isResponsesBodyElement, + isSchemaElement, + isSecurityRequirementElement, + isServerElement, + isServerVariableElement, +} from '../predicates'; export { BREAK } from 'apidom'; export const getNodeType = (element: T): string | undefined => { - return isReferenceElement(element) ? 'reference' : getNodeTypeBase(element); + /* eslint-disable no-nested-ternary */ + return isCallbackElement(element) + ? 'callback' + : isComponentsElement(element) + ? 'components' + : isContactElement(element) + ? 'contact' + : isExternalDocumentationElement(element) + ? 'externalDocumentation' + : isInfoElement(element) + ? 'info' + : isLicenseElement(element) + ? 'license' + : isOpenapiElement(element) + ? 'openapi' + : isOpenApiApi3_1Element(element) + ? 'openApi3-1' + : isOperationElement(element) + ? 'operation' + : isParameterElement(element) + ? 'parameter' + : isPathItemElement(element) + ? 'pathItem' + : isPathsElement(element) + ? 'paths' + : isReferenceElement(element) + ? 'reference' + : isRequestBodyElement(element) + ? 'requestBody' + : isResponsesBodyElement(element) + ? 'responses' + : isSchemaElement(element) + ? 'schema' + : isSecurityRequirementElement(element) + ? 'securityRequirement' + : isServerElement(element) + ? 'server' + : isServerVariableElement(element) + ? 'serverVariable' + : getNodeTypeBase(element); + /* eslint-enable */ }; export const keyMapDefault = { From 06885139a68890b2554b8a5717e82fa59ef41a63 Mon Sep 17 00:00:00 2001 From: Vladimir Gorej Date: Fri, 19 Feb 2021 13:49:57 +0100 Subject: [PATCH 2/4] fix: test --- apidom/packages/apidom-ns-openapi-3-1/src/index.ts | 2 +- apidom/packages/apidom-ns-openapi-3-1/src/predicates.ts | 2 +- .../packages/apidom-ns-openapi-3-1/src/traversal/visitor.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apidom/packages/apidom-ns-openapi-3-1/src/index.ts b/apidom/packages/apidom-ns-openapi-3-1/src/index.ts index b24bfd5478..461b276afe 100644 --- a/apidom/packages/apidom-ns-openapi-3-1/src/index.ts +++ b/apidom/packages/apidom-ns-openapi-3-1/src/index.ts @@ -14,7 +14,7 @@ export { } from 'apidom'; export { - isOpenApiApi3_1Element, + isOpenApi3_1Element, isContactElement, isLicenseElement, isInfoElement, diff --git a/apidom/packages/apidom-ns-openapi-3-1/src/predicates.ts b/apidom/packages/apidom-ns-openapi-3-1/src/predicates.ts index c07938d5f4..b4aa745d67 100644 --- a/apidom/packages/apidom-ns-openapi-3-1/src/predicates.ts +++ b/apidom/packages/apidom-ns-openapi-3-1/src/predicates.ts @@ -21,7 +21,7 @@ import RequestBodyElement from './elements/RequestBody'; import ResponsesElement from './elements/Responses'; import SecurityRequirementElement from './elements/SecurityRequirement'; -export const isOpenApiApi3_1Element = createPredicate( +export const isOpenApi3_1Element = createPredicate( ({ hasBasicElementProps, isElementType, primitiveEq, hasClass }) => { const isElementTypeOpenApi3_1 = isElementType('openApi3-1'); const primitiveEqObject = primitiveEq('object'); diff --git a/apidom/packages/apidom-ns-openapi-3-1/src/traversal/visitor.ts b/apidom/packages/apidom-ns-openapi-3-1/src/traversal/visitor.ts index 2eb17ba897..13dfc91547 100644 --- a/apidom/packages/apidom-ns-openapi-3-1/src/traversal/visitor.ts +++ b/apidom/packages/apidom-ns-openapi-3-1/src/traversal/visitor.ts @@ -13,7 +13,7 @@ import { isInfoElement, isLicenseElement, isOpenapiElement, - isOpenApiApi3_1Element, + isOpenApi3_1Element, isOperationElement, isParameterElement, isPathItemElement, @@ -45,7 +45,7 @@ export const getNodeType = (element: T): string | undefined = ? 'license' : isOpenapiElement(element) ? 'openapi' - : isOpenApiApi3_1Element(element) + : isOpenApi3_1Element(element) ? 'openApi3-1' : isOperationElement(element) ? 'operation' From 4624833f929ba9012333524ae9d51cfb856d6233 Mon Sep 17 00:00:00 2001 From: Vladimir Gorej Date: Fri, 19 Feb 2021 13:55:45 +0100 Subject: [PATCH 3/4] fix: tests --- .../apidom-ns-openapi-3-1/test/predicates.ts | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/apidom/packages/apidom-ns-openapi-3-1/test/predicates.ts b/apidom/packages/apidom-ns-openapi-3-1/test/predicates.ts index 85a9f5c6c5..6955de720a 100644 --- a/apidom/packages/apidom-ns-openapi-3-1/test/predicates.ts +++ b/apidom/packages/apidom-ns-openapi-3-1/test/predicates.ts @@ -8,7 +8,7 @@ import { isContactElement, isComponentsElement, isOpenapiElement, - isOpenApiApi3_1Element, + isOpenApi3_1Element, isServerElement, isServerVariableElement, isPathsElement, @@ -36,7 +36,7 @@ describe('predicates', function () { specify('should return true', function () { const element = new OpenApi3_1Element(); - assert.isTrue(isOpenApiApi3_1Element(element)); + assert.isTrue(isOpenApi3_1Element(element)); }); }); @@ -44,18 +44,18 @@ describe('predicates', function () { specify('should return true', function () { class OpenApi3_1SubElement extends OpenApi3_1Element {} - assert.isTrue(isOpenApiApi3_1Element(new OpenApi3_1SubElement())); + assert.isTrue(isOpenApi3_1Element(new OpenApi3_1SubElement())); }); }); context('given non OpenApi3_1SubElement instance value', function () { specify('should return false', function () { - assert.isFalse(isOpenApiApi3_1Element(1)); - assert.isFalse(isOpenApiApi3_1Element(null)); - assert.isFalse(isOpenApiApi3_1Element(undefined)); - assert.isFalse(isOpenApiApi3_1Element({})); - assert.isFalse(isOpenApiApi3_1Element([])); - assert.isFalse(isOpenApiApi3_1Element('string')); + assert.isFalse(isOpenApi3_1Element(1)); + assert.isFalse(isOpenApi3_1Element(null)); + assert.isFalse(isOpenApi3_1Element(undefined)); + assert.isFalse(isOpenApi3_1Element({})); + assert.isFalse(isOpenApi3_1Element([])); + assert.isFalse(isOpenApi3_1Element('string')); }); }); @@ -83,8 +83,8 @@ describe('predicates', function () { }, }; - assert.isTrue(isOpenApiApi3_1Element(openApi3_1ElementDuck)); - assert.isFalse(isOpenApiApi3_1Element(openApi3_1ElementSwan)); + assert.isTrue(isOpenApi3_1Element(openApi3_1ElementDuck)); + assert.isFalse(isOpenApi3_1Element(openApi3_1ElementSwan)); }); }); From dbf637adb9b108c84c1c2bd32c3a29447218d6a3 Mon Sep 17 00:00:00 2001 From: Vladimir Gorej Date: Fri, 19 Feb 2021 14:12:00 +0100 Subject: [PATCH 4/4] fix: test --- apidom/packages/apidom-ls/src/utils/utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apidom/packages/apidom-ls/src/utils/utils.ts b/apidom/packages/apidom-ls/src/utils/utils.ts index afc5ed3235..a0e63afae0 100644 --- a/apidom/packages/apidom-ls/src/utils/utils.ts +++ b/apidom/packages/apidom-ls/src/utils/utils.ts @@ -1,7 +1,7 @@ // @ts-ignore import { isMemberElement, isObjectElement, traverse } from 'apidom'; import { Element, ObjectElement, MemberElement } from 'minim'; -import { isOpenApiApi3_1Element } from 'apidom-ns-openapi-3-1'; +import { isOpenApi3_1Element } from 'apidom-ns-openapi-3-1'; import { CompletionItem, CompletionItemKind, InsertTextFormat } from 'vscode-languageserver-types'; export class SourceMap { @@ -132,7 +132,7 @@ export function addMetadataMapping(root: Element): void { } export function addMetadata(element: Element): void { - if (isOpenApiApi3_1Element(element)) { + if (isOpenApi3_1Element(element)) { element.attributes.set('completion', ['info', 'paths']); } }