From 8a6cd9cedeef4ce43cf1105e82c6ddf29f5a136e Mon Sep 17 00:00:00 2001 From: Vladimir Gorej Date: Fri, 6 Jan 2023 13:36:08 +0100 Subject: [PATCH] fix(reference): fix bug in OpenAPI 3.1.0 Schema Object resolving Refs https://github.com/swagger-api/swagger-js/issues/2760 --- .../resolve/strategies/openapi-3-1/visitor.ts | 21 ++++++++-- .../fixtures/$ref-url/dereferenced.json | 38 +++++++++++++++++++ .../schema-object/fixtures/$ref-url/root.json | 30 +++++++++++++++ .../openapi-3-1/schema-object/index.ts | 13 +++++++ 4 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 packages/apidom-reference/test/resolve/strategies/openapi-3-1/schema-object/fixtures/$ref-url/dereferenced.json create mode 100644 packages/apidom-reference/test/resolve/strategies/openapi-3-1/schema-object/fixtures/$ref-url/root.json diff --git a/packages/apidom-reference/src/resolve/strategies/openapi-3-1/visitor.ts b/packages/apidom-reference/src/resolve/strategies/openapi-3-1/visitor.ts index 3d8c7e3b55..e9d3416fe5 100644 --- a/packages/apidom-reference/src/resolve/strategies/openapi-3-1/visitor.ts +++ b/packages/apidom-reference/src/resolve/strategies/openapi-3-1/visitor.ts @@ -211,6 +211,7 @@ const OpenApi3_1ResolveVisitor = stampit({ const $refBaseURIStrippedHash = url.stripHash($refBaseURI); const file = File({ uri: $refBaseURIStrippedHash }); const isUnknownURI = none((r: IResolver) => r.canRead(file), this.options.resolve.resolvers); + const isURL = !isUnknownURI; const isExternal = !isUnknownURI && this.reference.uri !== $refBaseURIStrippedHash; // ignore resolving external Reference Objects @@ -222,9 +223,23 @@ const OpenApi3_1ResolveVisitor = stampit({ } if (!has($refBaseURIStrippedHash, this.crawlingMap)) { - this.crawlingMap[$refBaseURIStrippedHash] = isUnknownURI - ? this.reference - : this.toReference($refBaseURIStrippedHash); + try { + if (isUnknownURI || isURL) { + this.crawlingMap[$refBaseURIStrippedHash] = this.reference; + } else { + this.crawlingMap[$refBaseURIStrippedHash] = this.toReference( + url.unsanitize($refBaseURI), + ); + } + } catch (error) { + if (isURL && error instanceof EvaluationJsonSchemaUriError) { + this.crawlingMap[$refBaseURIStrippedHash] = this.toReference( + url.unsanitize($refBaseURI), + ); + } else { + throw error; + } + } } this.crawledElements.push(schemaElement); diff --git a/packages/apidom-reference/test/resolve/strategies/openapi-3-1/schema-object/fixtures/$ref-url/dereferenced.json b/packages/apidom-reference/test/resolve/strategies/openapi-3-1/schema-object/fixtures/$ref-url/dereferenced.json new file mode 100644 index 0000000000..990e6b83a1 --- /dev/null +++ b/packages/apidom-reference/test/resolve/strategies/openapi-3-1/schema-object/fixtures/$ref-url/dereferenced.json @@ -0,0 +1,38 @@ +[ + { + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$id": "https://swagger.io/schemas/user-profile", + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } + } + } + }, + "UserProfile": { + "$id": "https://swagger.io/schemas/user-profile", + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } + } + } + } + } +] diff --git a/packages/apidom-reference/test/resolve/strategies/openapi-3-1/schema-object/fixtures/$ref-url/root.json b/packages/apidom-reference/test/resolve/strategies/openapi-3-1/schema-object/fixtures/$ref-url/root.json new file mode 100644 index 0000000000..1b6485de39 --- /dev/null +++ b/packages/apidom-reference/test/resolve/strategies/openapi-3-1/schema-object/fixtures/$ref-url/root.json @@ -0,0 +1,30 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$ref": "https://swagger.io/schemas/user-profile" + } + } + }, + "UserProfile": { + "$id": "https://swagger.io/schemas/user-profile", + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } + } + } + } +} diff --git a/packages/apidom-reference/test/resolve/strategies/openapi-3-1/schema-object/index.ts b/packages/apidom-reference/test/resolve/strategies/openapi-3-1/schema-object/index.ts index c5db163532..0464f6650c 100644 --- a/packages/apidom-reference/test/resolve/strategies/openapi-3-1/schema-object/index.ts +++ b/packages/apidom-reference/test/resolve/strategies/openapi-3-1/schema-object/index.ts @@ -263,6 +263,19 @@ describe('resolve', function () { }); }); + context('given Schema Objects with $ref keyword containing URL', function () { + const fixturePath = path.join(rootFixturePath, '$ref-url'); + + specify('should resolve', async function () { + const rootFilePath = path.join(fixturePath, 'root.json'); + const refSet = await resolve(rootFilePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + + assert.strictEqual(refSet.size, 1); + }); + }); + context( 'given Schema Objects with $ref keyword containing Uniform Resource Name', function () {