From c7f404711118de9c2652dc2a79c4d035ee21edf6 Mon Sep 17 00:00:00 2001 From: Vladimir Gorej Date: Wed, 4 Jan 2023 13:59:36 +0100 Subject: [PATCH] feat(resolver): add support for OpenAPI 3.1.0 resolution Refs #2744 --- config/webpack/browser.config.babel.js | 2 +- package-lock.json | 158 +++++------ package.json | 8 +- src/resolver/index.js | 7 +- src/resolver/strategies/openapi-3-1.js | 67 +++++ .../openapi-2--3-0.js} | 4 +- .../openapi-3-1/__fixtures__/petstore.json | 179 ++++++++++++ .../openapi-3-1/__snapshots__/index.js.snap | 261 ++++++++++++++++++ test/resolver/strategies/openapi-3-1/index.js | 29 ++ 9 files changed, 628 insertions(+), 87 deletions(-) create mode 100644 src/resolver/strategies/openapi-3-1.js rename test/resolver/{resolver.js => strategies/openapi-2--3-0.js} (99%) create mode 100644 test/resolver/strategies/openapi-3-1/__fixtures__/petstore.json create mode 100644 test/resolver/strategies/openapi-3-1/__snapshots__/index.js.snap create mode 100644 test/resolver/strategies/openapi-3-1/index.js diff --git a/config/webpack/browser.config.babel.js b/config/webpack/browser.config.babel.js index aa3cddda9a..9e10c78df0 100644 --- a/config/webpack/browser.config.babel.js +++ b/config/webpack/browser.config.babel.js @@ -74,7 +74,7 @@ const browserMin = { devtool: 'source-map', performance: { hints: 'error', - maxEntrypointSize: 270000, + maxEntrypointSize: 500000, maxAssetSize: 1300000, }, output: { diff --git a/package-lock.json b/package-lock.json index 4801dcb7aa..e3b2a75852 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,10 +10,10 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.11.2", - "@swagger-api/apidom-core": "^0.62.0", - "@swagger-api/apidom-json-pointer": "^0.62.0", - "@swagger-api/apidom-ns-openapi-3-1": "^0.62.0", - "@swagger-api/apidom-reference": "^0.62.0", + "@swagger-api/apidom-core": "^0.62.1", + "@swagger-api/apidom-json-pointer": "^0.62.1", + "@swagger-api/apidom-ns-openapi-3-1": "^0.62.1", + "@swagger-api/apidom-reference": "^0.62.1", "cookie": "~0.5.0", "cross-fetch": "^3.1.5", "deepmerge": "~4.2.2", @@ -6790,9 +6790,9 @@ } }, "node_modules/@swagger-api/apidom-ast": { - "version": "0.62.0", - "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-ast/0.62.0/25aefcf2fca9a013e5c6bca1f5790029e3481a51", - "integrity": "sha512-4GLnXbllh3WhQUCMc6V8xx6sLaURvU6aKUncAs2sbT+5plEEfvDkY74gi/zMEeoA05tBZtIL7MWt7gW1QV2MQQ==", + "version": "0.62.1", + "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-ast/0.62.1/319b518fdda0c4d6b680c49310cc804e2c586af3", + "integrity": "sha512-83tD2A1fQLgceFYxJaf0E1jQE8wM7bmuOI3GW55T5kipsj2jwpBvn4CMO694i9RIkpGIgvn8Ks7vJZ0mfCBeyg==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "=7.20.7", @@ -6804,13 +6804,13 @@ } }, "node_modules/@swagger-api/apidom-core": { - "version": "0.62.0", - "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-core/0.62.0/0c9685da739b9045b3182b9218292098be9ee3be", - "integrity": "sha512-21XHt7aG5qReevyHhaB9HZD587uLYNpkzvvI/Je4wVNw0Iec8hIbUN3WpCOeg7CTO1aaA+XN1GWZtv+XfkCMVw==", + "version": "0.62.1", + "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-core/0.62.1/82fe01b573e6e7cf332a3d8c36d2abc03325e2ae", + "integrity": "sha512-0xAVlaYzTFVz+xGMab3rx2eSz4vdHbokCL2JFvs8p3cAaTSclOIVa4mLzesNNZgNNZcoPCL/LhKxFnvSg+bN1g==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "=7.20.7", - "@swagger-api/apidom-ast": "^0.62.0", + "@swagger-api/apidom-ast": "^0.62.1", "@types/ramda": "=0.28.20", "minim": "=0.23.8", "ramda": "=0.28.0", @@ -6820,13 +6820,13 @@ } }, "node_modules/@swagger-api/apidom-json-pointer": { - "version": "0.62.0", - "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-json-pointer/0.62.0/be20413b33186af12a41c40ba458f79e4a2fb7bb", - "integrity": "sha512-eA812EfN/yXZyAlgkzIMeUGaTv6pe0wTqVbXoKxmpdYcdMKVzByytt+l6DjKs/ia4uuS+mzKtY2S4+dIN9lJQg==", + "version": "0.62.1", + "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-json-pointer/0.62.1/509a60ad89dbae6b7601da698d796334a5058417", + "integrity": "sha512-+hsor8tp3OUWBAlb0UjAVgzveLPcyjvokrVYp0wF8TlSoNYKbEEjbRbvv49MaW57uH0c4i13PYSlEkwlRMZoBg==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "=7.20.7", - "@swagger-api/apidom-core": "^0.62.0", + "@swagger-api/apidom-core": "^0.62.1", "ramda": "=0.28.0", "ramda-adjunct": "=3.4.0" } @@ -6838,13 +6838,13 @@ "integrity": "sha512-3HfneK3DGAm05fpyj20sT3apkNcvPpCuccOThOPdzz8sY7GgQGe0l93XH9bt+YzibcTIgUAIMoyVJI740RtgyQ==" }, "node_modules/@swagger-api/apidom-ns-json-schema-draft-4": { - "version": "0.62.0", - "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-ns-json-schema-draft-4/0.62.0/ebcdcec2ba22edc89b360f6d048097a2270dc650", - "integrity": "sha512-H8d49uFMPO+QLi0hjJZ0X56t310j95fn4xrk/12tgc5mHIcAuq77Uxsfk5aK6JuRCamBBLLD8FDgX/Jqw2czUg==", + "version": "0.62.1", + "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-ns-json-schema-draft-4/0.62.1/fbcd8bc5bbb534a9f677f6604454307d3363e04f", + "integrity": "sha512-EZOwVkL/HgpNWfqEbzOsxczy/HL4Qu5KsMy7NaiCtQixikSpS6tw+8kN+Vy6EzyYe5PsWFvLmelGpeqDnO9bHw==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "=7.20.7", - "@swagger-api/apidom-core": "^0.62.0", + "@swagger-api/apidom-core": "^0.62.1", "@types/ramda": "=0.28.20", "ramda": "=0.28.0", "ramda-adjunct": "=3.4.0", @@ -6852,14 +6852,14 @@ } }, "node_modules/@swagger-api/apidom-ns-openapi-3-0": { - "version": "0.62.0", - "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-ns-openapi-3-0/0.62.0/7fab1d1066d0bfa56e01a40ab7fdb1858283f7dd", - "integrity": "sha512-LDIv6FDhKIYIqt9LGeOXxiQbStWKELEx0xRZWZr/iCxxGFjBdfSC7Y5ZLiJ7AZ6RZcudpGSls9f3ArNDFAfR1w==", + "version": "0.62.1", + "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-ns-openapi-3-0/0.62.1/c704e48d5c5f60b6e2e73610096fa6abff9d7d3a", + "integrity": "sha512-22+6oAobEdDkT9esogVaWqbCWVVKHet+0R9FVxDG/4t0YwrmGzXW0Fgcr6COc9OEadwwnpwHACMjh3f1l8hYnQ==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "=7.20.7", - "@swagger-api/apidom-core": "^0.62.0", - "@swagger-api/apidom-ns-json-schema-draft-4": "^0.62.0", + "@swagger-api/apidom-core": "^0.62.1", + "@swagger-api/apidom-ns-json-schema-draft-4": "^0.62.1", "@types/ramda": "=0.28.20", "ramda": "=0.28.0", "ramda-adjunct": "=3.4.0", @@ -6867,14 +6867,14 @@ } }, "node_modules/@swagger-api/apidom-ns-openapi-3-1": { - "version": "0.62.0", - "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-ns-openapi-3-1/0.62.0/8131ab2a6fdae220f824d0fe97f06e1540cd2381", - "integrity": "sha512-2IAa/kP6wNoyFGYuKc481NLSSmXwOprQSA4VDXerubwXnafa668V3IIlMlqxvPu9ibkdQl2ebXi9HSVJP6LEog==", + "version": "0.62.1", + "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-ns-openapi-3-1/0.62.1/8d550c0a806c8fc04f8af99bd0f94d89e1b08e7f", + "integrity": "sha512-R843rR7weZQzDDma1EeNnnJ1haWpk17Entc3uCZr6TTm0MCwhI5/dN+Rs1oiiOvuX386GMrarMlZAXX4Q/tG8w==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "=7.20.7", - "@swagger-api/apidom-core": "^0.62.0", - "@swagger-api/apidom-ns-openapi-3-0": "^0.62.0", + "@swagger-api/apidom-core": "^0.62.1", + "@swagger-api/apidom-ns-openapi-3-0": "^0.62.1", "@types/ramda": "=0.28.20", "ramda": "=0.28.0", "ramda-adjunct": "=3.4.0", @@ -6942,27 +6942,27 @@ "integrity": "sha512-3HfneK3DGAm05fpyj20sT3apkNcvPpCuccOThOPdzz8sY7GgQGe0l93XH9bt+YzibcTIgUAIMoyVJI740RtgyQ==" }, "node_modules/@swagger-api/apidom-reference": { - "version": "0.62.0", - "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-reference/0.62.0/e78d8b225951a621dd73839f7ad8094049f7723b", - "integrity": "sha512-yK5ogzHcs7NoQ1G2g4xadDxN2WPPlHD3qN9UYuzw6uZXpK6p+RkrWLKcgCVgN2COApv49IvWlm665Vw1dCvxRA==", + "version": "0.62.1", + "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-reference/0.62.1/714a6d28166bba5b786cd954c40f9e6821be7f8b", + "integrity": "sha512-FkAYKRdT4T0MXiRIDaJ+xjxAd36M1nX2AHn8GkFSB9NOmARg3qLlVj3gDnoPIV/yG1pBWiLsjHFuV3rDMQ6dbw==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "=7.20.7", - "@swagger-api/apidom-core": "^0.62.0", - "@swagger-api/apidom-json-pointer": "^0.62.0", - "@swagger-api/apidom-ns-asyncapi-2": "^0.62.0", - "@swagger-api/apidom-ns-openapi-3-0": "^0.62.0", - "@swagger-api/apidom-ns-openapi-3-1": "^0.62.0", - "@swagger-api/apidom-parser-adapter-api-design-systems-json": "^0.62.0", - "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "^0.62.0", - "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "^0.62.0", - "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "^0.62.0", - "@swagger-api/apidom-parser-adapter-json": "^0.62.0", - "@swagger-api/apidom-parser-adapter-openapi-json-3-0": "^0.62.0", - "@swagger-api/apidom-parser-adapter-openapi-json-3-1": "^0.62.0", - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "^0.62.0", - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "^0.62.0", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.62.0", + "@swagger-api/apidom-core": "^0.62.1", + "@swagger-api/apidom-json-pointer": "^0.62.1", + "@swagger-api/apidom-ns-asyncapi-2": "^0.62.1", + "@swagger-api/apidom-ns-openapi-3-0": "^0.62.1", + "@swagger-api/apidom-ns-openapi-3-1": "^0.62.1", + "@swagger-api/apidom-parser-adapter-api-design-systems-json": "^0.62.1", + "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "^0.62.1", + "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "^0.62.1", + "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "^0.62.1", + "@swagger-api/apidom-parser-adapter-json": "^0.62.1", + "@swagger-api/apidom-parser-adapter-openapi-json-3-0": "^0.62.1", + "@swagger-api/apidom-parser-adapter-openapi-json-3-1": "^0.62.1", + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "^0.62.1", + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "^0.62.1", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.62.1", "@types/ramda": "=0.28.20", "axios": "=1.2.2", "minimatch": "=5.1.2", @@ -23788,9 +23788,9 @@ } }, "@swagger-api/apidom-ast": { - "version": "0.62.0", - "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-ast/0.62.0/25aefcf2fca9a013e5c6bca1f5790029e3481a51", - "integrity": "sha512-4GLnXbllh3WhQUCMc6V8xx6sLaURvU6aKUncAs2sbT+5plEEfvDkY74gi/zMEeoA05tBZtIL7MWt7gW1QV2MQQ==", + "version": "0.62.1", + "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-ast/0.62.1/319b518fdda0c4d6b680c49310cc804e2c586af3", + "integrity": "sha512-83tD2A1fQLgceFYxJaf0E1jQE8wM7bmuOI3GW55T5kipsj2jwpBvn4CMO694i9RIkpGIgvn8Ks7vJZ0mfCBeyg==", "requires": { "@babel/runtime-corejs3": "=7.20.7", "@types/ramda": "=0.28.20", @@ -23801,12 +23801,12 @@ } }, "@swagger-api/apidom-core": { - "version": "0.62.0", - "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-core/0.62.0/0c9685da739b9045b3182b9218292098be9ee3be", - "integrity": "sha512-21XHt7aG5qReevyHhaB9HZD587uLYNpkzvvI/Je4wVNw0Iec8hIbUN3WpCOeg7CTO1aaA+XN1GWZtv+XfkCMVw==", + "version": "0.62.1", + "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-core/0.62.1/82fe01b573e6e7cf332a3d8c36d2abc03325e2ae", + "integrity": "sha512-0xAVlaYzTFVz+xGMab3rx2eSz4vdHbokCL2JFvs8p3cAaTSclOIVa4mLzesNNZgNNZcoPCL/LhKxFnvSg+bN1g==", "requires": { "@babel/runtime-corejs3": "=7.20.7", - "@swagger-api/apidom-ast": "^0.62.0", + "@swagger-api/apidom-ast": "^0.62.1", "@types/ramda": "=0.28.20", "minim": "=0.23.8", "ramda": "=0.28.0", @@ -23816,12 +23816,12 @@ } }, "@swagger-api/apidom-json-pointer": { - "version": "0.62.0", - "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-json-pointer/0.62.0/be20413b33186af12a41c40ba458f79e4a2fb7bb", - "integrity": "sha512-eA812EfN/yXZyAlgkzIMeUGaTv6pe0wTqVbXoKxmpdYcdMKVzByytt+l6DjKs/ia4uuS+mzKtY2S4+dIN9lJQg==", + "version": "0.62.1", + "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-json-pointer/0.62.1/509a60ad89dbae6b7601da698d796334a5058417", + "integrity": "sha512-+hsor8tp3OUWBAlb0UjAVgzveLPcyjvokrVYp0wF8TlSoNYKbEEjbRbvv49MaW57uH0c4i13PYSlEkwlRMZoBg==", "requires": { "@babel/runtime-corejs3": "=7.20.7", - "@swagger-api/apidom-core": "^0.62.0", + "@swagger-api/apidom-core": "^0.62.1", "ramda": "=0.28.0", "ramda-adjunct": "=3.4.0" } @@ -23832,12 +23832,12 @@ "integrity": "sha512-3HfneK3DGAm05fpyj20sT3apkNcvPpCuccOThOPdzz8sY7GgQGe0l93XH9bt+YzibcTIgUAIMoyVJI740RtgyQ==" }, "@swagger-api/apidom-ns-json-schema-draft-4": { - "version": "0.62.0", - "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-ns-json-schema-draft-4/0.62.0/ebcdcec2ba22edc89b360f6d048097a2270dc650", - "integrity": "sha512-H8d49uFMPO+QLi0hjJZ0X56t310j95fn4xrk/12tgc5mHIcAuq77Uxsfk5aK6JuRCamBBLLD8FDgX/Jqw2czUg==", + "version": "0.62.1", + "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-ns-json-schema-draft-4/0.62.1/fbcd8bc5bbb534a9f677f6604454307d3363e04f", + "integrity": "sha512-EZOwVkL/HgpNWfqEbzOsxczy/HL4Qu5KsMy7NaiCtQixikSpS6tw+8kN+Vy6EzyYe5PsWFvLmelGpeqDnO9bHw==", "requires": { "@babel/runtime-corejs3": "=7.20.7", - "@swagger-api/apidom-core": "^0.62.0", + "@swagger-api/apidom-core": "^0.62.1", "@types/ramda": "=0.28.20", "ramda": "=0.28.0", "ramda-adjunct": "=3.4.0", @@ -23845,13 +23845,13 @@ } }, "@swagger-api/apidom-ns-openapi-3-0": { - "version": "0.62.0", - "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-ns-openapi-3-0/0.62.0/7fab1d1066d0bfa56e01a40ab7fdb1858283f7dd", - "integrity": "sha512-LDIv6FDhKIYIqt9LGeOXxiQbStWKELEx0xRZWZr/iCxxGFjBdfSC7Y5ZLiJ7AZ6RZcudpGSls9f3ArNDFAfR1w==", + "version": "0.62.1", + "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-ns-openapi-3-0/0.62.1/c704e48d5c5f60b6e2e73610096fa6abff9d7d3a", + "integrity": "sha512-22+6oAobEdDkT9esogVaWqbCWVVKHet+0R9FVxDG/4t0YwrmGzXW0Fgcr6COc9OEadwwnpwHACMjh3f1l8hYnQ==", "requires": { "@babel/runtime-corejs3": "=7.20.7", - "@swagger-api/apidom-core": "^0.62.0", - "@swagger-api/apidom-ns-json-schema-draft-4": "^0.62.0", + "@swagger-api/apidom-core": "^0.62.1", + "@swagger-api/apidom-ns-json-schema-draft-4": "^0.62.1", "@types/ramda": "=0.28.20", "ramda": "=0.28.0", "ramda-adjunct": "=3.4.0", @@ -23859,13 +23859,13 @@ } }, "@swagger-api/apidom-ns-openapi-3-1": { - "version": "0.62.0", - "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-ns-openapi-3-1/0.62.0/8131ab2a6fdae220f824d0fe97f06e1540cd2381", - "integrity": "sha512-2IAa/kP6wNoyFGYuKc481NLSSmXwOprQSA4VDXerubwXnafa668V3IIlMlqxvPu9ibkdQl2ebXi9HSVJP6LEog==", + "version": "0.62.1", + "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-ns-openapi-3-1/0.62.1/8d550c0a806c8fc04f8af99bd0f94d89e1b08e7f", + "integrity": "sha512-R843rR7weZQzDDma1EeNnnJ1haWpk17Entc3uCZr6TTm0MCwhI5/dN+Rs1oiiOvuX386GMrarMlZAXX4Q/tG8w==", "requires": { "@babel/runtime-corejs3": "=7.20.7", - "@swagger-api/apidom-core": "^0.62.0", - "@swagger-api/apidom-ns-openapi-3-0": "^0.62.0", + "@swagger-api/apidom-core": "^0.62.1", + "@swagger-api/apidom-ns-openapi-3-0": "^0.62.1", "@types/ramda": "=0.28.20", "ramda": "=0.28.0", "ramda-adjunct": "=3.4.0", @@ -23923,16 +23923,16 @@ "integrity": "sha512-3HfneK3DGAm05fpyj20sT3apkNcvPpCuccOThOPdzz8sY7GgQGe0l93XH9bt+YzibcTIgUAIMoyVJI740RtgyQ==" }, "@swagger-api/apidom-reference": { - "version": "0.62.0", - "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-reference/0.62.0/e78d8b225951a621dd73839f7ad8094049f7723b", - "integrity": "sha512-yK5ogzHcs7NoQ1G2g4xadDxN2WPPlHD3qN9UYuzw6uZXpK6p+RkrWLKcgCVgN2COApv49IvWlm665Vw1dCvxRA==", + "version": "0.62.1", + "resolved": "https://npm.pkg.github.com/download/@swagger-api/apidom-reference/0.62.1/714a6d28166bba5b786cd954c40f9e6821be7f8b", + "integrity": "sha512-FkAYKRdT4T0MXiRIDaJ+xjxAd36M1nX2AHn8GkFSB9NOmARg3qLlVj3gDnoPIV/yG1pBWiLsjHFuV3rDMQ6dbw==", "requires": { "@babel/runtime-corejs3": "=7.20.7", - "@swagger-api/apidom-core": "^0.62.0", - "@swagger-api/apidom-json-pointer": "^0.62.0", + "@swagger-api/apidom-core": "^0.62.1", + "@swagger-api/apidom-json-pointer": "^0.62.1", "@swagger-api/apidom-ns-asyncapi-2": "npm:-@0.0.1", - "@swagger-api/apidom-ns-openapi-3-0": "^0.62.0", - "@swagger-api/apidom-ns-openapi-3-1": "^0.62.0", + "@swagger-api/apidom-ns-openapi-3-0": "^0.62.1", + "@swagger-api/apidom-ns-openapi-3-1": "^0.62.1", "@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", diff --git a/package.json b/package.json index 9b67e18b1d..479a992bda 100644 --- a/package.json +++ b/package.json @@ -111,10 +111,10 @@ }, "dependencies": { "@babel/runtime-corejs3": "^7.11.2", - "@swagger-api/apidom-core": "^0.62.0", - "@swagger-api/apidom-reference": "^0.62.0", - "@swagger-api/apidom-ns-openapi-3-1": "^0.62.0", - "@swagger-api/apidom-json-pointer": "^0.62.0", + "@swagger-api/apidom-core": "^0.62.1", + "@swagger-api/apidom-reference": "^0.62.1", + "@swagger-api/apidom-ns-openapi-3-1": "^0.62.1", + "@swagger-api/apidom-json-pointer": "^0.62.1", "cookie": "~0.5.0", "cross-fetch": "^3.1.5", "deepmerge": "~4.2.2", diff --git a/src/resolver/index.js b/src/resolver/index.js index 1afec9dd95..7e63991720 100644 --- a/src/resolver/index.js +++ b/src/resolver/index.js @@ -1,7 +1,9 @@ // eslint-disable-next-line camelcase import resolveOpenAPI2_30Strategy from './strategies/openapi-2--3-0.js'; +import resolveOpenAPI31Strategy from './strategies/openapi-3-1.js'; import { makeFetchJSON } from './utils/index.js'; import * as optionsUtil from './utils/options.js'; +import { isOpenAPI31 } from '../helpers/openapi-predicates.js'; const resolve = async (options) => { const { spec, requestInterceptor, responseInterceptor } = options; @@ -11,8 +13,11 @@ const resolve = async (options) => { const retrievedSpec = spec || (await makeFetchJSON(httpClient, { requestInterceptor, responseInterceptor })(retrievalURI)); + const strategyOptions = { ...options, spec: retrievedSpec }; - return resolveOpenAPI2_30Strategy({ ...options, spec: retrievedSpec }); + return isOpenAPI31(retrievedSpec) + ? resolveOpenAPI31Strategy(strategyOptions) + : resolveOpenAPI2_30Strategy(strategyOptions); }; export default resolve; diff --git a/src/resolver/strategies/openapi-3-1.js b/src/resolver/strategies/openapi-3-1.js new file mode 100644 index 0000000000..723b298dc0 --- /dev/null +++ b/src/resolver/strategies/openapi-3-1.js @@ -0,0 +1,67 @@ +/* eslint-disable camelcase */ +import { toValue } from '@swagger-api/apidom-core'; +import { OpenApi3_1Element } from '@swagger-api/apidom-ns-openapi-3-1'; +import { dereferenceApiDOM } from '@swagger-api/apidom-reference/configuration/empty'; +import BinaryParser from '@swagger-api/apidom-reference/parse/parsers/binary'; +import OpenApi3_1ResolveStrategy from '@swagger-api/apidom-reference/resolve/strategies/openapi-3-1'; + +import * as optionsUtil from '../utils/options.js'; +import normalizeOpenAPI31 from '../../helpers/normalize/openapi-3-1.js'; +import HttpResolverSwaggerClient from '../../helpers/apidom/reference/resolve/resolvers/http-swagger-client/index.js'; +import JsonParser from '../../helpers/apidom/reference/parse/parsers/json/index.js'; +import YamlParser from '../../helpers/apidom/reference/parse/parsers/yaml-1-2/index.js'; +import OpenApiJson3_1Parser from '../../helpers/apidom/reference/parse/parsers/openapi-json-3-1/index.js'; +import OpenApiYaml3_1Parser from '../../helpers/apidom/reference/parse/parsers/openapi-yaml-3-1/index.js'; +import OpenApi3_1SwaggerClientDereferenceStrategy from '../../helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/index.js'; + +const resolveOpenAPI31Strategy = async (options) => { + const { + spec, + timeout, + redirects, + requestInterceptor, + responseInterceptor, + allowMetaPatches = false, + useCircularStructures = false, + skipNormalization = false, + } = options; + const openApiElement = OpenApi3_1Element.refract(spec); + const dereferenced = await dereferenceApiDOM(openApiElement, { + resolve: { + baseURI: optionsUtil.retrievalURI(options), + resolvers: [ + HttpResolverSwaggerClient({ + timeout: timeout || 10000, + redirects: redirects || 10, + }), + ], + resolverOpts: { + swaggerHTTPClientConfig: { + requestInterceptor, + responseInterceptor, + }, + }, + strategies: [OpenApi3_1ResolveStrategy()], + }, + parse: { + parsers: [ + OpenApiJson3_1Parser({ allowEmpty: false, sourceMap: false }), + OpenApiYaml3_1Parser({ allowEmpty: false, sourceMap: false }), + JsonParser({ allowEmpty: false, sourceMap: false }), + YamlParser({ allowEmpty: false, sourceMap: false }), + BinaryParser({ allowEmpty: false, sourceMap: false }), + ], + }, + dereference: { + strategies: [ + OpenApi3_1SwaggerClientDereferenceStrategy({ allowMetaPatches, useCircularStructures }), + ], + }, + }); + const normalized = skipNormalization ? dereferenced : normalizeOpenAPI31(dereferenced); + + return { spec: toValue(normalized), errors: [] }; +}; + +export default resolveOpenAPI31Strategy; +/* eslint-enable camelcase */ diff --git a/test/resolver/resolver.js b/test/resolver/strategies/openapi-2--3-0.js similarity index 99% rename from test/resolver/resolver.js rename to test/resolver/strategies/openapi-2--3-0.js index 947b4afce2..f42a4df50a 100644 --- a/test/resolver/resolver.js +++ b/test/resolver/strategies/openapi-2--3-0.js @@ -3,7 +3,7 @@ import path from 'path'; import fs from 'fs'; import jsYaml from 'js-yaml'; -import Swagger from '../../src/index.js'; +import Swagger from '../../../src/index.js'; describe('resolver', () => { afterEach(() => { @@ -721,7 +721,7 @@ describe('resolver', () => { test('should not throw errors on resvered-keywords in freely-named-fields', () => { // Given const ReservedKeywordSpec = jsYaml.load( - fs.readFileSync(path.resolve(__dirname, '../data/reserved-keywords.yaml'), 'utf8') + fs.readFileSync(path.resolve(__dirname, '../../data/reserved-keywords.yaml'), 'utf8') ); // When diff --git a/test/resolver/strategies/openapi-3-1/__fixtures__/petstore.json b/test/resolver/strategies/openapi-3-1/__fixtures__/petstore.json new file mode 100644 index 0000000000..5ce290715d --- /dev/null +++ b/test/resolver/strategies/openapi-3-1/__fixtures__/petstore.json @@ -0,0 +1,179 @@ +{ + "openapi": "3.1.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore", + "license": { + "name": "MIT" + } + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1" + } + ], + "paths": { + "/pets": { + "get": { + "summary": "List all pets", + "operationId": "listPets", + "tags": [ + "pets" + ], + "parameters": [ + { + "name": "limit", + "in": "query", + "description": "How many items to return at one time (max 100)", + "required": false, + "schema": { + "type": "integer", + "maximum": 100, + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "A paged array of pets", + "headers": { + "x-next": { + "description": "A link to the next page of responses", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pets" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "post": { + "summary": "Create a pet", + "operationId": "createPets", + "tags": [ + "pets" + ], + "responses": { + "201": { + "description": "Null response" + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/pets/{petId}": { + "get": { + "summary": "Info for a specific pet", + "operationId": "showPetById", + "tags": [ + "pets" + ], + "parameters": [ + { + "name": "petId", + "in": "path", + "required": true, + "description": "The id of the pet to retrieve", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Expected response to a valid request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pet" + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Pet": { + "type": "object", + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "Pets": { + "type": "array", + "maxItems": 100, + "items": { + "$ref": "#/components/schemas/Pet" + } + }, + "Error": { + "type": "object", + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } +} diff --git a/test/resolver/strategies/openapi-3-1/__snapshots__/index.js.snap b/test/resolver/strategies/openapi-3-1/__snapshots__/index.js.snap new file mode 100644 index 0000000000..adac708daf --- /dev/null +++ b/test/resolver/strategies/openapi-3-1/__snapshots__/index.js.snap @@ -0,0 +1,261 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`resolve OpenAPI 3.1.0 strategy given OpenAPI 3.1.0 definition should resolve 1`] = ` +{ + "errors": [], + "spec": { + "$$normalized": true, + "components": { + "schemas": { + "Error": { + "properties": { + "code": { + "format": "int32", + "type": "integer", + }, + "message": { + "type": "string", + }, + }, + "required": [ + "code", + "message", + ], + "type": "object", + }, + "Pet": { + "properties": { + "id": { + "format": "int64", + "type": "integer", + }, + "name": { + "type": "string", + }, + "tag": { + "type": "string", + }, + }, + "required": [ + "id", + "name", + ], + "type": "object", + }, + "Pets": { + "items": { + "properties": { + "id": { + "format": "int64", + "type": "integer", + }, + "name": { + "type": "string", + }, + "tag": { + "type": "string", + }, + }, + "required": [ + "id", + "name", + ], + "type": "object", + }, + "maxItems": 100, + "type": "array", + }, + }, + }, + "info": { + "license": { + "name": "MIT", + }, + "title": "Swagger Petstore", + "version": "1.0.0", + }, + "openapi": "3.1.0", + "paths": { + "/pets": { + "get": { + "operationId": "listPets", + "parameters": [ + { + "description": "How many items to return at one time (max 100)", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "format": "int32", + "maximum": 100, + "type": "integer", + }, + }, + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "properties": { + "id": { + "format": "int64", + "type": "integer", + }, + "name": { + "type": "string", + }, + "tag": { + "type": "string", + }, + }, + "required": [ + "id", + "name", + ], + "type": "object", + }, + "maxItems": 100, + "type": "array", + }, + }, + }, + "description": "A paged array of pets", + "headers": { + "x-next": { + "description": "A link to the next page of responses", + "schema": { + "type": "string", + }, + }, + }, + }, + "default": { + "content": { + "application/json": { + "schema": { + "properties": { + "code": { + "format": "int32", + "type": "integer", + }, + "message": { + "type": "string", + }, + }, + "required": [ + "code", + "message", + ], + "type": "object", + }, + }, + }, + "description": "unexpected error", + }, + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1", + }, + ], + "summary": "List all pets", + "tags": [ + "pets", + ], + }, + "post": { + "operationId": "createPets", + "responses": { + "201": { + "description": "Null response", + }, + "default": { + "content": { + "application/json": { + "schema": { + "$ref": "https://example.com/petstore.json#/components/schemas/Error", + }, + }, + }, + "description": "unexpected error", + }, + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1", + }, + ], + "summary": "Create a pet", + "tags": [ + "pets", + ], + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1", + }, + ], + }, + "/pets/{petId}": { + "get": { + "operationId": "showPetById", + "parameters": [ + { + "description": "The id of the pet to retrieve", + "in": "path", + "name": "petId", + "required": true, + "schema": { + "type": "string", + }, + }, + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "https://example.com/petstore.json#/components/schemas/Pet", + }, + }, + }, + "description": "Expected response to a valid request", + }, + "default": { + "content": { + "application/json": { + "schema": { + "$ref": "https://example.com/petstore.json#/components/schemas/Error", + }, + }, + }, + "description": "unexpected error", + }, + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1", + }, + ], + "summary": "Info for a specific pet", + "tags": [ + "pets", + ], + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1", + }, + ], + }, + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1", + }, + ], + }, +} +`; diff --git a/test/resolver/strategies/openapi-3-1/index.js b/test/resolver/strategies/openapi-3-1/index.js new file mode 100644 index 0000000000..e007e8f47b --- /dev/null +++ b/test/resolver/strategies/openapi-3-1/index.js @@ -0,0 +1,29 @@ +import path from 'node:path'; +import fetchMock from 'fetch-mock'; + +import Swagger from '../../../../src/index.js'; + +const fixturePath = path.join(__dirname, '__fixtures__'); + +describe('resolve', () => { + describe('OpenAPI 3.1.0 strategy', () => { + test('should expose a resolver function', () => { + expect(Swagger.resolve).toBeInstanceOf(Function); + }); + + describe('given OpenAPI 3.1.0 definition', () => { + test('should resolve', async () => { + const url = 'https://example.com/petstore.json'; + const response = new Response(globalThis.loadFile(path.join(fixturePath, 'petstore.json'))); + fetchMock.get(url, response, { repeat: 1 }); + const resolvedSpec = await Swagger.resolve({ + url: 'https://example.com/petstore.json', + }); + + expect(resolvedSpec).toMatchSnapshot(); + + fetchMock.restore(); + }); + }); + }); +});