From a69a6983e5b0295417fbab8f2213d641f34768e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Gorej?= Date: Sun, 26 Jan 2025 23:08:51 +0100 Subject: [PATCH] fix(ns-json-schema): collect properly metadata for dialect and schema identifiers (#4689) --- .../refractor/__snapshots__/index.mjs.snap | 128 +++++++++++++++--- .../refractor/elements/JSONSchema/index.ts | 62 ++++++++- .../refractor/__snapshots__/index.mjs.snap | 128 +++++++++++++++--- .../refractor/elements/JSONSchema/index.ts | 62 ++++++++- .../visitors/SpecificationVisitor.ts | 4 +- .../refractor/visitors/json-schema/index.ts | 2 +- .../refractor/__snapshots__/index.mjs.snap | 88 ++++++++++-- .../refractor/elements/JSONSchema/index.ts | 62 ++++++++- .../refractor/__snapshots__/index.mjs.snap | 104 ++++++++++++-- .../refractor/elements/JSONSchema/index.ts | 62 ++++++++- .../refractor/__snapshots__/index.mjs.snap | 104 ++++++++++++-- .../refractor/elements/JSONSchema/index.ts | 62 ++++++++- 12 files changed, 786 insertions(+), 82 deletions(-) diff --git a/packages/apidom-ns-json-schema-2019-09/test/refractor/__snapshots__/index.mjs.snap b/packages/apidom-ns-json-schema-2019-09/test/refractor/__snapshots__/index.mjs.snap index 46a65a493f..65b044131a 100644 --- a/packages/apidom-ns-json-schema-2019-09/test/refractor/__snapshots__/index.mjs.snap +++ b/packages/apidom-ns-json-schema-2019-09/test/refractor/__snapshots__/index.mjs.snap @@ -294,7 +294,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2019-09 shape shou "content": "https://json-schema.org/draft/2019-09/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -340,7 +346,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2019-09 shape shou "content": "https://json-schema.org/draft/2019-09/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -446,7 +458,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2019-09 shape shou "content": "https://json-schema.org/draft/2019-09/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -602,7 +620,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2019-09 shape shou "content": "https://json-schema.org/draft/2019-09/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -638,7 +662,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2019-09 shape shou "content": "https://json-schema.org/draft/2019-09/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -702,7 +732,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2019-09 shape shou "content": "https://json-schema.org/draft/2019-09/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -770,7 +806,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2019-09 shape shou "content": "https://json-schema.org/draft/2019-09/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -806,7 +848,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2019-09 shape shou "content": "https://json-schema.org/draft/2019-09/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -959,7 +1007,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2019-09 shape shou "content": "https://json-schema.org/draft/2019-09/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1007,7 +1061,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2019-09 shape shou "content": "https://json-schema.org/draft/2019-09/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1055,7 +1115,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2019-09 shape shou "content": "https://json-schema.org/draft/2019-09/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1089,7 +1155,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2019-09 shape shou "content": "https://json-schema.org/draft/2019-09/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1153,7 +1225,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2019-09 shape shou "content": "https://json-schema.org/draft/2019-09/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1561,7 +1639,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2019-09 shape shou "content": "https://json-schema.org/draft/2019-09/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1593,7 +1677,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2019-09 shape shou "content": "https://json-schema.org/draft/2019-09/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1751,7 +1841,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2019-09 shape shou "content": "https://json-schema.org/draft/2019-09/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } diff --git a/packages/apidom-ns-json-schema-2019-09/test/refractor/elements/JSONSchema/index.ts b/packages/apidom-ns-json-schema-2019-09/test/refractor/elements/JSONSchema/index.ts index 41a15ab11e..45397251a3 100644 --- a/packages/apidom-ns-json-schema-2019-09/test/refractor/elements/JSONSchema/index.ts +++ b/packages/apidom-ns-json-schema-2019-09/test/refractor/elements/JSONSchema/index.ts @@ -1,7 +1,7 @@ import { assert, expect } from 'chai'; -import { ObjectElement, sexprs, toValue } from '@swagger-api/apidom-core'; +import { ObjectElement, sexprs, toValue, find, isElement } from '@swagger-api/apidom-core'; -import { JSONSchemaElement } from '../../../../src/index.ts'; +import { JSONSchemaElement, isJSONSchemaElement } from '../../../../src/index.ts'; describe('refractor', function () { context('elements', function () { @@ -118,6 +118,64 @@ describe('refractor', function () { }); }); + context('given JSONSchema ancestors are embedded resources', function () { + specify('should expose ancestors schema identifiers as metadata', function () { + const jsonSchemaElement = JSONSchemaElement.refract({ + type: 'array', + oneOf: [ + { + $id: '$id1', + type: 'number', + items: { $id: '$id2', type: 'object' }, + }, + ], + items: { + type: 'string', + }, + }); + const foundJsonSchemaElement = find( + (e) => isJSONSchemaElement(e) && isElement(e.$id) && e.$id.equals('$id2'), + jsonSchemaElement, + ); + const ancestorsSchemaIdentifiers = foundJsonSchemaElement!.meta.get( + 'ancestorsSchemaIdentifiers', + ); + + assert.deepEqual(toValue(ancestorsSchemaIdentifiers), ['$id1', '$id2']); + }); + }); + + context('given JSONSchema switches dialect via parent schema', function () { + specify('should expose ancestors schema dialect identifier as metadata', function () { + const jsonSchemaElement = JSONSchemaElement.refract({ + type: 'object', + oneOf: [ + { + type: 'number', + $schema: 'schema1', + items: { type: 'object' }, + }, + ], + items: { + type: 'string', + }, + }) as JSONSchemaElement; + + assert.strictEqual( + toValue(jsonSchemaElement.meta.get('inheritedDialectIdentifier')), + 'https://json-schema.org/draft/2019-09/schema', + ); + assert.strictEqual( + toValue(jsonSchemaElement.items!.meta.get('inheritedDialectIdentifier')), + 'https://json-schema.org/draft/2019-09/schema', + ); + assert.strictEqual( + toValue(jsonSchemaElement.oneOf!.get(0).items.meta.get('inheritedDialectIdentifier')), + 'schema1', + ); + }); + }); + context('given $ref fields', function () { specify('should refract to semantic ApiDOM tree', function () { const jsonSchemaElement = JSONSchemaElement.refract({ diff --git a/packages/apidom-ns-json-schema-2020-12/test/refractor/__snapshots__/index.mjs.snap b/packages/apidom-ns-json-schema-2020-12/test/refractor/__snapshots__/index.mjs.snap index 7c178f0f44..f2af119a5b 100644 --- a/packages/apidom-ns-json-schema-2020-12/test/refractor/__snapshots__/index.mjs.snap +++ b/packages/apidom-ns-json-schema-2020-12/test/refractor/__snapshots__/index.mjs.snap @@ -308,7 +308,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2020-12 shape shou "content": "https://json-schema.org/draft/2020-12/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -342,7 +348,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2020-12 shape shou "content": "https://json-schema.org/draft/2020-12/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -446,7 +458,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2020-12 shape shou "content": "https://json-schema.org/draft/2020-12/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -602,7 +620,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2020-12 shape shou "content": "https://json-schema.org/draft/2020-12/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -638,7 +662,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2020-12 shape shou "content": "https://json-schema.org/draft/2020-12/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -702,7 +732,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2020-12 shape shou "content": "https://json-schema.org/draft/2020-12/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -770,7 +806,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2020-12 shape shou "content": "https://json-schema.org/draft/2020-12/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -806,7 +848,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2020-12 shape shou "content": "https://json-schema.org/draft/2020-12/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -959,7 +1007,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2020-12 shape shou "content": "https://json-schema.org/draft/2020-12/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1007,7 +1061,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2020-12 shape shou "content": "https://json-schema.org/draft/2020-12/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1055,7 +1115,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2020-12 shape shou "content": "https://json-schema.org/draft/2020-12/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1089,7 +1155,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2020-12 shape shou "content": "https://json-schema.org/draft/2020-12/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1153,7 +1225,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2020-12 shape shou "content": "https://json-schema.org/draft/2020-12/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1572,7 +1650,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2020-12 shape shou "content": "https://json-schema.org/draft/2020-12/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1604,7 +1688,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2020-12 shape shou "content": "https://json-schema.org/draft/2020-12/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1762,7 +1852,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema 2020-12 shape shou "content": "https://json-schema.org/draft/2020-12/schema" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } diff --git a/packages/apidom-ns-json-schema-2020-12/test/refractor/elements/JSONSchema/index.ts b/packages/apidom-ns-json-schema-2020-12/test/refractor/elements/JSONSchema/index.ts index 43eaf2d5e6..7cc281c54b 100644 --- a/packages/apidom-ns-json-schema-2020-12/test/refractor/elements/JSONSchema/index.ts +++ b/packages/apidom-ns-json-schema-2020-12/test/refractor/elements/JSONSchema/index.ts @@ -1,7 +1,7 @@ import { assert, expect } from 'chai'; -import { ObjectElement, sexprs, toValue } from '@swagger-api/apidom-core'; +import { ObjectElement, sexprs, toValue, isElement, find } from '@swagger-api/apidom-core'; -import { JSONSchemaElement } from '../../../../src/index.ts'; +import { JSONSchemaElement, isJSONSchemaElement } from '../../../../src/index.ts'; describe('refractor', function () { context('elements', function () { @@ -116,6 +116,64 @@ describe('refractor', function () { }); }); + context('given JSONSchema ancestors are embedded resources', function () { + specify('should expose ancestors schema identifiers as metadata', function () { + const jsonSchemaElement = JSONSchemaElement.refract({ + type: 'array', + oneOf: [ + { + $id: '$id1', + type: 'number', + items: { $id: '$id2', type: 'object' }, + }, + ], + items: { + type: 'string', + }, + }); + const foundJsonSchemaElement = find( + (e) => isJSONSchemaElement(e) && isElement(e.$id) && e.$id.equals('$id2'), + jsonSchemaElement, + ); + const ancestorsSchemaIdentifiers = foundJsonSchemaElement!.meta.get( + 'ancestorsSchemaIdentifiers', + ); + + assert.deepEqual(toValue(ancestorsSchemaIdentifiers), ['$id1', '$id2']); + }); + }); + + context('given JSONSchema switches dialect via parent schema', function () { + specify('should expose ancestors schema dialect identifier as metadata', function () { + const jsonSchemaElement = JSONSchemaElement.refract({ + type: 'object', + oneOf: [ + { + type: 'number', + $schema: 'schema1', + items: { type: 'object' }, + }, + ], + items: { + type: 'string', + }, + }) as JSONSchemaElement; + + assert.strictEqual( + toValue(jsonSchemaElement.meta.get('inheritedDialectIdentifier')), + 'https://json-schema.org/draft/2020-12/schema', + ); + assert.strictEqual( + toValue(jsonSchemaElement.items!.meta.get('inheritedDialectIdentifier')), + 'https://json-schema.org/draft/2020-12/schema', + ); + assert.strictEqual( + toValue(jsonSchemaElement.oneOf!.get(0).items.meta.get('inheritedDialectIdentifier')), + 'schema1', + ); + }); + }); + context('given $ref fields', function () { specify('should refract to semantic ApiDOM tree', function () { const jsonSchemaElement = JSONSchemaElement.refract({ diff --git a/packages/apidom-ns-json-schema-draft-4/src/refractor/visitors/SpecificationVisitor.ts b/packages/apidom-ns-json-schema-draft-4/src/refractor/visitors/SpecificationVisitor.ts index e2b32eb15b..a7d4a6ca77 100644 --- a/packages/apidom-ns-json-schema-draft-4/src/refractor/visitors/SpecificationVisitor.ts +++ b/packages/apidom-ns-json-schema-draft-4/src/refractor/visitors/SpecificationVisitor.ts @@ -21,7 +21,7 @@ export interface SpecificationVisitorOptions extends VisitorOptions { class SpecificationVisitor extends Visitor { protected readonly specObj: typeof specification; - protected readonly passingOptionsNames: string[] = ['specObj']; + protected readonly passingOptionsNames: string[] = ['specObj', 'parent']; constructor({ specObj, ...rest }: SpecificationVisitorOptions) { super({ ...rest }); @@ -58,7 +58,7 @@ class SpecificationVisitor extends Visitor { toRefractedElement(specPath: string[], element: any, options = {}) { /** - * This is `Visitor shortcut`: mechanism for short circuiting the traversal and replacing + * This is `Visitor shortcut`: mechanism for short-circuiting the traversal and replacing * it by basic node cloning. * * Visiting the element is equivalent to cloning it if the prototype of a visitor diff --git a/packages/apidom-ns-json-schema-draft-4/src/refractor/visitors/json-schema/index.ts b/packages/apidom-ns-json-schema-draft-4/src/refractor/visitors/json-schema/index.ts index 50d39bf199..5cca39b803 100644 --- a/packages/apidom-ns-json-schema-draft-4/src/refractor/visitors/json-schema/index.ts +++ b/packages/apidom-ns-json-schema-draft-4/src/refractor/visitors/json-schema/index.ts @@ -55,7 +55,7 @@ class JSONSchemaVisitor extends Mixin( this.handleDialectIdentifier(objectElement); this.handleSchemaIdentifier(objectElement); - // for further processing consider this Schema Element as parent for all embedded Schema Elements + // for further processing consider this JSONSchema Element as parent for all sub-schemas this.parent = this.element; return FixedFieldsVisitor.prototype.ObjectElement.call(this, objectElement); diff --git a/packages/apidom-ns-json-schema-draft-4/test/refractor/__snapshots__/index.mjs.snap b/packages/apidom-ns-json-schema-draft-4/test/refractor/__snapshots__/index.mjs.snap index 023790cd7d..9efb9b8ad6 100644 --- a/packages/apidom-ns-json-schema-draft-4/test/refractor/__snapshots__/index.mjs.snap +++ b/packages/apidom-ns-json-schema-draft-4/test/refractor/__snapshots__/index.mjs.snap @@ -281,7 +281,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 4 shape shou "content": "http://json-schema.org/draft-04/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -327,7 +333,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 4 shape shou "content": "http://json-schema.org/draft-04/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -557,7 +569,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 4 shape shou "content": "http://json-schema.org/draft-04/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -593,7 +611,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 4 shape shou "content": "http://json-schema.org/draft-04/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -657,7 +681,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 4 shape shou "content": "http://json-schema.org/draft-04/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -725,7 +755,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 4 shape shou "content": "http://json-schema.org/draft-04/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -858,7 +894,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 4 shape shou "content": "http://json-schema.org/draft-04/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -906,7 +948,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 4 shape shou "content": "http://json-schema.org/draft-04/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -954,7 +1002,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 4 shape shou "content": "http://json-schema.org/draft-04/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -988,7 +1042,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 4 shape shou "content": "http://json-schema.org/draft-04/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1052,7 +1112,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 4 shape shou "content": "http://json-schema.org/draft-04/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } diff --git a/packages/apidom-ns-json-schema-draft-4/test/refractor/elements/JSONSchema/index.ts b/packages/apidom-ns-json-schema-draft-4/test/refractor/elements/JSONSchema/index.ts index 8179c6e74d..a977cacb42 100644 --- a/packages/apidom-ns-json-schema-draft-4/test/refractor/elements/JSONSchema/index.ts +++ b/packages/apidom-ns-json-schema-draft-4/test/refractor/elements/JSONSchema/index.ts @@ -1,7 +1,7 @@ import { assert, expect } from 'chai'; -import { ObjectElement, sexprs, toValue } from '@swagger-api/apidom-core'; +import { ObjectElement, sexprs, toValue, find, isElement } from '@swagger-api/apidom-core'; -import { JSONSchemaElement } from '../../../../src/index.ts'; +import { JSONSchemaElement, isJSONSchemaElement } from '../../../../src/index.ts'; describe('refractor', function () { context('elements', function () { @@ -65,6 +65,64 @@ describe('refractor', function () { }); }); + context('given JSONSchema ancestors are embedded resources', function () { + specify('should expose ancestors schema identifiers as metadata', function () { + const jsonSchemaElement = JSONSchemaElement.refract({ + type: 'array', + oneOf: [ + { + id: 'id1', + type: 'number', + items: { id: 'id2', type: 'object' }, + }, + ], + items: { + type: 'string', + }, + }); + const foundJsonSchemaElement = find( + (e) => isJSONSchemaElement(e) && isElement(e.get('id')) && e.get('id').equals('id2'), + jsonSchemaElement, + ); + const ancestorsSchemaIdentifiers = foundJsonSchemaElement!.meta.get( + 'ancestorsSchemaIdentifiers', + ); + + assert.deepEqual(toValue(ancestorsSchemaIdentifiers), ['id1', 'id2']); + }); + }); + + context('given JSONSchema switches dialect via parent schema', function () { + specify('should expose ancestors schema dialect identifier as metadata', function () { + const jsonSchemaElement = JSONSchemaElement.refract({ + type: 'object', + oneOf: [ + { + type: 'number', + $schema: 'schema1', + items: { type: 'object' }, + }, + ], + items: { + type: 'string', + }, + }) as JSONSchemaElement; + + assert.strictEqual( + toValue(jsonSchemaElement.meta.get('inheritedDialectIdentifier')), + 'http://json-schema.org/draft-04/schema#', + ); + assert.strictEqual( + toValue(jsonSchemaElement.items!.meta.get('inheritedDialectIdentifier')), + 'http://json-schema.org/draft-04/schema#', + ); + assert.strictEqual( + toValue(jsonSchemaElement.oneOf!.get(0).items.meta.get('inheritedDialectIdentifier')), + 'schema1', + ); + }); + }); + context('given fields of type JSONReference', function () { specify('should refract to semantic ApiDOM tree', function () { const jsonSchemaElement = JSONSchemaElement.refract({ diff --git a/packages/apidom-ns-json-schema-draft-6/test/refractor/__snapshots__/index.mjs.snap b/packages/apidom-ns-json-schema-draft-6/test/refractor/__snapshots__/index.mjs.snap index 3d3907a1b2..1f39fd23fc 100644 --- a/packages/apidom-ns-json-schema-draft-6/test/refractor/__snapshots__/index.mjs.snap +++ b/packages/apidom-ns-json-schema-draft-6/test/refractor/__snapshots__/index.mjs.snap @@ -281,7 +281,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 6 shape shou "content": "http://json-schema.org/draft-06/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -327,7 +333,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 6 shape shou "content": "http://json-schema.org/draft-06/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -433,7 +445,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 6 shape shou "content": "http://json-schema.org/draft-06/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -589,7 +607,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 6 shape shou "content": "http://json-schema.org/draft-06/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -625,7 +649,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 6 shape shou "content": "http://json-schema.org/draft-06/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -689,7 +719,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 6 shape shou "content": "http://json-schema.org/draft-06/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -757,7 +793,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 6 shape shou "content": "http://json-schema.org/draft-06/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -793,7 +835,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 6 shape shou "content": "http://json-schema.org/draft-06/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -946,7 +994,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 6 shape shou "content": "http://json-schema.org/draft-06/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -994,7 +1048,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 6 shape shou "content": "http://json-schema.org/draft-06/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1042,7 +1102,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 6 shape shou "content": "http://json-schema.org/draft-06/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1076,7 +1142,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 6 shape shou "content": "http://json-schema.org/draft-06/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1140,7 +1212,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 6 shape shou "content": "http://json-schema.org/draft-06/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } diff --git a/packages/apidom-ns-json-schema-draft-6/test/refractor/elements/JSONSchema/index.ts b/packages/apidom-ns-json-schema-draft-6/test/refractor/elements/JSONSchema/index.ts index 216d1cce81..824bab74fd 100644 --- a/packages/apidom-ns-json-schema-draft-6/test/refractor/elements/JSONSchema/index.ts +++ b/packages/apidom-ns-json-schema-draft-6/test/refractor/elements/JSONSchema/index.ts @@ -1,7 +1,7 @@ import { assert, expect } from 'chai'; -import { ObjectElement, sexprs, toValue } from '@swagger-api/apidom-core'; +import { ObjectElement, sexprs, toValue, find, isElement } from '@swagger-api/apidom-core'; -import { JSONSchemaElement } from '../../../../src/index.ts'; +import { JSONSchemaElement, isJSONSchemaElement } from '../../../../src/index.ts'; describe('refractor', function () { context('elements', function () { @@ -92,6 +92,64 @@ describe('refractor', function () { }); }); + context('given JSONSchema ancestors are embedded resources', function () { + specify('should expose ancestors schema identifiers as metadata', function () { + const jsonSchemaElement = JSONSchemaElement.refract({ + type: 'array', + oneOf: [ + { + $id: '$id1', + type: 'number', + items: { $id: '$id2', type: 'object' }, + }, + ], + items: { + type: 'string', + }, + }); + const foundJsonSchemaElement = find( + (e) => isJSONSchemaElement(e) && isElement(e.$id) && e.$id.equals('$id2'), + jsonSchemaElement, + ); + const ancestorsSchemaIdentifiers = foundJsonSchemaElement!.meta.get( + 'ancestorsSchemaIdentifiers', + ); + + assert.deepEqual(toValue(ancestorsSchemaIdentifiers), ['$id1', '$id2']); + }); + }); + + context('given JSONSchema switches dialect via parent schema', function () { + specify('should expose ancestors schema dialect identifier as metadata', function () { + const jsonSchemaElement = JSONSchemaElement.refract({ + type: 'object', + oneOf: [ + { + type: 'number', + $schema: 'schema1', + items: { type: 'object' }, + }, + ], + items: { + type: 'string', + }, + }) as JSONSchemaElement; + + assert.strictEqual( + toValue(jsonSchemaElement.meta.get('inheritedDialectIdentifier')), + 'http://json-schema.org/draft-06/schema#', + ); + assert.strictEqual( + toValue(jsonSchemaElement.items!.meta.get('inheritedDialectIdentifier')), + 'http://json-schema.org/draft-06/schema#', + ); + assert.strictEqual( + toValue(jsonSchemaElement.oneOf!.get(0).items.meta.get('inheritedDialectIdentifier')), + 'schema1', + ); + }); + }); + context('given fields of type JSONReference', function () { specify('should refract to semantic ApiDOM tree', function () { const jsonSchemaElement = JSONSchemaElement.refract({ diff --git a/packages/apidom-ns-json-schema-draft-7/test/refractor/__snapshots__/index.mjs.snap b/packages/apidom-ns-json-schema-draft-7/test/refractor/__snapshots__/index.mjs.snap index cbbc8dc12e..e1d0ec83c0 100644 --- a/packages/apidom-ns-json-schema-draft-7/test/refractor/__snapshots__/index.mjs.snap +++ b/packages/apidom-ns-json-schema-draft-7/test/refractor/__snapshots__/index.mjs.snap @@ -281,7 +281,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 7 shape shou "content": "http://json-schema.org/draft-07/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -327,7 +333,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 7 shape shou "content": "http://json-schema.org/draft-07/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -433,7 +445,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 7 shape shou "content": "http://json-schema.org/draft-07/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -589,7 +607,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 7 shape shou "content": "http://json-schema.org/draft-07/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -625,7 +649,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 7 shape shou "content": "http://json-schema.org/draft-07/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -689,7 +719,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 7 shape shou "content": "http://json-schema.org/draft-07/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -757,7 +793,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 7 shape shou "content": "http://json-schema.org/draft-07/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -793,7 +835,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 7 shape shou "content": "http://json-schema.org/draft-07/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -946,7 +994,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 7 shape shou "content": "http://json-schema.org/draft-07/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -994,7 +1048,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 7 shape shou "content": "http://json-schema.org/draft-07/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1042,7 +1102,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 7 shape shou "content": "http://json-schema.org/draft-07/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1076,7 +1142,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 7 shape shou "content": "http://json-schema.org/draft-07/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } @@ -1140,7 +1212,13 @@ exports[`refractor given generic ApiDOM object in JSON Schema Draft 7 shape shou "content": "http://json-schema.org/draft-07/schema#" }, "ancestorsSchemaIdentifiers": { - "element": "array" + "element": "array", + "content": [ + { + "element": "string", + "content": "http://x.y.z/rootschema.json#" + } + ] } } } diff --git a/packages/apidom-ns-json-schema-draft-7/test/refractor/elements/JSONSchema/index.ts b/packages/apidom-ns-json-schema-draft-7/test/refractor/elements/JSONSchema/index.ts index 9c1ce10cb4..6b8ad62268 100644 --- a/packages/apidom-ns-json-schema-draft-7/test/refractor/elements/JSONSchema/index.ts +++ b/packages/apidom-ns-json-schema-draft-7/test/refractor/elements/JSONSchema/index.ts @@ -1,7 +1,7 @@ import { assert, expect } from 'chai'; -import { ObjectElement, sexprs, toValue } from '@swagger-api/apidom-core'; +import { ObjectElement, sexprs, toValue, isElement, find } from '@swagger-api/apidom-core'; -import { JSONSchemaElement } from '../../../../src/index.ts'; +import { JSONSchemaElement, isJSONSchemaElement } from '../../../../src/index.ts'; describe('refractor', function () { context('elements', function () { @@ -101,6 +101,64 @@ describe('refractor', function () { }); }); + context('given JSONSchema ancestors are embedded resources', function () { + specify('should expose ancestors schema identifiers as metadata', function () { + const jsonSchemaElement = JSONSchemaElement.refract({ + type: 'array', + oneOf: [ + { + $id: '$id1', + type: 'number', + items: { $id: '$id2', type: 'object' }, + }, + ], + items: { + type: 'string', + }, + }); + const foundJsonSchemaElement = find( + (e) => isJSONSchemaElement(e) && isElement(e.$id) && e.$id.equals('$id2'), + jsonSchemaElement, + ); + const ancestorsSchemaIdentifiers = foundJsonSchemaElement!.meta.get( + 'ancestorsSchemaIdentifiers', + ); + + assert.deepEqual(toValue(ancestorsSchemaIdentifiers), ['$id1', '$id2']); + }); + }); + + context('given JSONSchema switches dialect via parent schema', function () { + specify('should expose ancestors schema dialect identifier as metadata', function () { + const jsonSchemaElement = JSONSchemaElement.refract({ + type: 'object', + oneOf: [ + { + type: 'number', + $schema: 'schema1', + items: { type: 'object' }, + }, + ], + items: { + type: 'string', + }, + }) as JSONSchemaElement; + + assert.strictEqual( + toValue(jsonSchemaElement.meta.get('inheritedDialectIdentifier')), + 'http://json-schema.org/draft-07/schema#', + ); + assert.strictEqual( + toValue(jsonSchemaElement.items!.meta.get('inheritedDialectIdentifier')), + 'http://json-schema.org/draft-07/schema#', + ); + assert.strictEqual( + toValue(jsonSchemaElement.oneOf!.get(0).items.meta.get('inheritedDialectIdentifier')), + 'schema1', + ); + }); + }); + context('given fields of type JSONReference', function () { specify('should refract to semantic ApiDOM tree', function () { const jsonSchemaElement = JSONSchemaElement.refract({