From 3c99a9d51ef00df8288658869369fc382e538012 Mon Sep 17 00:00:00 2001 From: Vladimir Gorej Date: Wed, 13 Dec 2023 13:22:16 +0100 Subject: [PATCH 1/2] feat: allow linting OpenAPI path templates Refs #3517 --- package-lock.json | 17 + packages/apidom-ls/package.json | 1 + packages/apidom-ls/src/config/codes.ts | 7 +- .../apidom-ls/src/config/openapi/config.ts | 2 + .../openapi/path-template/lint/index.ts | 6 + .../path-template/lint/value--valid.ts | 23 + .../path-template/lint/value--well-formed.ts | 18 + .../src/config/openapi/path-template/meta.ts | 8 + .../src/config/openapi/paths/lint/index.ts | 3 +- .../openapi/paths/lint/keys--pattern.ts | 19 - .../config/openapi/paths/lint/values--type.ts | 2 +- .../services/validation/linter-functions.ts | 21 + .../visitors/open-api-2/paths/index.ts | 6 +- .../refractor/__snapshots__/index.ts.snap | 420 ++++++++++++++++++ .../visitors/open-api-3-0/paths/index.ts | 6 +- .../refractor/__snapshots__/index.ts.snap | 60 +++ .../refractor/__snapshots__/index.ts.snap | 60 +++ .../__snapshots__/index.ts.snap | 210 +++++++++ .../callbacks/__snapshots__/index.ts.snap | 30 ++ .../paths/__snapshots__/index.ts.snap | 60 +++ .../__snapshots__/index.ts.snap | 30 ++ 21 files changed, 981 insertions(+), 28 deletions(-) create mode 100644 packages/apidom-ls/src/config/openapi/path-template/lint/index.ts create mode 100644 packages/apidom-ls/src/config/openapi/path-template/lint/value--valid.ts create mode 100644 packages/apidom-ls/src/config/openapi/path-template/lint/value--well-formed.ts create mode 100644 packages/apidom-ls/src/config/openapi/path-template/meta.ts delete mode 100644 packages/apidom-ls/src/config/openapi/paths/lint/keys--pattern.ts diff --git a/package-lock.json b/package-lock.json index 63d31a1548..6d42d7b32c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10672,6 +10672,11 @@ "node": ">= 8" } }, + "node_modules/apg-lite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/apg-lite/-/apg-lite-1.0.2.tgz", + "integrity": "sha512-HvCR3+MQ8S4KK5lHsXv8MtWcdbt9PDaxRMuTvChLoiIpmoE+LW9FrHQea2ZU1llCPucDNAojMMe2bTArsWPDAw==" + }, "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -29671,6 +29676,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openapi-path-templating": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/openapi-path-templating/-/openapi-path-templating-1.2.0.tgz", + "integrity": "sha512-m1f9ws9Zn/1CjaBPxECzLmtaTyFwO79eL53pgHUmjCBJQShtVo3vhM0yGOyPF3dxsQ0FYrX+zfflkvaw4+PlNg==", + "dependencies": { + "apg-lite": "^1.0.2" + }, + "engines": { + "node": ">=14.16" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -38250,6 +38266,7 @@ "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.87.0", "@swagger-api/apidom-reference": "^0.87.0", "@types/ramda": "~0.29.6", + "openapi-path-templating": "^1.2.0", "ramda": "~0.29.1", "ramda-adjunct": "^4.1.1", "vscode-languageserver-protocol": "^3.17.2", diff --git a/packages/apidom-ls/package.json b/packages/apidom-ls/package.json index 8d03b7b77a..9e38900a1e 100644 --- a/packages/apidom-ls/package.json +++ b/packages/apidom-ls/package.json @@ -116,6 +116,7 @@ "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.87.0", "@swagger-api/apidom-reference": "^0.87.0", "@types/ramda": "~0.29.6", + "openapi-path-templating": "^1.2.0", "ramda": "~0.29.1", "ramda-adjunct": "^4.1.1", "vscode-languageserver-protocol": "^3.17.2", diff --git a/packages/apidom-ls/src/config/codes.ts b/packages/apidom-ls/src/config/codes.ts index 0ca6896eee..efdef0a04e 100644 --- a/packages/apidom-ls/src/config/codes.ts +++ b/packages/apidom-ls/src/config/codes.ts @@ -650,6 +650,10 @@ enum ApilintCodes { OPENAPI2_INFO = 3030000, + OPENAPI2_PATH_TEMPLATE = 3040000, + OPENAPI2_PATH_TEMPLATE_VALUE_WELL_FORMED = 3040100, + OPENAPI2_PATH_TEMPLATE_VALUE_VALID, + OPENAPI3_0 = 5000000, OPENAPI3_0_OPENAPI_VALUE_PATTERN_3_0_0 = 5000100, @@ -723,8 +727,7 @@ enum ApilintCodes { OPENAPI3_O_SERVER_VARIABLE_FIELD_DESCRIPTION_TYPE = 5080300, OPENAPI3_0_PATHS = 5090000, - OPENAPI3_0_PATHS_KEYS_PATTERN, - OPENAPI3_0_PATHS_VALUES_PATTERN, + OPENAPI3_0_PATHS_VALUES_TYPE, OPENAPI_3_0_SECURITY_REQUIREMENT = 5100000, OPENAPI_3_0_SECURITY_REQUIREMENT_KEYS_DEFINED, diff --git a/packages/apidom-ls/src/config/openapi/config.ts b/packages/apidom-ls/src/config/openapi/config.ts index 332b99b42e..6c35976e49 100644 --- a/packages/apidom-ls/src/config/openapi/config.ts +++ b/packages/apidom-ls/src/config/openapi/config.ts @@ -33,6 +33,7 @@ import serverVariableMeta from './server-variable/meta'; import swaggerMeta from './swagger/meta'; import tagMeta from './tag/meta'; import xmlMeta from './xml/meta'; +import pathTemplateMeta from './path-template/meta'; import schemaMeta from '../common/schema/meta'; import ApilintCodes from '../codes'; @@ -83,4 +84,5 @@ export default { tag: tagMeta, xml: xmlMeta, schema: schemaMeta, + 'path-template': pathTemplateMeta, }; diff --git a/packages/apidom-ls/src/config/openapi/path-template/lint/index.ts b/packages/apidom-ls/src/config/openapi/path-template/lint/index.ts new file mode 100644 index 0000000000..7aaa6d17e8 --- /dev/null +++ b/packages/apidom-ls/src/config/openapi/path-template/lint/index.ts @@ -0,0 +1,6 @@ +import valueWellFormedLint from './value--well-formed'; +import valueValidLint from './value--valid'; + +const lints = [valueWellFormedLint, valueValidLint]; + +export default lints; diff --git a/packages/apidom-ls/src/config/openapi/path-template/lint/value--valid.ts b/packages/apidom-ls/src/config/openapi/path-template/lint/value--valid.ts new file mode 100644 index 0000000000..eceb6643d1 --- /dev/null +++ b/packages/apidom-ls/src/config/openapi/path-template/lint/value--valid.ts @@ -0,0 +1,23 @@ +import { DiagnosticSeverity } from 'vscode-languageserver-types'; + +import ApilintCodes from '../../../codes'; +import { LinterMeta } from '../../../../apidom-language-types'; +import { OpenAPI } from '../../target-specs'; + +const valueValidLint: LinterMeta = { + code: ApilintCodes.OPENAPI2_PATH_TEMPLATE_VALUE_VALID, + source: 'apilint', + message: 'path template expressions is not matched with Parameter Object(s)', + severity: DiagnosticSeverity.Error, + linterFunction: 'apilintOpenAPIPathTemplateValid', + marker: 'value', + targetSpecs: OpenAPI, + conditions: [ + { + function: 'apilintOpenAPIPathTemplateWellFormed', + params: [true], + }, + ], +}; + +export default valueValidLint; diff --git a/packages/apidom-ls/src/config/openapi/path-template/lint/value--well-formed.ts b/packages/apidom-ls/src/config/openapi/path-template/lint/value--well-formed.ts new file mode 100644 index 0000000000..4e26fb305e --- /dev/null +++ b/packages/apidom-ls/src/config/openapi/path-template/lint/value--well-formed.ts @@ -0,0 +1,18 @@ +import { DiagnosticSeverity } from 'vscode-languageserver-types'; + +import ApilintCodes from '../../../codes'; +import { LinterMeta } from '../../../../apidom-language-types'; +import { OpenAPI } from '../../target-specs'; + +const valueWellFormedLint: LinterMeta = { + code: ApilintCodes.OPENAPI2_PATH_TEMPLATE_VALUE_WELL_FORMED, + source: 'apilint', + message: "'path' must begin with '/' and be relative to an individual endpoint", + severity: DiagnosticSeverity.Error, + linterFunction: 'apilintOpenAPIPathTemplateWellFormed', + linterParams: [false], + marker: 'value', + targetSpecs: OpenAPI, +}; + +export default valueWellFormedLint; diff --git a/packages/apidom-ls/src/config/openapi/path-template/meta.ts b/packages/apidom-ls/src/config/openapi/path-template/meta.ts new file mode 100644 index 0000000000..209e9e4292 --- /dev/null +++ b/packages/apidom-ls/src/config/openapi/path-template/meta.ts @@ -0,0 +1,8 @@ +import lint from './lint'; +import { FormatMeta } from '../../../apidom-language-types'; + +const meta: FormatMeta = { + lint, +}; + +export default meta; diff --git a/packages/apidom-ls/src/config/openapi/paths/lint/index.ts b/packages/apidom-ls/src/config/openapi/paths/lint/index.ts index 215696d1bf..f49a5fe791 100644 --- a/packages/apidom-ls/src/config/openapi/paths/lint/index.ts +++ b/packages/apidom-ls/src/config/openapi/paths/lint/index.ts @@ -1,6 +1,5 @@ -import keysPatternLint from './keys--pattern'; import valuesTypeLint from './values--type'; -const lints = [valuesTypeLint, keysPatternLint]; +const lints = [valuesTypeLint]; export default lints; diff --git a/packages/apidom-ls/src/config/openapi/paths/lint/keys--pattern.ts b/packages/apidom-ls/src/config/openapi/paths/lint/keys--pattern.ts deleted file mode 100644 index bf469a5a81..0000000000 --- a/packages/apidom-ls/src/config/openapi/paths/lint/keys--pattern.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { DiagnosticSeverity } from 'vscode-languageserver-types'; - -import ApilintCodes from '../../../codes'; -import { LinterMeta } from '../../../../apidom-language-types'; -import { OpenAPI3 } from '../../target-specs'; - -const keysPatternLint: LinterMeta = { - code: ApilintCodes.OPENAPI3_0_PATHS_KEYS_PATTERN, - source: 'apilint', - message: 'Paths Object keys must match the regular expression: `^(/|x-)`', - severity: DiagnosticSeverity.Error, - linterFunction: 'apilintKeysRegex', - linterParams: ['^(/|x-)'], - marker: 'key', - data: {}, - targetSpecs: OpenAPI3, -}; - -export default keysPatternLint; diff --git a/packages/apidom-ls/src/config/openapi/paths/lint/values--type.ts b/packages/apidom-ls/src/config/openapi/paths/lint/values--type.ts index 3b53e93d18..470ddd9609 100644 --- a/packages/apidom-ls/src/config/openapi/paths/lint/values--type.ts +++ b/packages/apidom-ls/src/config/openapi/paths/lint/values--type.ts @@ -5,7 +5,7 @@ import { LinterMeta } from '../../../../apidom-language-types'; import { OpenAPI3 } from '../../target-specs'; const valuesTypeLint: LinterMeta = { - code: ApilintCodes.OPENAPI3_0_PATHS_VALUES_PATTERN, + code: ApilintCodes.OPENAPI3_0_PATHS_VALUES_TYPE, source: 'apilint', message: 'Paths Object values must be of Path Item Object shape', severity: DiagnosticSeverity.Error, diff --git a/packages/apidom-ls/src/services/validation/linter-functions.ts b/packages/apidom-ls/src/services/validation/linter-functions.ts index 12e9dc9891..c595ff234a 100644 --- a/packages/apidom-ls/src/services/validation/linter-functions.ts +++ b/packages/apidom-ls/src/services/validation/linter-functions.ts @@ -3,12 +3,14 @@ import { Element, ArrayElement, MemberElement, + isStringElement, filter, toValue, ArraySlice, ObjectElement, } from '@swagger-api/apidom-core'; import { CompletionItem } from 'vscode-languageserver-types'; +import { test } from 'openapi-path-templating'; // eslint-disable-next-line import/no-cycle import { @@ -993,4 +995,23 @@ export const standardLinterfunctions: FunctionItem[] = [ return true; }, }, + { + functionName: 'apilintOpenAPIPathTemplateWellFormed', + function: (element: Element, strict = false) => { + if (isStringElement(element)) { + const pathTemplate = toValue(element); + return test(pathTemplate, { strict }); + } + return true; + }, + }, + { + functionName: 'apilintOpenAPIPathTemplateValid', + function: (element: Element) => { + if (isStringElement(element)) { + return true; + } + return true; + }, + }, ]; diff --git a/packages/apidom-ns-openapi-2/src/refractor/visitors/open-api-2/paths/index.ts b/packages/apidom-ns-openapi-2/src/refractor/visitors/open-api-2/paths/index.ts index 269ab14cfb..d911d91fb6 100644 --- a/packages/apidom-ns-openapi-2/src/refractor/visitors/open-api-2/paths/index.ts +++ b/packages/apidom-ns-openapi-2/src/refractor/visitors/open-api-2/paths/index.ts @@ -1,5 +1,5 @@ import stampit from 'stampit'; -import { test, always } from 'ramda'; +import { T as stubTrue, always } from 'ramda'; import { ObjectElement, StringElement, cloneDeep } from '@swagger-api/apidom-core'; import PathsElement from '../../../../elements/Paths'; @@ -10,7 +10,7 @@ import { isPathItemElement } from '../../../../predicates'; const PathsVisitor = stampit(PatternedFieldsVisitor, FallbackVisitor, { props: { - fieldPatternPredicate: test(/^\/(?.*)$/), + fieldPatternPredicate: stubTrue, specPath: always(['document', 'objects', 'PathItem']), canSupportSpecificationExtensions: true, }, @@ -26,6 +26,8 @@ const PathsVisitor = stampit(PatternedFieldsVisitor, FallbackVisitor, { this.element .filter(isPathItemElement) .forEach((pathItemElement: PathItemElement, key: StringElement) => { + key.classes.push('openapi-path-template'); + key.classes.push('path-template'); pathItemElement.setMetaProperty('path', cloneDeep(key)); }); diff --git a/packages/apidom-ns-openapi-2/test/refractor/__snapshots__/index.ts.snap b/packages/apidom-ns-openapi-2/test/refractor/__snapshots__/index.ts.snap index 486113f54d..d94737dbad 100644 --- a/packages/apidom-ns-openapi-2/test/refractor/__snapshots__/index.ts.snap +++ b/packages/apidom-ns-openapi-2/test/refractor/__snapshots__/index.ts.snap @@ -815,6 +815,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/pet/{petId}/uploadImage" }, "value": { @@ -822,6 +837,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/pet/{petId}/uploadImage" } }, @@ -1815,6 +1845,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/pet" }, "value": { @@ -1822,6 +1867,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/pet" } }, @@ -3204,6 +3264,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/pet/findByStatus" }, "value": { @@ -3211,6 +3286,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/pet/findByStatus" } }, @@ -4143,6 +4233,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/pet/findByTags" }, "value": { @@ -4150,6 +4255,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/pet/findByTags" } }, @@ -5034,6 +5154,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/pet/{petId}" }, "value": { @@ -5041,6 +5176,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/pet/{petId}" } }, @@ -7436,6 +7586,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/store/order" }, "value": { @@ -7443,6 +7608,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/store/order" } }, @@ -8143,6 +8323,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/store/order/{orderId}" }, "value": { @@ -8150,6 +8345,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/store/order/{orderId}" } }, @@ -9454,6 +9664,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/store/inventory" }, "value": { @@ -9461,6 +9686,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/store/inventory" } }, @@ -10024,6 +10264,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/user/createWithArray" }, "value": { @@ -10031,6 +10286,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/user/createWithArray" } }, @@ -10668,6 +10938,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/user/createWithList" }, "value": { @@ -10675,6 +10960,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/user/createWithList" } }, @@ -11312,6 +11612,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/user/{username}" }, "value": { @@ -11319,6 +11634,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/user/{username}" } }, @@ -13247,6 +13577,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/user/login" }, "value": { @@ -13254,6 +13599,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/user/login" } }, @@ -14272,6 +14632,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/user/logout" }, "value": { @@ -14279,6 +14654,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/user/logout" } }, @@ -14612,6 +15002,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/user" }, "value": { @@ -14619,6 +15024,21 @@ exports[`refractor given generic ApiDOM object in OpenAPI 2.0 shape should refra "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/user" } }, diff --git a/packages/apidom-ns-openapi-3-0/src/refractor/visitors/open-api-3-0/paths/index.ts b/packages/apidom-ns-openapi-3-0/src/refractor/visitors/open-api-3-0/paths/index.ts index 269ab14cfb..d911d91fb6 100644 --- a/packages/apidom-ns-openapi-3-0/src/refractor/visitors/open-api-3-0/paths/index.ts +++ b/packages/apidom-ns-openapi-3-0/src/refractor/visitors/open-api-3-0/paths/index.ts @@ -1,5 +1,5 @@ import stampit from 'stampit'; -import { test, always } from 'ramda'; +import { T as stubTrue, always } from 'ramda'; import { ObjectElement, StringElement, cloneDeep } from '@swagger-api/apidom-core'; import PathsElement from '../../../../elements/Paths'; @@ -10,7 +10,7 @@ import { isPathItemElement } from '../../../../predicates'; const PathsVisitor = stampit(PatternedFieldsVisitor, FallbackVisitor, { props: { - fieldPatternPredicate: test(/^\/(?.*)$/), + fieldPatternPredicate: stubTrue, specPath: always(['document', 'objects', 'PathItem']), canSupportSpecificationExtensions: true, }, @@ -26,6 +26,8 @@ const PathsVisitor = stampit(PatternedFieldsVisitor, FallbackVisitor, { this.element .filter(isPathItemElement) .forEach((pathItemElement: PathItemElement, key: StringElement) => { + key.classes.push('openapi-path-template'); + key.classes.push('path-template'); pathItemElement.setMetaProperty('path', cloneDeep(key)); }); diff --git a/packages/apidom-ns-openapi-3-0/test/refractor/__snapshots__/index.ts.snap b/packages/apidom-ns-openapi-3-0/test/refractor/__snapshots__/index.ts.snap index 31be7f5657..89754bf772 100644 --- a/packages/apidom-ns-openapi-3-0/test/refractor/__snapshots__/index.ts.snap +++ b/packages/apidom-ns-openapi-3-0/test/refractor/__snapshots__/index.ts.snap @@ -654,6 +654,21 @@ exports[`refractor given generic ApiDOM object in OpenApi 3.0.3 shape should ref "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/path1" }, "value": { @@ -661,6 +676,21 @@ exports[`refractor given generic ApiDOM object in OpenApi 3.0.3 shape should ref "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/path1" } }, @@ -4409,6 +4439,21 @@ exports[`refractor given generic ApiDOM object in OpenApi 3.0.3 shape should ref "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/path2" }, "value": { @@ -4425,6 +4470,21 @@ exports[`refractor given generic ApiDOM object in OpenApi 3.0.3 shape should ref }, "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/path2" } }, diff --git a/packages/apidom-ns-openapi-3-1/test/refractor/__snapshots__/index.ts.snap b/packages/apidom-ns-openapi-3-1/test/refractor/__snapshots__/index.ts.snap index befe452b93..fc0e63ff00 100644 --- a/packages/apidom-ns-openapi-3-1/test/refractor/__snapshots__/index.ts.snap +++ b/packages/apidom-ns-openapi-3-1/test/refractor/__snapshots__/index.ts.snap @@ -726,6 +726,21 @@ exports[`refractor given generic ApiDOM object in OpenApi 3.1 shape should refra "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/path1" }, "value": { @@ -733,6 +748,21 @@ exports[`refractor given generic ApiDOM object in OpenApi 3.1 shape should refra "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/path1" } }, @@ -4475,6 +4505,21 @@ exports[`refractor given generic ApiDOM object in OpenApi 3.1 shape should refra "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/path2" }, "value": { @@ -4491,6 +4536,21 @@ exports[`refractor given generic ApiDOM object in OpenApi 3.1 shape should refra }, "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/path2" } }, diff --git a/packages/apidom-ns-openapi-3-1/test/refractor/plugins/normalize-operation-ids/__snapshots__/index.ts.snap b/packages/apidom-ns-openapi-3-1/test/refractor/plugins/normalize-operation-ids/__snapshots__/index.ts.snap index 7c2d5e9d8d..2502b971e8 100644 --- a/packages/apidom-ns-openapi-3-1/test/refractor/plugins/normalize-operation-ids/__snapshots__/index.ts.snap +++ b/packages/apidom-ns-openapi-3-1/test/refractor/plugins/normalize-operation-ids/__snapshots__/index.ts.snap @@ -91,6 +91,21 @@ exports[`refractor plugins normalize-operation-ids given Operation Object with m "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" }, "value": { @@ -98,6 +113,21 @@ exports[`refractor plugins normalize-operation-ids given Operation Object with m "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" } }, @@ -234,6 +264,21 @@ exports[`refractor plugins normalize-operation-ids given Operation Object with n "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" }, "value": { @@ -241,6 +286,21 @@ exports[`refractor plugins normalize-operation-ids given Operation Object with n "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" } }, @@ -403,6 +463,21 @@ exports[`refractor plugins normalize-operation-ids given Operation Object with o "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/path/to/resource" }, "value": { @@ -410,6 +485,21 @@ exports[`refractor plugins normalize-operation-ids given Operation Object with o "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/path/to/resource" } }, @@ -589,6 +679,21 @@ exports[`refractor plugins normalize-operation-ids given Operation Object with o "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/path/to/resource" }, "value": { @@ -596,6 +701,21 @@ exports[`refractor plugins normalize-operation-ids given Operation Object with o "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/path/to/resource" } }, @@ -913,6 +1033,21 @@ exports[`refractor plugins normalize-operation-ids given Operation Object with u "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" }, "value": { @@ -920,6 +1055,21 @@ exports[`refractor plugins normalize-operation-ids given Operation Object with u "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" } }, @@ -1099,6 +1249,21 @@ exports[`refractor plugins normalize-operation-ids given Operation Object with u "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" }, "value": { @@ -1106,6 +1271,21 @@ exports[`refractor plugins normalize-operation-ids given Operation Object with u "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" } }, @@ -1285,6 +1465,21 @@ exports[`refractor plugins normalize-operation-ids given Operation Objects with "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" }, "value": { @@ -1292,6 +1487,21 @@ exports[`refractor plugins normalize-operation-ids given Operation Objects with "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" } }, diff --git a/packages/apidom-ns-openapi-3-1/test/refractor/plugins/normalize-parameters/callbacks/__snapshots__/index.ts.snap b/packages/apidom-ns-openapi-3-1/test/refractor/plugins/normalize-parameters/callbacks/__snapshots__/index.ts.snap index d8d713a8da..6c7a755915 100644 --- a/packages/apidom-ns-openapi-3-1/test/refractor/plugins/normalize-parameters/callbacks/__snapshots__/index.ts.snap +++ b/packages/apidom-ns-openapi-3-1/test/refractor/plugins/normalize-parameters/callbacks/__snapshots__/index.ts.snap @@ -180,6 +180,21 @@ exports[`refractor plugins normalize-parameters given parameters are defined in "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" }, "value": { @@ -187,6 +202,21 @@ exports[`refractor plugins normalize-parameters given parameters are defined in "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" } }, diff --git a/packages/apidom-ns-openapi-3-1/test/refractor/plugins/normalize-parameters/paths/__snapshots__/index.ts.snap b/packages/apidom-ns-openapi-3-1/test/refractor/plugins/normalize-parameters/paths/__snapshots__/index.ts.snap index b5d2ca4366..af865b08cb 100644 --- a/packages/apidom-ns-openapi-3-1/test/refractor/plugins/normalize-parameters/paths/__snapshots__/index.ts.snap +++ b/packages/apidom-ns-openapi-3-1/test/refractor/plugins/normalize-parameters/paths/__snapshots__/index.ts.snap @@ -198,6 +198,21 @@ exports[`refractor plugins normalize-parameters given parameters are defined in "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" }, "value": { @@ -205,6 +220,21 @@ exports[`refractor plugins normalize-parameters given parameters are defined in "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" } }, @@ -659,6 +689,21 @@ exports[`refractor plugins normalize-parameters given parameters are defined in "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" }, "value": { @@ -666,6 +711,21 @@ exports[`refractor plugins normalize-parameters given parameters are defined in "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" } }, diff --git a/packages/apidom-ns-openapi-3-1/test/refractor/plugins/normalize-servers/__snapshots__/index.ts.snap b/packages/apidom-ns-openapi-3-1/test/refractor/plugins/normalize-servers/__snapshots__/index.ts.snap index 41ee341fef..42bd7581d3 100644 --- a/packages/apidom-ns-openapi-3-1/test/refractor/plugins/normalize-servers/__snapshots__/index.ts.snap +++ b/packages/apidom-ns-openapi-3-1/test/refractor/plugins/normalize-servers/__snapshots__/index.ts.snap @@ -237,6 +237,21 @@ exports[`refractor plugins normalize-servers given OpenAPI.servers defined and P "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" }, "value": { @@ -244,6 +259,21 @@ exports[`refractor plugins normalize-servers given OpenAPI.servers defined and P "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/" } }, From e19de08ca3bc466e97f8b4a5ac4f17ae15a2d876 Mon Sep 17 00:00:00 2001 From: Vladimir Gorej Date: Wed, 13 Dec 2023 13:30:33 +0100 Subject: [PATCH 2/2] test: fix --- .../standard-identifier-selectors.ts.snap | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/packages/apidom-ns-api-design-systems/test/refractor/plugins/openapi-3-1/__snapshots__/standard-identifier-selectors.ts.snap b/packages/apidom-ns-api-design-systems/test/refractor/plugins/openapi-3-1/__snapshots__/standard-identifier-selectors.ts.snap index f58b810bdf..23bdcbc982 100644 --- a/packages/apidom-ns-api-design-systems/test/refractor/plugins/openapi-3-1/__snapshots__/standard-identifier-selectors.ts.snap +++ b/packages/apidom-ns-api-design-systems/test/refractor/plugins/openapi-3-1/__snapshots__/standard-identifier-selectors.ts.snap @@ -91,6 +91,21 @@ exports[`given OpenAPI 3.1 definition should decorate with API Design Systems St "content": { "key": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/path1" }, "value": { @@ -98,6 +113,21 @@ exports[`given OpenAPI 3.1 definition should decorate with API Design Systems St "meta": { "path": { "element": "string", + "meta": { + "classes": { + "element": "array", + "content": [ + { + "element": "string", + "content": "openapi-path-template" + }, + { + "element": "string", + "content": "path-template" + } + ] + } + }, "content": "/path1" } },