From 3697242beae66812e58dee92f946bcda2e1b3a9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Gorej?= Date: Fri, 14 Jul 2023 13:24:32 +0200 Subject: [PATCH] fix(resolve): fix critial bug in OpenAPI 3.1.0 resolution (#3050) This bug was further upstream also in ApiDOM, which was unable to resolve local references from fragments as well. Refs https://github.com/swagger-api/apidom/issues/2934 --- package-lock.json | 260 ++++++------------ package.json | 8 +- .../visitors/dereference.js | 6 +- .../path-item-object/dereference-apidom.js | 36 ++- .../reference-object/dereference-apidom.js | 85 +++++- .../dereferenced.json | 45 +++ .../$anchor-internal-no-embedding/root.json | 34 +++ .../$ref-url-path-override/dereferenced.json | 21 ++ .../$ref-url-path-override/root.json | 19 ++ .../schema-object/dereference-apidom.js | 40 ++- .../schema-object/index.js | 49 ++++ 11 files changed, 420 insertions(+), 183 deletions(-) create mode 100644 test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-internal-no-embedding/dereferenced.json create mode 100644 test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-internal-no-embedding/root.json create mode 100644 test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-path-override/dereferenced.json create mode 100644 test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-path-override/root.json diff --git a/package-lock.json b/package-lock.json index bdaf62bcb..ef2661d83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,10 +10,10 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.13", - "@swagger-api/apidom-core": ">=0.70.1 <1.0.0", - "@swagger-api/apidom-json-pointer": ">=0.70.1 <1.0.0", - "@swagger-api/apidom-ns-openapi-3-1": ">=0.70.2 <1.0.0", - "@swagger-api/apidom-reference": ">=0.70.2 <1.0.0", + "@swagger-api/apidom-core": ">=0.71.0 <1.0.0", + "@swagger-api/apidom-json-pointer": ">=0.71.0 <1.0.0", + "@swagger-api/apidom-ns-openapi-3-1": ">=0.71.0 <1.0.0", + "@swagger-api/apidom-reference": ">=0.71.1 <1.0.0", "cookie": "~0.5.0", "cross-fetch": "^3.1.5", "deepmerge": "~4.3.0", @@ -3690,12 +3690,12 @@ } }, "node_modules/@swagger-api/apidom-ast": { - "version": "0.70.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-0.70.0.tgz", - "integrity": "sha512-zQ1RUkXjx5NPYv1bmkoXwlQi7oJC7DJqYi0syTQKswJZDbOkHCwz8cDP/YystOEOL+yyIN7i5EQBIHfy5yAMmA==", + "version": "0.71.0", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-0.71.0.tgz", + "integrity": "sha512-ueOhGJmSZNW45YaPcLR4MTyy/2A+2cwPtxoCuNaEL/7qHElLtjr3q/8HdQ7WbvYA4euoDJGF58WCKGSpTLaVeQ==", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@types/ramda": "~0.29.1", + "@types/ramda": "~0.29.3", "ramda": "~0.29.0", "ramda-adjunct": "^4.0.0", "stampit": "^4.3.2", @@ -3703,13 +3703,13 @@ } }, "node_modules/@swagger-api/apidom-core": { - "version": "0.70.1", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-0.70.1.tgz", - "integrity": "sha512-doE6escw5LYVxIp5/lfdeNC8jF39JohKeYQ/YuH5wbo5T06uy8nZ3VxcjPHymmQmLlHdEegUIiirp7dSZFZlIg==", + "version": "0.71.0", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-0.71.0.tgz", + "integrity": "sha512-azIjQ371DweiztMyzNLFI0f8drrW0cLc+EC6coaTGjnMZ583UhaoLUkYZcp7qfRlFabx4kR0xFzEwlPuc6TDOw==", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.70.0", - "@types/ramda": "~0.29.1", + "@swagger-api/apidom-ast": "^0.71.0", + "@types/ramda": "~0.29.3", "minim": "~0.23.8", "ramda": "~0.29.0", "ramda-adjunct": "^4.0.0", @@ -3729,34 +3729,6 @@ "ramda-adjunct": "^4.0.0" } }, - "node_modules/@swagger-api/apidom-json-pointer/node_modules/@swagger-api/apidom-ast": { - "version": "0.71.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-0.71.0.tgz", - "integrity": "sha512-ueOhGJmSZNW45YaPcLR4MTyy/2A+2cwPtxoCuNaEL/7qHElLtjr3q/8HdQ7WbvYA4euoDJGF58WCKGSpTLaVeQ==", - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0", - "stampit": "^4.3.2", - "unraw": "^2.0.1" - } - }, - "node_modules/@swagger-api/apidom-json-pointer/node_modules/@swagger-api/apidom-core": { - "version": "0.71.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-0.71.0.tgz", - "integrity": "sha512-azIjQ371DweiztMyzNLFI0f8drrW0cLc+EC6coaTGjnMZ583UhaoLUkYZcp7qfRlFabx4kR0xFzEwlPuc6TDOw==", - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.71.0", - "@types/ramda": "~0.29.3", - "minim": "~0.23.8", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0", - "short-unique-id": "^4.4.4", - "stampit": "^4.3.2" - } - }, "node_modules/@swagger-api/apidom-ns-asyncapi-2": { "name": "-", "version": "0.0.1", @@ -3765,43 +3737,43 @@ "optional": true }, "node_modules/@swagger-api/apidom-ns-json-schema-draft-4": { - "version": "0.70.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-0.70.3.tgz", - "integrity": "sha512-y/WJTQCzm59p8wVPb034AcydzgXNEOVdh+S/OGuHJ+HYUFmVT5NWvBGWC7Ikc9ixXN0v585dzq1QvE2T7H0ZfQ==", + "version": "0.71.0", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-0.71.0.tgz", + "integrity": "sha512-wKYZLo/FyjLPZdz9lRWzXClOOJaUDcVpzv1Yb+CvzZ4sk9PKjfc9ugZ0xBaxCy1ZkuaTziGkUKUHwmb5ngLUHA==", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.70.0", - "@swagger-api/apidom-core": "^0.70.1", - "@types/ramda": "~0.29.1", + "@swagger-api/apidom-ast": "^0.71.0", + "@swagger-api/apidom-core": "^0.71.0", + "@types/ramda": "~0.29.3", "ramda": "~0.29.0", "ramda-adjunct": "^4.0.0", "stampit": "^4.3.2" } }, "node_modules/@swagger-api/apidom-ns-openapi-3-0": { - "version": "0.70.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-0.70.3.tgz", - "integrity": "sha512-ci5GNSf1cA/Xc2/1Kjlo2u78McevOYsH6+weEPW4JlHa3hMJyi6dlw16yHBRl7lzdxiO0D64+r0JVX0bOBhqyw==", + "version": "0.71.0", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-0.71.0.tgz", + "integrity": "sha512-d4bHOBkEs3B6pQ3Elz+R/5emRFF/kdYVgh98pihO1OK3/HrL24DpgMEj/jvDMUpUYh/q/FYixbEUCkDc7BiccQ==", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.70.1", - "@swagger-api/apidom-ns-json-schema-draft-4": "^0.70.3", - "@types/ramda": "~0.29.1", + "@swagger-api/apidom-core": "^0.71.0", + "@swagger-api/apidom-ns-json-schema-draft-4": "^0.71.0", + "@types/ramda": "~0.29.3", "ramda": "~0.29.0", "ramda-adjunct": "^4.0.0", "stampit": "^4.3.2" } }, "node_modules/@swagger-api/apidom-ns-openapi-3-1": { - "version": "0.70.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-0.70.3.tgz", - "integrity": "sha512-/AwVei3FJeC4wAnmNMywyK8zjKiP8CzuuA58G9xqWk2asOH2qjppYjaFAE6BeJ7of7juR5+BvdQg1wXYz8sutA==", + "version": "0.71.0", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-0.71.0.tgz", + "integrity": "sha512-ejKem4uP6MozoVaAKTWbBD1H6KLuz75Q6jAj/kDaU8ReNic+VIUf77yZEcKUl4pc8Ze88dU6zfokQo0WGXqgWg==", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.70.0", - "@swagger-api/apidom-core": "^0.70.1", - "@swagger-api/apidom-ns-openapi-3-0": "^0.70.3", - "@types/ramda": "~0.29.1", + "@swagger-api/apidom-ast": "^0.71.0", + "@swagger-api/apidom-core": "^0.71.0", + "@swagger-api/apidom-ns-openapi-3-0": "^0.71.0", + "@types/ramda": "~0.29.3", "ramda": "~0.29.0", "ramda-adjunct": "^4.0.0", "stampit": "^4.3.2" @@ -3878,13 +3850,13 @@ "optional": true }, "node_modules/@swagger-api/apidom-reference": { - "version": "0.70.4", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-0.70.4.tgz", - "integrity": "sha512-+jrDtbJc7zVqHumyDu1rGXZD3BwrD8qu+FaC7+9iZThU2GAEOs4VvTcCkPQLfVtpIrv1fPvNkzean27MJZxpkw==", + "version": "0.71.1", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-0.71.1.tgz", + "integrity": "sha512-t/8AoS2prTytS5CkQC/gMdy1996uxz615N8kO1GHHWBjlQFL7x9sDA84uxdQKacFJoDVXbNFWJ8+IWV6802GaA==", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.70.1", - "@types/ramda": "~0.29.1", + "@swagger-api/apidom-core": "^0.71.0", + "@types/ramda": "~0.29.3", "axios": "^1.4.0", "minimatch": "^7.4.3", "process": "^0.11.10", @@ -3893,33 +3865,20 @@ "stampit": "^4.3.2" }, "optionalDependencies": { - "@swagger-api/apidom-json-pointer": "^0.70.1", - "@swagger-api/apidom-ns-asyncapi-2": "^0.70.3", - "@swagger-api/apidom-ns-openapi-3-0": "^0.70.3", - "@swagger-api/apidom-ns-openapi-3-1": "^0.70.3", - "@swagger-api/apidom-parser-adapter-api-design-systems-json": "^0.70.4", - "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "^0.70.3", - "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "^0.70.4", - "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "^0.70.3", - "@swagger-api/apidom-parser-adapter-json": "^0.70.4", - "@swagger-api/apidom-parser-adapter-openapi-json-3-0": "^0.70.4", - "@swagger-api/apidom-parser-adapter-openapi-json-3-1": "^0.70.4", - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "^0.70.3", - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "^0.70.3", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.70.3" - } - }, - "node_modules/@swagger-api/apidom-reference/node_modules/@swagger-api/apidom-json-pointer": { - "version": "0.70.1", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-0.70.1.tgz", - "integrity": "sha512-9NyeflCD0Vy8rce3Eag/Xdu2SGF4nr/mnQ6/vb4VbV9pID12z6EbBWvF9p9l0/sRdA6IePj39B3uBLcPl5b4Dg==", - "optional": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.70.1", - "@types/ramda": "~0.29.1", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" + "@swagger-api/apidom-json-pointer": "^0.71.0", + "@swagger-api/apidom-ns-asyncapi-2": "^0.71.0", + "@swagger-api/apidom-ns-openapi-3-0": "^0.71.0", + "@swagger-api/apidom-ns-openapi-3-1": "^0.71.0", + "@swagger-api/apidom-parser-adapter-api-design-systems-json": "^0.71.0", + "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "^0.71.0", + "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "^0.71.0", + "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "^0.71.0", + "@swagger-api/apidom-parser-adapter-json": "^0.71.0", + "@swagger-api/apidom-parser-adapter-openapi-json-3-0": "^0.71.0", + "@swagger-api/apidom-parser-adapter-openapi-json-3-1": "^0.71.0", + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "^0.71.0", + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "^0.71.0", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.71.0" } }, "node_modules/@tootallnate/once": { @@ -18232,12 +18191,12 @@ } }, "@swagger-api/apidom-ast": { - "version": "0.70.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-0.70.0.tgz", - "integrity": "sha512-zQ1RUkXjx5NPYv1bmkoXwlQi7oJC7DJqYi0syTQKswJZDbOkHCwz8cDP/YystOEOL+yyIN7i5EQBIHfy5yAMmA==", + "version": "0.71.0", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-0.71.0.tgz", + "integrity": "sha512-ueOhGJmSZNW45YaPcLR4MTyy/2A+2cwPtxoCuNaEL/7qHElLtjr3q/8HdQ7WbvYA4euoDJGF58WCKGSpTLaVeQ==", "requires": { "@babel/runtime-corejs3": "^7.20.7", - "@types/ramda": "~0.29.1", + "@types/ramda": "~0.29.3", "ramda": "~0.29.0", "ramda-adjunct": "^4.0.0", "stampit": "^4.3.2", @@ -18245,13 +18204,13 @@ } }, "@swagger-api/apidom-core": { - "version": "0.70.1", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-0.70.1.tgz", - "integrity": "sha512-doE6escw5LYVxIp5/lfdeNC8jF39JohKeYQ/YuH5wbo5T06uy8nZ3VxcjPHymmQmLlHdEegUIiirp7dSZFZlIg==", + "version": "0.71.0", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-0.71.0.tgz", + "integrity": "sha512-azIjQ371DweiztMyzNLFI0f8drrW0cLc+EC6coaTGjnMZ583UhaoLUkYZcp7qfRlFabx4kR0xFzEwlPuc6TDOw==", "requires": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.70.0", - "@types/ramda": "~0.29.1", + "@swagger-api/apidom-ast": "^0.71.0", + "@types/ramda": "~0.29.3", "minim": "~0.23.8", "ramda": "~0.29.0", "ramda-adjunct": "^4.0.0", @@ -18269,36 +18228,6 @@ "@types/ramda": "~0.29.3", "ramda": "~0.29.0", "ramda-adjunct": "^4.0.0" - }, - "dependencies": { - "@swagger-api/apidom-ast": { - "version": "0.71.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-0.71.0.tgz", - "integrity": "sha512-ueOhGJmSZNW45YaPcLR4MTyy/2A+2cwPtxoCuNaEL/7qHElLtjr3q/8HdQ7WbvYA4euoDJGF58WCKGSpTLaVeQ==", - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@types/ramda": "~0.29.3", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0", - "stampit": "^4.3.2", - "unraw": "^2.0.1" - } - }, - "@swagger-api/apidom-core": { - "version": "0.71.0", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-0.71.0.tgz", - "integrity": "sha512-azIjQ371DweiztMyzNLFI0f8drrW0cLc+EC6coaTGjnMZ583UhaoLUkYZcp7qfRlFabx4kR0xFzEwlPuc6TDOw==", - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.71.0", - "@types/ramda": "~0.29.3", - "minim": "~0.23.8", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0", - "short-unique-id": "^4.4.4", - "stampit": "^4.3.2" - } - } } }, "@swagger-api/apidom-ns-asyncapi-2": { @@ -18308,43 +18237,43 @@ "optional": true }, "@swagger-api/apidom-ns-json-schema-draft-4": { - "version": "0.70.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-0.70.3.tgz", - "integrity": "sha512-y/WJTQCzm59p8wVPb034AcydzgXNEOVdh+S/OGuHJ+HYUFmVT5NWvBGWC7Ikc9ixXN0v585dzq1QvE2T7H0ZfQ==", + "version": "0.71.0", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-0.71.0.tgz", + "integrity": "sha512-wKYZLo/FyjLPZdz9lRWzXClOOJaUDcVpzv1Yb+CvzZ4sk9PKjfc9ugZ0xBaxCy1ZkuaTziGkUKUHwmb5ngLUHA==", "requires": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.70.0", - "@swagger-api/apidom-core": "^0.70.1", - "@types/ramda": "~0.29.1", + "@swagger-api/apidom-ast": "^0.71.0", + "@swagger-api/apidom-core": "^0.71.0", + "@types/ramda": "~0.29.3", "ramda": "~0.29.0", "ramda-adjunct": "^4.0.0", "stampit": "^4.3.2" } }, "@swagger-api/apidom-ns-openapi-3-0": { - "version": "0.70.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-0.70.3.tgz", - "integrity": "sha512-ci5GNSf1cA/Xc2/1Kjlo2u78McevOYsH6+weEPW4JlHa3hMJyi6dlw16yHBRl7lzdxiO0D64+r0JVX0bOBhqyw==", + "version": "0.71.0", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-0.71.0.tgz", + "integrity": "sha512-d4bHOBkEs3B6pQ3Elz+R/5emRFF/kdYVgh98pihO1OK3/HrL24DpgMEj/jvDMUpUYh/q/FYixbEUCkDc7BiccQ==", "requires": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.70.1", - "@swagger-api/apidom-ns-json-schema-draft-4": "^0.70.3", - "@types/ramda": "~0.29.1", + "@swagger-api/apidom-core": "^0.71.0", + "@swagger-api/apidom-ns-json-schema-draft-4": "^0.71.0", + "@types/ramda": "~0.29.3", "ramda": "~0.29.0", "ramda-adjunct": "^4.0.0", "stampit": "^4.3.2" } }, "@swagger-api/apidom-ns-openapi-3-1": { - "version": "0.70.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-0.70.3.tgz", - "integrity": "sha512-/AwVei3FJeC4wAnmNMywyK8zjKiP8CzuuA58G9xqWk2asOH2qjppYjaFAE6BeJ7of7juR5+BvdQg1wXYz8sutA==", + "version": "0.71.0", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-0.71.0.tgz", + "integrity": "sha512-ejKem4uP6MozoVaAKTWbBD1H6KLuz75Q6jAj/kDaU8ReNic+VIUf77yZEcKUl4pc8Ze88dU6zfokQo0WGXqgWg==", "requires": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^0.70.0", - "@swagger-api/apidom-core": "^0.70.1", - "@swagger-api/apidom-ns-openapi-3-0": "^0.70.3", - "@types/ramda": "~0.29.1", + "@swagger-api/apidom-ast": "^0.71.0", + "@swagger-api/apidom-core": "^0.71.0", + "@swagger-api/apidom-ns-openapi-3-0": "^0.71.0", + "@types/ramda": "~0.29.3", "ramda": "~0.29.0", "ramda-adjunct": "^4.0.0", "stampit": "^4.3.2" @@ -18411,16 +18340,16 @@ "optional": true }, "@swagger-api/apidom-reference": { - "version": "0.70.4", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-0.70.4.tgz", - "integrity": "sha512-+jrDtbJc7zVqHumyDu1rGXZD3BwrD8qu+FaC7+9iZThU2GAEOs4VvTcCkPQLfVtpIrv1fPvNkzean27MJZxpkw==", + "version": "0.71.1", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-0.71.1.tgz", + "integrity": "sha512-t/8AoS2prTytS5CkQC/gMdy1996uxz615N8kO1GHHWBjlQFL7x9sDA84uxdQKacFJoDVXbNFWJ8+IWV6802GaA==", "requires": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.70.1", - "@swagger-api/apidom-json-pointer": "^0.70.1", + "@swagger-api/apidom-core": "^0.71.0", + "@swagger-api/apidom-json-pointer": "^0.71.0", "@swagger-api/apidom-ns-asyncapi-2": "npm:-@0.0.1", - "@swagger-api/apidom-ns-openapi-3-0": "^0.70.3", - "@swagger-api/apidom-ns-openapi-3-1": "^0.70.3", + "@swagger-api/apidom-ns-openapi-3-0": "^0.71.0", + "@swagger-api/apidom-ns-openapi-3-1": "^0.71.0", "@swagger-api/apidom-parser-adapter-api-design-systems-json": "npm:-@0.0.1", "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "npm:-@0.0.1", "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "npm:-@0.0.1", @@ -18431,28 +18360,13 @@ "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "npm:-@0.0.1", "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "npm:-@0.0.1", "@swagger-api/apidom-parser-adapter-yaml-1-2": "npm:-@0.0.1", - "@types/ramda": "~0.29.1", + "@types/ramda": "~0.29.3", "axios": "^1.4.0", "minimatch": "^7.4.3", "process": "^0.11.10", "ramda": "~0.29.0", "ramda-adjunct": "^4.0.0", "stampit": "^4.3.2" - }, - "dependencies": { - "@swagger-api/apidom-json-pointer": { - "version": "0.70.1", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-0.70.1.tgz", - "integrity": "sha512-9NyeflCD0Vy8rce3Eag/Xdu2SGF4nr/mnQ6/vb4VbV9pID12z6EbBWvF9p9l0/sRdA6IePj39B3uBLcPl5b4Dg==", - "optional": true, - "requires": { - "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^0.70.1", - "@types/ramda": "~0.29.1", - "ramda": "~0.29.0", - "ramda-adjunct": "^4.0.0" - } - } } }, "@tootallnate/once": { diff --git a/package.json b/package.json index e5a1940f7..a6de180a1 100644 --- a/package.json +++ b/package.json @@ -114,10 +114,10 @@ }, "dependencies": { "@babel/runtime-corejs3": "^7.20.13", - "@swagger-api/apidom-core": ">=0.70.1 <1.0.0", - "@swagger-api/apidom-json-pointer": ">=0.70.1 <1.0.0", - "@swagger-api/apidom-ns-openapi-3-1": ">=0.70.2 <1.0.0", - "@swagger-api/apidom-reference": ">=0.70.2 <1.0.0", + "@swagger-api/apidom-core": ">=0.71.0 <1.0.0", + "@swagger-api/apidom-json-pointer": ">=0.71.0 <1.0.0", + "@swagger-api/apidom-ns-openapi-3-1": ">=0.71.0 <1.0.0", + "@swagger-api/apidom-reference": ">=0.71.1 <1.0.0", "cookie": "~0.5.0", "cross-fetch": "^3.1.5", "deepmerge": "~4.3.0", diff --git a/src/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitors/dereference.js b/src/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitors/dereference.js index 7cffaa674..c268c70cf 100644 --- a/src/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitors/dereference.js +++ b/src/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitors/dereference.js @@ -83,7 +83,7 @@ const OpenApi3_1SwaggerClientDereferenceVisitor = OpenApi3_1DereferenceVisitor.c } const reference = await this.toReference(referenceElement.$ref.toValue()); - const retrievalURI = reference.uri; + const { uri: retrievalURI } = reference; const $refBaseURI = url.resolve(retrievalURI, referenceElement.$ref.toValue()); this.indirections.push(referenceElement); @@ -230,7 +230,7 @@ const OpenApi3_1SwaggerClientDereferenceVisitor = OpenApi3_1DereferenceVisitor.c } const reference = await this.toReference(pathItemElement.$ref.toValue()); - const retrievalURI = reference.uri; + const { uri: retrievalURI } = reference; const $refBaseURI = url.resolve(retrievalURI, pathItemElement.$ref.toValue()); this.indirections.push(pathItemElement); @@ -366,7 +366,7 @@ const OpenApi3_1SwaggerClientDereferenceVisitor = OpenApi3_1DereferenceVisitor.c } // compute baseURI using rules around $id and $ref keywords - let { reference } = this; + let reference = await this.toReference(url.unsanitize(this.reference.uri)); let { uri: retrievalURI } = reference; const $refBaseURI = resolveSchema$refField(retrievalURI, referencingElement); const $refBaseURIStrippedHash = url.stripHash($refBaseURI); diff --git a/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/path-item-object/dereference-apidom.js b/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/path-item-object/dereference-apidom.js index 6d59552da..7a8d6d025 100644 --- a/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/path-item-object/dereference-apidom.js +++ b/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/path-item-object/dereference-apidom.js @@ -17,7 +17,41 @@ describe('dereference', () => { describe('strategies', () => { describe('openapi-3-1-swagger-client', () => { describe('Path Item Object', () => { - describe('given single PathItemElement passed to dereferenceApiDOM', () => { + describe('given single PathItemElement passed to dereferenceApiDOM with internal references', () => { + const fixturePath = path.join(__dirname, '__fixtures__', 'internal-only', 'root.json'); + + test('should dereference', async () => { + const parseResult = await parse(fixturePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + const jsonPointer = compile(['paths', '/path1']); + const pathItemElement = evaluate(jsonPointer, parseResult.api); + const dereferenced = await dereferenceApiDOM(pathItemElement, { + parse: { mediaType: mediaTypes.latest('json') }, + resolve: { baseURI: `${fixturePath}#${jsonPointer}` }, + }); + + expect(isPathItemElement(dereferenced)).toBe(true); + }); + + test('should dereference and contain metadata about origin', async () => { + const jsonPointer = compile(['paths', '/path1']); + const parseResult = await parse(fixturePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + const pathItemElement = evaluate(jsonPointer, parseResult.api); + const dereferenced = await dereferenceApiDOM(pathItemElement, { + parse: { mediaType: mediaTypes.latest('json') }, + resolve: { baseURI: `${fixturePath}#${jsonPointer}` }, + }); + + expect(dereferenced.meta.get('ref-origin').toValue()).toEqual( + expect.stringMatching(/internal-only\/root\.json$/) + ); + }); + }); + + describe('given single PathItemElement passed to dereferenceApiDOM with external references', () => { const fixturePath = path.join(__dirname, '__fixtures__', 'external-only', 'root.json'); test('should dereference', async () => { diff --git a/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/reference-object/dereference-apidom.js b/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/reference-object/dereference-apidom.js index 6685cd37e..a3de8faf5 100644 --- a/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/reference-object/dereference-apidom.js +++ b/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/reference-object/dereference-apidom.js @@ -19,7 +19,90 @@ describe('dereference', () => { describe('strategies', () => { describe('openapi-3-1-swagger-client', () => { describe('Reference Object', () => { - describe('given single ReferenceElement passed to dereferenceApiDOM', () => { + describe('given single ReferenceElement passed to dereferenceApiDOM with internal references', () => { + describe('given dereferencing using local file system', () => { + const fixturePath = path.join(__dirname, '__fixtures__', 'internal-only', 'root.json'); + + test('should dereference', async () => { + const parseResult = await parse(fixturePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + const referenceElement = evaluate('/components/parameters/userId', parseResult.api); + const dereferenced = await dereferenceApiDOM(referenceElement, { + parse: { mediaType: mediaTypes.latest('json') }, + resolve: { + baseURI: `${fixturePath}#/components/parameters/userId`, + }, + }); + + expect(isParameterElement(dereferenced)).toBe(true); + }); + + test('should dereference and contain metadata about origin', async () => { + const parseResult = await parse(fixturePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + const referenceElement = evaluate('/components/parameters/userId', parseResult.api); + const dereferenced = await dereferenceApiDOM(referenceElement, { + parse: { mediaType: mediaTypes.latest('json') }, + resolve: { baseURI: `${fixturePath}#/components/parameters/userId` }, + }); + + expect(dereferenced.meta.get('ref-origin').toValue()).toEqual( + expect.stringMatching(/internal-only\/root\.json$/) + ); + }); + }); + + describe('given dereferencing using HTTP protocol', () => { + const fixturePath = path.join(__dirname, '__fixtures__', 'internal-only', 'root.json'); + const httpPort = 8123; + let httpServer; + + beforeEach(() => { + const cwd = path.join(__dirname, '__fixtures__', 'internal-only'); + httpServer = globalThis.createHTTPServer({ port: httpPort, cwd }); + }); + + afterEach(async () => { + await httpServer.terminate(); + }); + + test('should dereference', async () => { + const parseResult = await parse(fixturePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + const referenceElement = evaluate('/components/parameters/userId', parseResult.api); + const dereferenced = await dereferenceApiDOM(referenceElement, { + parse: { mediaType: mediaTypes.latest('json') }, + resolve: { + baseURI: `http://localhost:${httpPort}/root.json#/components/parameters/userId`, + }, + }); + + expect(isParameterElement(dereferenced)).toBe(true); + }); + + test('should dereference and contain metadata about origin', async () => { + const parseResult = await parse(fixturePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + const referenceElement = evaluate('/components/parameters/userId', parseResult.api); + const dereferenced = await dereferenceApiDOM(referenceElement, { + parse: { mediaType: mediaTypes.latest('json') }, + resolve: { + baseURI: `http://localhost:${httpPort}/root.json#/components/parameters/userId`, + }, + }); + + expect(dereferenced.meta.get('ref-origin').toValue()).toEqual( + expect.stringMatching(/\/root\.json$/) + ); + }); + }); + }); + + describe('given single ReferenceElement passed to dereferenceApiDOM with external references', () => { describe('given dereferencing using local file system', () => { const fixturePath = path.join(rootFixturePath, 'external-only', 'root.json'); diff --git a/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-internal-no-embedding/dereferenced.json b/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-internal-no-embedding/dereferenced.json new file mode 100644 index 000000000..c1ac6781f --- /dev/null +++ b/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-internal-no-embedding/dereferenced.json @@ -0,0 +1,45 @@ +[ + { + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "$id": "/components/schemas/user", + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$id": "/components/schemas/user-profile", + "$anchor": "user-profile", + "properties": { + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + } + } + } + }, + "UserProfile": { + "$id": "/components/schemas/user-profile", + "$anchor": "user-profile", + "properties": { + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + } + } + } + } + } +] diff --git a/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-internal-no-embedding/root.json b/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-internal-no-embedding/root.json new file mode 100644 index 000000000..2aa126ddd --- /dev/null +++ b/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-internal-no-embedding/root.json @@ -0,0 +1,34 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "$id": "/components/schemas/user", + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$ref": "/components/schemas/user-profile#user-profile" + } + } + }, + "UserProfile": { + "$id": "/components/schemas/user-profile", + "$anchor": "user-profile", + "properties": { + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + } + } + } + } +} diff --git a/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-path-override/dereferenced.json b/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-path-override/dereferenced.json new file mode 100644 index 000000000..393bd9dc0 --- /dev/null +++ b/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-path-override/dereferenced.json @@ -0,0 +1,21 @@ +[ + { + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object" + }, + "UserProfile": { + "$id": "/components/schemas/user-profile", + "type": "object", + "properties": { + "user": { + "type": "object" + } + } + } + } + } + } +] diff --git a/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-path-override/root.json b/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-path-override/root.json new file mode 100644 index 000000000..1727aeefb --- /dev/null +++ b/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-path-override/root.json @@ -0,0 +1,19 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object" + }, + "UserProfile": { + "$id": "/components/schemas/user-profile", + "type": "object", + "properties": { + "user": { + "$ref": "/#/components/schemas/User" + } + } + } + } + } +} diff --git a/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/dereference-apidom.js b/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/dereference-apidom.js index eef9e3e9e..2e7ca0532 100644 --- a/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/dereference-apidom.js +++ b/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/dereference-apidom.js @@ -17,7 +17,45 @@ describe('dereference', () => { describe('strategies', () => { describe('openapi-3-1-swagger-client', () => { describe('Schema Object', () => { - describe('given single SchemaElement passed to dereferenceApiDOM', () => { + describe('given single SchemaElement passed to dereferenceApiDOM with internal references', () => { + const fixturePath = path.join(__dirname, '__fixtures__', 'internal-only', 'root.json'); + + test('should dereference', async () => { + const parseResult = await parse(fixturePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + const schemaElement = evaluate( + '/components/schemas/User/properties/profile', + parseResult.api + ); + const dereferenced = await dereferenceApiDOM(schemaElement, { + parse: { mediaType: mediaTypes.latest('json') }, + resolve: { baseURI: `${fixturePath}#/components/schemas/User/properties/profile` }, + }); + + expect(isSchemaElement(dereferenced)).toBe(true); + }); + + test('should dereference and contain metadata about origin', async () => { + const parseResult = await parse(fixturePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + const schemaElement = evaluate( + '/components/schemas/User/properties/profile', + parseResult.api + ); + const dereferenced = await dereferenceApiDOM(schemaElement, { + parse: { mediaType: mediaTypes.latest('json') }, + resolve: { baseURI: `${fixturePath}#/components/schemas/User/properties/profile` }, + }); + + expect(dereferenced.meta.get('ref-origin').toValue()).toEqual( + expect.stringMatching(/internal-only\/root\.json$/) + ); + }); + }); + + describe('given single SchemaElement passed to dereferenceApiDOM with external references', () => { const fixturePath = path.join(__dirname, '__fixtures__', 'external-only', 'root.json'); test('should dereference', async () => { diff --git a/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/index.js b/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/index.js index 6d363e84a..1b235b5e8 100644 --- a/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/index.js +++ b/test/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/index.js @@ -3,9 +3,12 @@ import { toValue, toJSON } from '@swagger-api/apidom-core'; import { isSchemaElement, mediaTypes } from '@swagger-api/apidom-ns-openapi-3-1'; import { evaluate } from '@swagger-api/apidom-json-pointer'; import { + parse, dereference, dereferenceApiDOM, resolve, + Reference, + ReferenceSet, } from '@swagger-api/apidom-reference/configuration/empty'; // eslint-disable-next-line camelcase @@ -1049,6 +1052,29 @@ describe('dereference', () => { }); }); + describe('given Schema Objects with $ref keyword containing URL path override', () => { + const fixturePath = path.join(rootFixturePath, '$ref-url-path-override'); + + test('should dereference', async () => { + const rootFilePath = path.join(fixturePath, 'root.json'); + const parseResult = await parse(rootFilePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + const uri = 'https://example.com/'; + const reference = Reference({ uri, value: parseResult }); + const refSet = ReferenceSet({ refs: [reference] }); + + const actual = await dereference(uri, { + dereference: { refSet }, + parse: { mediaType: mediaTypes.latest('json') }, + }); + + const expected = globalThis.loadJsonFile(path.join(fixturePath, 'dereferenced.json')); + + expect(toValue(actual)).toEqual(expected); + }); + }); + describe('given Schema Objects with $ref keyword containing resolvable URL', () => { test('should dereference', async () => { const fixturePath = path.join(rootFixturePath, '$ref-url-resolvable'); @@ -1114,6 +1140,29 @@ describe('dereference', () => { }); }); + describe('given Schema Objects with $anchor keyword after $id pointing to internal schema', () => { + const fixturePath = path.join(rootFixturePath, '$anchor-internal-no-embedding'); + + test('should dereference', async () => { + const rootFilePath = path.join(fixturePath, 'root.json'); + const parseResult = await parse(rootFilePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + const uri = 'https://example.com/'; + const reference = Reference({ uri, value: parseResult }); + const refSet = ReferenceSet({ refs: [reference] }); + + const actual = await dereference(uri, { + dereference: { refSet }, + parse: { mediaType: mediaTypes.latest('json') }, + }); + + const expected = globalThis.loadJsonFile(path.join(fixturePath, 'dereferenced.json')); + + expect(toValue(actual)).toEqual(expected); + }); + }); + describe('given Schema Objects with $ref keyword containing unresolvable URL', () => { const fixturePath = path.join(rootFixturePath, '$ref-url-unresolvable'); const rootFilePath = path.join(fixturePath, 'root.json');