From 5b504e523c532a31aaf1b133a14ff3b76c126435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Gorej?= Date: Thu, 23 Nov 2023 17:02:49 +0100 Subject: [PATCH] feat(ns-workflows-1): add support for JSONSchema Object (#3445) Refs #3392 --- package-lock.json | 1 + .../src/elements/Schema.ts | 3 + packages/apidom-ns-openapi-3-1/src/index.ts | 1 + .../src/refractor/specification.ts | 230 +++++++-------- .../visitors/open-api-3-1/schema/index.ts | 10 +- packages/apidom-ns-workflows-1/README.md | 1 + packages/apidom-ns-workflows-1/package.json | 1 + .../src/elements/JSONSchema.ts | 47 ++++ packages/apidom-ns-workflows-1/src/index.ts | 2 + .../apidom-ns-workflows-1/src/namespace.ts | 2 + .../apidom-ns-workflows-1/src/predicates.ts | 11 + .../src/refractor/registration.ts | 9 + .../src/refractor/specification.ts | 23 ++ .../visitors/workflows-1/json-schema/index.ts | 20 ++ .../src/traversal/visitor.ts | 1 + .../JSONSchema/__snapshots__/index.ts.snap | 266 ++++++++++++++++++ .../JSONSchema/embedded-resources-$id.ts | 105 +++++++ .../JSONSchema/embedded-resources-$schema.ts | 110 ++++++++ .../refractor/elements/JSONSchema/index.ts | 131 +++++++++ 19 files changed, 855 insertions(+), 119 deletions(-) create mode 100644 packages/apidom-ns-workflows-1/src/elements/JSONSchema.ts create mode 100644 packages/apidom-ns-workflows-1/src/refractor/visitors/workflows-1/json-schema/index.ts create mode 100644 packages/apidom-ns-workflows-1/test/refractor/elements/JSONSchema/__snapshots__/index.ts.snap create mode 100644 packages/apidom-ns-workflows-1/test/refractor/elements/JSONSchema/embedded-resources-$id.ts create mode 100644 packages/apidom-ns-workflows-1/test/refractor/elements/JSONSchema/embedded-resources-$schema.ts create mode 100644 packages/apidom-ns-workflows-1/test/refractor/elements/JSONSchema/index.ts diff --git a/package-lock.json b/package-lock.json index f3e5a22d77..b412226506 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34241,6 +34241,7 @@ "dependencies": { "@babel/runtime-corejs3": "^7.20.7", "@swagger-api/apidom-core": "*", + "@swagger-api/apidom-ns-openapi-3-1": "*", "@types/ramda": "~0.29.6", "ramda": "~0.29.1", "ramda-adjunct": "^4.1.1", diff --git a/packages/apidom-ns-openapi-3-1/src/elements/Schema.ts b/packages/apidom-ns-openapi-3-1/src/elements/Schema.ts index a27b457dfa..06d015dab3 100644 --- a/packages/apidom-ns-openapi-3-1/src/elements/Schema.ts +++ b/packages/apidom-ns-openapi-3-1/src/elements/Schema.ts @@ -584,6 +584,9 @@ class Schema extends ObjectElement { return this.get('example'); } + /** + * @deprecated The example property has been deprecated in favor of the JSON Schema examples keyword. Use of example is discouraged, and later versions of this specification may remove it. + */ set example(example: Element | undefined) { this.set('example', example); } diff --git a/packages/apidom-ns-openapi-3-1/src/index.ts b/packages/apidom-ns-openapi-3-1/src/index.ts index 43a928c5cd..fae8545ea0 100644 --- a/packages/apidom-ns-openapi-3-1/src/index.ts +++ b/packages/apidom-ns-openapi-3-1/src/index.ts @@ -24,6 +24,7 @@ export { default as refractorPluginNormalizeOperationIds } from './refractor/plu export { default as refractorPluginNormalizeParameterExamples } from './refractor/plugins/normalize-parameter-examples'; export { default as refractorPluginNormalizeHeaderExamples } from './refractor/plugins/normalize-header-examples'; export { default as createToolbox } from './refractor/toolbox'; +export { default as specificationObj } from './refractor/specification'; export { isCallbackElement, diff --git a/packages/apidom-ns-openapi-3-1/src/refractor/specification.ts b/packages/apidom-ns-openapi-3-1/src/refractor/specification.ts index d595e3c6eb..f86a54174b 100644 --- a/packages/apidom-ns-openapi-3-1/src/refractor/specification.ts +++ b/packages/apidom-ns-openapi-3-1/src/refractor/specification.ts @@ -1,4 +1,4 @@ -import { specificationObj as OpenApi3_1Specification } from '@swagger-api/apidom-ns-openapi-3-0'; +import { specificationObj as OpenApi3_0Specification } from '@swagger-api/apidom-ns-openapi-3-0'; import OpenApi3_1Visitor from './visitors/open-api-3-1'; import InfoVisitor from './visitors/open-api-3-1/info'; @@ -96,18 +96,18 @@ import WebhooksVisitor from './visitors/open-api-3-1/WebhooksVisitor'; */ const specification = { visitors: { - value: OpenApi3_1Specification.visitors.value, + value: OpenApi3_0Specification.visitors.value, document: { objects: { OpenApi: { $visitor: OpenApi3_1Visitor, fixedFields: { - openapi: OpenApi3_1Specification.visitors.document.objects.OpenApi.fixedFields.openapi, + openapi: OpenApi3_0Specification.visitors.document.objects.OpenApi.fixedFields.openapi, info: { $ref: '#/visitors/document/objects/Info', }, jsonSchemaDialect: JsonSchemaDialectVisitor, - servers: OpenApi3_1Specification.visitors.document.objects.OpenApi.fixedFields.servers, + servers: OpenApi3_0Specification.visitors.document.objects.OpenApi.fixedFields.servers, paths: { $ref: '#/visitors/document/objects/Paths', }, @@ -116,8 +116,8 @@ const specification = { $ref: '#/visitors/document/objects/Components', }, security: - OpenApi3_1Specification.visitors.document.objects.OpenApi.fixedFields.security, - tags: OpenApi3_1Specification.visitors.document.objects.OpenApi.fixedFields.tags, + OpenApi3_0Specification.visitors.document.objects.OpenApi.fixedFields.security, + tags: OpenApi3_0Specification.visitors.document.objects.OpenApi.fixedFields.tags, externalDocs: { $ref: '#/visitors/document/objects/ExternalDocumentation', }, @@ -126,55 +126,55 @@ const specification = { Info: { $visitor: InfoVisitor, fixedFields: { - title: OpenApi3_1Specification.visitors.document.objects.Info.fixedFields.title, + title: OpenApi3_0Specification.visitors.document.objects.Info.fixedFields.title, description: - OpenApi3_1Specification.visitors.document.objects.Info.fixedFields.description, + OpenApi3_0Specification.visitors.document.objects.Info.fixedFields.description, summary: InfoSummaryVisitor, termsOfService: - OpenApi3_1Specification.visitors.document.objects.Info.fixedFields.termsOfService, + OpenApi3_0Specification.visitors.document.objects.Info.fixedFields.termsOfService, contact: { $ref: '#/visitors/document/objects/Contact', }, license: { $ref: '#/visitors/document/objects/License', }, - version: OpenApi3_1Specification.visitors.document.objects.Info.fixedFields.version, + version: OpenApi3_0Specification.visitors.document.objects.Info.fixedFields.version, }, }, Contact: { $visitor: ContactVisitor, fixedFields: { - name: OpenApi3_1Specification.visitors.document.objects.Contact.fixedFields.name, - url: OpenApi3_1Specification.visitors.document.objects.Contact.fixedFields.url, - email: OpenApi3_1Specification.visitors.document.objects.Contact.fixedFields.email, + name: OpenApi3_0Specification.visitors.document.objects.Contact.fixedFields.name, + url: OpenApi3_0Specification.visitors.document.objects.Contact.fixedFields.url, + email: OpenApi3_0Specification.visitors.document.objects.Contact.fixedFields.email, }, }, License: { $visitor: LicenseVisitor, fixedFields: { - name: OpenApi3_1Specification.visitors.document.objects.License.fixedFields.name, + name: OpenApi3_0Specification.visitors.document.objects.License.fixedFields.name, identifier: LicenseIdentifierVisitor, - url: OpenApi3_1Specification.visitors.document.objects.License.fixedFields.url, + url: OpenApi3_0Specification.visitors.document.objects.License.fixedFields.url, }, }, Server: { $visitor: ServerVisitor, fixedFields: { - url: OpenApi3_1Specification.visitors.document.objects.Server.fixedFields.url, + url: OpenApi3_0Specification.visitors.document.objects.Server.fixedFields.url, description: - OpenApi3_1Specification.visitors.document.objects.Server.fixedFields.description, + OpenApi3_0Specification.visitors.document.objects.Server.fixedFields.description, variables: - OpenApi3_1Specification.visitors.document.objects.Server.fixedFields.variables, + OpenApi3_0Specification.visitors.document.objects.Server.fixedFields.variables, }, }, ServerVariable: { $visitor: ServerVariableVisitor, fixedFields: { - enum: OpenApi3_1Specification.visitors.document.objects.ServerVariable.fixedFields.enum, + enum: OpenApi3_0Specification.visitors.document.objects.ServerVariable.fixedFields.enum, default: - OpenApi3_1Specification.visitors.document.objects.ServerVariable.fixedFields.default, + OpenApi3_0Specification.visitors.document.objects.ServerVariable.fixedFields.default, description: - OpenApi3_1Specification.visitors.document.objects.ServerVariable.fixedFields + OpenApi3_0Specification.visitors.document.objects.ServerVariable.fixedFields .description, }, }, @@ -183,22 +183,22 @@ const specification = { fixedFields: { schemas: ComponentsSchemasVisitor, responses: - OpenApi3_1Specification.visitors.document.objects.Components.fixedFields.responses, + OpenApi3_0Specification.visitors.document.objects.Components.fixedFields.responses, parameters: - OpenApi3_1Specification.visitors.document.objects.Components.fixedFields.parameters, + OpenApi3_0Specification.visitors.document.objects.Components.fixedFields.parameters, examples: - OpenApi3_1Specification.visitors.document.objects.Components.fixedFields.examples, + OpenApi3_0Specification.visitors.document.objects.Components.fixedFields.examples, requestBodies: - OpenApi3_1Specification.visitors.document.objects.Components.fixedFields + OpenApi3_0Specification.visitors.document.objects.Components.fixedFields .requestBodies, headers: - OpenApi3_1Specification.visitors.document.objects.Components.fixedFields.headers, + OpenApi3_0Specification.visitors.document.objects.Components.fixedFields.headers, securitySchemes: - OpenApi3_1Specification.visitors.document.objects.Components.fixedFields + OpenApi3_0Specification.visitors.document.objects.Components.fixedFields .securitySchemes, - links: OpenApi3_1Specification.visitors.document.objects.Components.fixedFields.links, + links: OpenApi3_0Specification.visitors.document.objects.Components.fixedFields.links, callbacks: - OpenApi3_1Specification.visitors.document.objects.Components.fixedFields.callbacks, + OpenApi3_0Specification.visitors.document.objects.Components.fixedFields.callbacks, pathItems: ComponentsPathItemsVisitor, }, }, @@ -208,10 +208,10 @@ const specification = { PathItem: { $visitor: PathItemVisitor, fixedFields: { - $ref: OpenApi3_1Specification.visitors.document.objects.PathItem.fixedFields.$ref, - summary: OpenApi3_1Specification.visitors.document.objects.PathItem.fixedFields.summary, + $ref: OpenApi3_0Specification.visitors.document.objects.PathItem.fixedFields.$ref, + summary: OpenApi3_0Specification.visitors.document.objects.PathItem.fixedFields.summary, description: - OpenApi3_1Specification.visitors.document.objects.PathItem.fixedFields.description, + OpenApi3_0Specification.visitors.document.objects.PathItem.fixedFields.description, get: { $ref: '#/visitors/document/objects/Operation', }, @@ -236,90 +236,90 @@ const specification = { trace: { $ref: '#/visitors/document/objects/Operation', }, - servers: OpenApi3_1Specification.visitors.document.objects.PathItem.fixedFields.servers, + servers: OpenApi3_0Specification.visitors.document.objects.PathItem.fixedFields.servers, parameters: - OpenApi3_1Specification.visitors.document.objects.PathItem.fixedFields.parameters, + OpenApi3_0Specification.visitors.document.objects.PathItem.fixedFields.parameters, }, }, Operation: { $visitor: OperationVisitor, fixedFields: { - tags: OpenApi3_1Specification.visitors.document.objects.Operation.fixedFields.tags, + tags: OpenApi3_0Specification.visitors.document.objects.Operation.fixedFields.tags, summary: - OpenApi3_1Specification.visitors.document.objects.Operation.fixedFields.summary, + OpenApi3_0Specification.visitors.document.objects.Operation.fixedFields.summary, description: - OpenApi3_1Specification.visitors.document.objects.Operation.fixedFields.description, + OpenApi3_0Specification.visitors.document.objects.Operation.fixedFields.description, externalDocs: { $ref: '#/visitors/document/objects/ExternalDocumentation', }, operationId: - OpenApi3_1Specification.visitors.document.objects.Operation.fixedFields.operationId, + OpenApi3_0Specification.visitors.document.objects.Operation.fixedFields.operationId, parameters: - OpenApi3_1Specification.visitors.document.objects.Operation.fixedFields.parameters, + OpenApi3_0Specification.visitors.document.objects.Operation.fixedFields.parameters, requestBody: - OpenApi3_1Specification.visitors.document.objects.Operation.fixedFields.requestBody, + OpenApi3_0Specification.visitors.document.objects.Operation.fixedFields.requestBody, responses: { $ref: '#/visitors/document/objects/Responses', }, callbacks: - OpenApi3_1Specification.visitors.document.objects.Operation.fixedFields.callbacks, + OpenApi3_0Specification.visitors.document.objects.Operation.fixedFields.callbacks, deprecated: - OpenApi3_1Specification.visitors.document.objects.Operation.fixedFields.deprecated, + OpenApi3_0Specification.visitors.document.objects.Operation.fixedFields.deprecated, security: - OpenApi3_1Specification.visitors.document.objects.Operation.fixedFields.security, + OpenApi3_0Specification.visitors.document.objects.Operation.fixedFields.security, servers: - OpenApi3_1Specification.visitors.document.objects.Operation.fixedFields.servers, + OpenApi3_0Specification.visitors.document.objects.Operation.fixedFields.servers, }, }, ExternalDocumentation: { $visitor: ExternalDocumentationVisitor, fixedFields: { description: - OpenApi3_1Specification.visitors.document.objects.ExternalDocumentation.fixedFields + OpenApi3_0Specification.visitors.document.objects.ExternalDocumentation.fixedFields .description, - url: OpenApi3_1Specification.visitors.document.objects.ExternalDocumentation.fixedFields + url: OpenApi3_0Specification.visitors.document.objects.ExternalDocumentation.fixedFields .url, }, }, Parameter: { $visitor: ParameterVisitor, fixedFields: { - name: OpenApi3_1Specification.visitors.document.objects.Parameter.fixedFields.name, - in: OpenApi3_1Specification.visitors.document.objects.Parameter.fixedFields.in, + name: OpenApi3_0Specification.visitors.document.objects.Parameter.fixedFields.name, + in: OpenApi3_0Specification.visitors.document.objects.Parameter.fixedFields.in, description: - OpenApi3_1Specification.visitors.document.objects.Parameter.fixedFields.description, + OpenApi3_0Specification.visitors.document.objects.Parameter.fixedFields.description, required: - OpenApi3_1Specification.visitors.document.objects.Parameter.fixedFields.required, + OpenApi3_0Specification.visitors.document.objects.Parameter.fixedFields.required, deprecated: - OpenApi3_1Specification.visitors.document.objects.Parameter.fixedFields.deprecated, + OpenApi3_0Specification.visitors.document.objects.Parameter.fixedFields.deprecated, allowEmptyValue: - OpenApi3_1Specification.visitors.document.objects.Parameter.fixedFields + OpenApi3_0Specification.visitors.document.objects.Parameter.fixedFields .allowEmptyValue, - style: OpenApi3_1Specification.visitors.document.objects.Parameter.fixedFields.style, + style: OpenApi3_0Specification.visitors.document.objects.Parameter.fixedFields.style, explode: - OpenApi3_1Specification.visitors.document.objects.Parameter.fixedFields.explode, + OpenApi3_0Specification.visitors.document.objects.Parameter.fixedFields.explode, allowReserved: - OpenApi3_1Specification.visitors.document.objects.Parameter.fixedFields.allowReserved, + OpenApi3_0Specification.visitors.document.objects.Parameter.fixedFields.allowReserved, schema: { $ref: '#/visitors/document/objects/Schema', }, example: - OpenApi3_1Specification.visitors.document.objects.Parameter.fixedFields.example, + OpenApi3_0Specification.visitors.document.objects.Parameter.fixedFields.example, examples: - OpenApi3_1Specification.visitors.document.objects.Parameter.fixedFields.examples, + OpenApi3_0Specification.visitors.document.objects.Parameter.fixedFields.examples, content: - OpenApi3_1Specification.visitors.document.objects.Parameter.fixedFields.content, + OpenApi3_0Specification.visitors.document.objects.Parameter.fixedFields.content, }, }, RequestBody: { $visitor: RequestBodyVisitor, fixedFields: { description: - OpenApi3_1Specification.visitors.document.objects.RequestBody.fixedFields.description, + OpenApi3_0Specification.visitors.document.objects.RequestBody.fixedFields.description, content: - OpenApi3_1Specification.visitors.document.objects.RequestBody.fixedFields.content, + OpenApi3_0Specification.visitors.document.objects.RequestBody.fixedFields.content, required: - OpenApi3_1Specification.visitors.document.objects.RequestBody.fixedFields.required, + OpenApi3_0Specification.visitors.document.objects.RequestBody.fixedFields.required, }, }, MediaType: { @@ -329,40 +329,40 @@ const specification = { $ref: '#/visitors/document/objects/Schema', }, example: - OpenApi3_1Specification.visitors.document.objects.MediaType.fixedFields.example, + OpenApi3_0Specification.visitors.document.objects.MediaType.fixedFields.example, examples: - OpenApi3_1Specification.visitors.document.objects.MediaType.fixedFields.examples, + OpenApi3_0Specification.visitors.document.objects.MediaType.fixedFields.examples, encoding: - OpenApi3_1Specification.visitors.document.objects.MediaType.fixedFields.encoding, + OpenApi3_0Specification.visitors.document.objects.MediaType.fixedFields.encoding, }, }, Encoding: { $visitor: EncodingVisitor, fixedFields: { contentType: - OpenApi3_1Specification.visitors.document.objects.Encoding.fixedFields.contentType, - headers: OpenApi3_1Specification.visitors.document.objects.Encoding.fixedFields.headers, - style: OpenApi3_1Specification.visitors.document.objects.Encoding.fixedFields.style, - explode: OpenApi3_1Specification.visitors.document.objects.Encoding.fixedFields.explode, + OpenApi3_0Specification.visitors.document.objects.Encoding.fixedFields.contentType, + headers: OpenApi3_0Specification.visitors.document.objects.Encoding.fixedFields.headers, + style: OpenApi3_0Specification.visitors.document.objects.Encoding.fixedFields.style, + explode: OpenApi3_0Specification.visitors.document.objects.Encoding.fixedFields.explode, allowReserved: - OpenApi3_1Specification.visitors.document.objects.Encoding.fixedFields.allowReserved, + OpenApi3_0Specification.visitors.document.objects.Encoding.fixedFields.allowReserved, }, }, Responses: { $visitor: ResponsesVisitor, fixedFields: { default: - OpenApi3_1Specification.visitors.document.objects.Responses.fixedFields.default, + OpenApi3_0Specification.visitors.document.objects.Responses.fixedFields.default, }, }, Response: { $visitor: ResponseVisitor, fixedFields: { description: - OpenApi3_1Specification.visitors.document.objects.Response.fixedFields.description, - headers: OpenApi3_1Specification.visitors.document.objects.Response.fixedFields.headers, - content: OpenApi3_1Specification.visitors.document.objects.Response.fixedFields.content, - links: OpenApi3_1Specification.visitors.document.objects.Response.fixedFields.links, + OpenApi3_0Specification.visitors.document.objects.Response.fixedFields.description, + headers: OpenApi3_0Specification.visitors.document.objects.Response.fixedFields.headers, + content: OpenApi3_0Specification.visitors.document.objects.Response.fixedFields.content, + links: OpenApi3_0Specification.visitors.document.objects.Response.fixedFields.links, }, }, Callback: { @@ -371,27 +371,27 @@ const specification = { Example: { $visitor: ExampleVisitor, fixedFields: { - summary: OpenApi3_1Specification.visitors.document.objects.Example.fixedFields.summary, + summary: OpenApi3_0Specification.visitors.document.objects.Example.fixedFields.summary, description: - OpenApi3_1Specification.visitors.document.objects.Example.fixedFields.description, - value: OpenApi3_1Specification.visitors.document.objects.Example.fixedFields.value, + OpenApi3_0Specification.visitors.document.objects.Example.fixedFields.description, + value: OpenApi3_0Specification.visitors.document.objects.Example.fixedFields.value, externalValue: - OpenApi3_1Specification.visitors.document.objects.Example.fixedFields.externalValue, + OpenApi3_0Specification.visitors.document.objects.Example.fixedFields.externalValue, }, }, Link: { $visitor: LinkVisitor, fixedFields: { operationRef: - OpenApi3_1Specification.visitors.document.objects.Link.fixedFields.operationRef, + OpenApi3_0Specification.visitors.document.objects.Link.fixedFields.operationRef, operationId: - OpenApi3_1Specification.visitors.document.objects.Link.fixedFields.operationId, + OpenApi3_0Specification.visitors.document.objects.Link.fixedFields.operationId, parameters: - OpenApi3_1Specification.visitors.document.objects.Link.fixedFields.parameters, + OpenApi3_0Specification.visitors.document.objects.Link.fixedFields.parameters, requestBody: - OpenApi3_1Specification.visitors.document.objects.Link.fixedFields.requestBody, + OpenApi3_0Specification.visitors.document.objects.Link.fixedFields.requestBody, description: - OpenApi3_1Specification.visitors.document.objects.Link.fixedFields.description, + OpenApi3_0Specification.visitors.document.objects.Link.fixedFields.description, server: { $ref: '#/visitors/document/objects/Server', }, @@ -401,30 +401,30 @@ const specification = { $visitor: HeaderVisitor, fixedFields: { description: - OpenApi3_1Specification.visitors.document.objects.Header.fixedFields.description, - required: OpenApi3_1Specification.visitors.document.objects.Header.fixedFields.required, + OpenApi3_0Specification.visitors.document.objects.Header.fixedFields.description, + required: OpenApi3_0Specification.visitors.document.objects.Header.fixedFields.required, deprecated: - OpenApi3_1Specification.visitors.document.objects.Header.fixedFields.deprecated, + OpenApi3_0Specification.visitors.document.objects.Header.fixedFields.deprecated, allowEmptyValue: - OpenApi3_1Specification.visitors.document.objects.Header.fixedFields.allowEmptyValue, - style: OpenApi3_1Specification.visitors.document.objects.Header.fixedFields.style, - explode: OpenApi3_1Specification.visitors.document.objects.Header.fixedFields.explode, + OpenApi3_0Specification.visitors.document.objects.Header.fixedFields.allowEmptyValue, + style: OpenApi3_0Specification.visitors.document.objects.Header.fixedFields.style, + explode: OpenApi3_0Specification.visitors.document.objects.Header.fixedFields.explode, allowReserved: - OpenApi3_1Specification.visitors.document.objects.Header.fixedFields.allowReserved, + OpenApi3_0Specification.visitors.document.objects.Header.fixedFields.allowReserved, schema: { $ref: '#/visitors/document/objects/Schema', }, - example: OpenApi3_1Specification.visitors.document.objects.Header.fixedFields.example, - examples: OpenApi3_1Specification.visitors.document.objects.Header.fixedFields.examples, - content: OpenApi3_1Specification.visitors.document.objects.Header.fixedFields.content, + example: OpenApi3_0Specification.visitors.document.objects.Header.fixedFields.example, + examples: OpenApi3_0Specification.visitors.document.objects.Header.fixedFields.examples, + content: OpenApi3_0Specification.visitors.document.objects.Header.fixedFields.content, }, }, Tag: { $visitor: TagVisitor, fixedFields: { - name: OpenApi3_1Specification.visitors.document.objects.Tag.fixedFields.name, + name: OpenApi3_0Specification.visitors.document.objects.Tag.fixedFields.name, description: - OpenApi3_1Specification.visitors.document.objects.Tag.fixedFields.description, + OpenApi3_0Specification.visitors.document.objects.Tag.fixedFields.description, externalDocs: { $ref: '#/visitors/document/objects/ExternalDocumentation', }, @@ -433,7 +433,7 @@ const specification = { Reference: { $visitor: ReferenceVisitor, fixedFields: { - $ref: OpenApi3_1Specification.visitors.document.objects.Reference.fixedFields.$ref, + $ref: OpenApi3_0Specification.visitors.document.objects.Reference.fixedFields.$ref, summary: ReferenceSummaryVisitor, description: ReferenceDescriptionVisitor, }, @@ -549,41 +549,41 @@ const specification = { $visitor: DiscriminatorVisitor, fixedFields: { propertyName: - OpenApi3_1Specification.visitors.document.objects.Discriminator.fixedFields + OpenApi3_0Specification.visitors.document.objects.Discriminator.fixedFields .propertyName, mapping: - OpenApi3_1Specification.visitors.document.objects.Discriminator.fixedFields.mapping, + OpenApi3_0Specification.visitors.document.objects.Discriminator.fixedFields.mapping, }, }, XML: { $visitor: XmlVisitor, fixedFields: { - name: OpenApi3_1Specification.visitors.document.objects.XML.fixedFields.name, - namespace: OpenApi3_1Specification.visitors.document.objects.XML.fixedFields.namespace, - prefix: OpenApi3_1Specification.visitors.document.objects.XML.fixedFields.prefix, - attribute: OpenApi3_1Specification.visitors.document.objects.XML.fixedFields.attribute, - wrapped: OpenApi3_1Specification.visitors.document.objects.XML.fixedFields.wrapped, + name: OpenApi3_0Specification.visitors.document.objects.XML.fixedFields.name, + namespace: OpenApi3_0Specification.visitors.document.objects.XML.fixedFields.namespace, + prefix: OpenApi3_0Specification.visitors.document.objects.XML.fixedFields.prefix, + attribute: OpenApi3_0Specification.visitors.document.objects.XML.fixedFields.attribute, + wrapped: OpenApi3_0Specification.visitors.document.objects.XML.fixedFields.wrapped, }, }, SecurityScheme: { $visitor: SecuritySchemeVisitor, fixedFields: { - type: OpenApi3_1Specification.visitors.document.objects.SecurityScheme.fixedFields.type, + type: OpenApi3_0Specification.visitors.document.objects.SecurityScheme.fixedFields.type, description: - OpenApi3_1Specification.visitors.document.objects.SecurityScheme.fixedFields + OpenApi3_0Specification.visitors.document.objects.SecurityScheme.fixedFields .description, - name: OpenApi3_1Specification.visitors.document.objects.SecurityScheme.fixedFields.name, - in: OpenApi3_1Specification.visitors.document.objects.SecurityScheme.fixedFields.in, + name: OpenApi3_0Specification.visitors.document.objects.SecurityScheme.fixedFields.name, + in: OpenApi3_0Specification.visitors.document.objects.SecurityScheme.fixedFields.in, scheme: - OpenApi3_1Specification.visitors.document.objects.SecurityScheme.fixedFields.scheme, + OpenApi3_0Specification.visitors.document.objects.SecurityScheme.fixedFields.scheme, bearerFormat: - OpenApi3_1Specification.visitors.document.objects.SecurityScheme.fixedFields + OpenApi3_0Specification.visitors.document.objects.SecurityScheme.fixedFields .bearerFormat, flows: { $ref: '#/visitors/document/objects/OAuthFlows', }, openIdConnectUrl: - OpenApi3_1Specification.visitors.document.objects.SecurityScheme.fixedFields + OpenApi3_0Specification.visitors.document.objects.SecurityScheme.fixedFields .openIdConnectUrl, }, }, @@ -608,13 +608,13 @@ const specification = { $visitor: OAuthFlowVisitor, fixedFields: { authorizationUrl: - OpenApi3_1Specification.visitors.document.objects.OAuthFlow.fixedFields + OpenApi3_0Specification.visitors.document.objects.OAuthFlow.fixedFields .authorizationUrl, tokenUrl: - OpenApi3_1Specification.visitors.document.objects.OAuthFlow.fixedFields.tokenUrl, + OpenApi3_0Specification.visitors.document.objects.OAuthFlow.fixedFields.tokenUrl, refreshUrl: - OpenApi3_1Specification.visitors.document.objects.OAuthFlow.fixedFields.refreshUrl, - scopes: OpenApi3_1Specification.visitors.document.objects.OAuthFlow.fixedFields.scopes, + OpenApi3_0Specification.visitors.document.objects.OAuthFlow.fixedFields.refreshUrl, + scopes: OpenApi3_0Specification.visitors.document.objects.OAuthFlow.fixedFields.scopes, }, }, SecurityRequirement: { @@ -622,7 +622,7 @@ const specification = { }, }, extension: { - $visitor: OpenApi3_1Specification.visitors.document.extension.$visitor, + $visitor: OpenApi3_0Specification.visitors.document.extension.$visitor, }, }, }, diff --git a/packages/apidom-ns-openapi-3-1/src/refractor/visitors/open-api-3-1/schema/index.ts b/packages/apidom-ns-openapi-3-1/src/refractor/visitors/open-api-3-1/schema/index.ts index b2d7dc8f2e..fdda983303 100644 --- a/packages/apidom-ns-openapi-3-1/src/refractor/visitors/open-api-3-1/schema/index.ts +++ b/packages/apidom-ns-openapi-3-1/src/refractor/visitors/open-api-3-1/schema/index.ts @@ -14,16 +14,19 @@ import { FallbackVisitor, FixedFieldsVisitor } from '@swagger-api/apidom-ns-open import { isSchemaElement, isJsonSchemaDialectElement } from '../../../../predicates'; import SchemaElement from '../../../../elements/Schema'; -import JsonSchemaDialect from '../../../../elements/JsonSchemaDialect'; +import JsonSchemaDialectElement from '../../../../elements/JsonSchemaDialect'; import ParentSchemaAwareVisitor from './ParentSchemaAwareVisitor'; const SchemaVisitor = stampit(FixedFieldsVisitor, ParentSchemaAwareVisitor, FallbackVisitor, { props: { specPath: always(['document', 'objects', 'Schema']), canSupportSpecificationExtensions: true, + jsonSchemaDefaultDialect: JsonSchemaDialectElement.default, }, // @ts-ignore init() { + this.element = new SchemaElement(); + /** * Private Api. */ @@ -47,7 +50,7 @@ const SchemaVisitor = stampit(FixedFieldsVisitor, ParentSchemaAwareVisitor, Fall ) { jsonSchemaDialect = toValue(this.openApiGenericElement.get('jsonSchemaDialect')); } else { - jsonSchemaDialect = toValue(JsonSchemaDialect.default); + jsonSchemaDialect = toValue(this.jsonSchemaDefaultDialect); } return jsonSchemaDialect; @@ -78,7 +81,7 @@ const SchemaVisitor = stampit(FixedFieldsVisitor, ParentSchemaAwareVisitor, Fall // get current $id keyword const $id = toValue(objectElement.get('$id')); - // remember $id keyword if it's a non empty strings + // remember $id keyword if it's a non-empty strings if (isNonEmptyString($id)) { inherited$id.push($id); } @@ -91,7 +94,6 @@ const SchemaVisitor = stampit(FixedFieldsVisitor, ParentSchemaAwareVisitor, Fall */ // eslint-disable-next-line @typescript-eslint/naming-convention this.ObjectElement = function _ObjectElement(objectElement: ObjectElement) { - this.element = new SchemaElement(); handle$schema(objectElement); handle$id(objectElement); diff --git a/packages/apidom-ns-workflows-1/README.md b/packages/apidom-ns-workflows-1/README.md index 8d985183cf..1bf3b8f440 100644 --- a/packages/apidom-ns-workflows-1/README.md +++ b/packages/apidom-ns-workflows-1/README.md @@ -196,4 +196,5 @@ Only fully implemented specification objects should be checked here. - [ ] [Component Object](https://github.com/OAI/sig-workflows/blob/main/versions/1.0.0.md#component-object) - [x] [Criterion Object](https://github.com/OAI/sig-workflows/blob/main/versions/1.0.0.md#criterion-object) - [ ] [Reference Object](https://github.com/OAI/sig-workflows/blob/main/versions/1.0.0.md#reference-object) +- [x] [JSON Schema](https://json-schema.org/specification-links#2020-12) - [x] [Specification extensions](https://github.com/OAI/sig-workflows/blob/main/versions/1.0.0.md#specification-extensions) diff --git a/packages/apidom-ns-workflows-1/package.json b/packages/apidom-ns-workflows-1/package.json index 68c70d9862..0d05fd340b 100644 --- a/packages/apidom-ns-workflows-1/package.json +++ b/packages/apidom-ns-workflows-1/package.json @@ -44,6 +44,7 @@ "dependencies": { "@babel/runtime-corejs3": "^7.20.7", "@swagger-api/apidom-core": "*", + "@swagger-api/apidom-ns-openapi-3-1": "*", "@types/ramda": "~0.29.6", "ramda": "~0.29.1", "ramda-adjunct": "^4.1.1", diff --git a/packages/apidom-ns-workflows-1/src/elements/JSONSchema.ts b/packages/apidom-ns-workflows-1/src/elements/JSONSchema.ts new file mode 100644 index 0000000000..161dbc86c3 --- /dev/null +++ b/packages/apidom-ns-workflows-1/src/elements/JSONSchema.ts @@ -0,0 +1,47 @@ +import type { Attributes, Meta } from '@swagger-api/apidom-core'; +import { SchemaElement } from '@swagger-api/apidom-ns-openapi-3-1'; + +class JSONSchema extends SchemaElement { + constructor(content?: Record, meta?: Meta, attributes?: Attributes) { + super(content, meta, attributes); + this.element = 'jSONSchemaDraft202012'; + } + + /** + * We're redefining the getters/setters here so that the following keywords + * are not part of the OAS base vocabulary, but rather an arbitrary custom dialect. + */ + get discriminator(): any { + return this.get('discriminator'); + } + + set discriminator(discriminator: any) { + this.set('discriminator', discriminator); + } + + get xml(): any { + return this.get('xml'); + } + + set xml(xml: any) { + this.set('xml', xml); + } + + get externalDocs(): any { + return this.get('externalDocs'); + } + + set externalDocs(externalDocs: any) { + this.set('externalDocs', externalDocs); + } + + get example(): any { + return this.get('example'); + } + + set example(example: any) { + this.set('example', example); + } +} + +export default JSONSchema; diff --git a/packages/apidom-ns-workflows-1/src/index.ts b/packages/apidom-ns-workflows-1/src/index.ts index bb4b5a7f08..3ea88a9850 100644 --- a/packages/apidom-ns-workflows-1/src/index.ts +++ b/packages/apidom-ns-workflows-1/src/index.ts @@ -33,6 +33,7 @@ export { isFailureActionElement, isFailureActionCriteriaElement, isCriterionElement, + isJSONSchemaElement, } from './predicates'; export { isWorkflowsSpecificationExtension } from './refractor/predicates'; @@ -56,6 +57,7 @@ export { SuccessActionElement, FailureActionElement, CriterionElement, + JSONSchemaElement, } from './refractor/registration'; // NCE types export { default as SourceDescriptionsElement } from './elements/nces/SourceDescriptions'; diff --git a/packages/apidom-ns-workflows-1/src/namespace.ts b/packages/apidom-ns-workflows-1/src/namespace.ts index 629a6e316b..b7b18e8711 100644 --- a/packages/apidom-ns-workflows-1/src/namespace.ts +++ b/packages/apidom-ns-workflows-1/src/namespace.ts @@ -8,6 +8,7 @@ import ParameterElement from './elements/Parameter'; import SuccessActionElement from './elements/SuccessAction'; import FailureActionElement from './elements/FailureAction'; import CriterionElement from './elements/Criterion'; +import JSONSchemaElement from './elements/JSONSchema'; const workflows1 = { namespace: (options: NamespacePluginOptions) => { @@ -21,6 +22,7 @@ const workflows1 = { base.register('successAction', SuccessActionElement); base.register('failureAction', FailureActionElement); base.register('criterion', CriterionElement); + base.register('jSONSchemaDraft202012', JSONSchemaElement); return base; }, diff --git a/packages/apidom-ns-workflows-1/src/predicates.ts b/packages/apidom-ns-workflows-1/src/predicates.ts index 18e22eb212..7cccd56d47 100644 --- a/packages/apidom-ns-workflows-1/src/predicates.ts +++ b/packages/apidom-ns-workflows-1/src/predicates.ts @@ -8,6 +8,7 @@ import ParameterElement from './elements/Parameter'; import SuccessActionElement from './elements/SuccessAction'; import FailureActionElement from './elements/FailureAction'; import CriterionElement from './elements/Criterion'; +import JSONSchemaElement from './elements/JSONSchema'; // NCE types import SourceDescriptionsElement from './elements/nces/SourceDescriptions'; import SuccessActionCriteriaElement from './elements/nces/SuccessActionCriteria'; @@ -130,3 +131,13 @@ export const isFailureActionCriteriaElement = createPredicate( hasClass('criteria', element)); }, ); + +export const isJSONSchemaElement = createPredicate( + ({ hasBasicElementProps, isElementType, primitiveEq }) => { + return (element: unknown): element is JSONSchemaElement => + element instanceof JSONSchemaElement || + (hasBasicElementProps(element) && + isElementType('jSONSchemaDraft202012', element) && + primitiveEq('object', element)); + }, +); diff --git a/packages/apidom-ns-workflows-1/src/refractor/registration.ts b/packages/apidom-ns-workflows-1/src/refractor/registration.ts index d29f971f5c..5c35249ca0 100644 --- a/packages/apidom-ns-workflows-1/src/refractor/registration.ts +++ b/packages/apidom-ns-workflows-1/src/refractor/registration.ts @@ -6,6 +6,7 @@ import ParameterElement from '../elements/Parameter'; import SuccessActionElement from '../elements/SuccessAction'; import FailureActionElement from '../elements/FailureAction'; import CriterionElement from '../elements/Criterion'; +import JSONSchemaElement from '../elements/JSONSchema'; import { createRefractor } from './index'; InfoElement.refract = createRefractor(['visitors', 'document', 'objects', 'Info', '$visitor']); @@ -59,6 +60,13 @@ CriterionElement.refract = createRefractor([ 'Criterion', '$visitor', ]); +JSONSchemaElement.refract = createRefractor([ + 'visitors', + 'document', + 'objects', + 'JSONSchema', + '$visitor', +]); export { WorkflowsSpecification1Element, @@ -69,4 +77,5 @@ export { SuccessActionElement, FailureActionElement, CriterionElement, + JSONSchemaElement, }; diff --git a/packages/apidom-ns-workflows-1/src/refractor/specification.ts b/packages/apidom-ns-workflows-1/src/refractor/specification.ts index 7648581960..e9abdac32c 100644 --- a/packages/apidom-ns-workflows-1/src/refractor/specification.ts +++ b/packages/apidom-ns-workflows-1/src/refractor/specification.ts @@ -1,3 +1,6 @@ +import { omit } from 'ramda'; +import { specificationObj as OpenApi3_1Specification } from '@swagger-api/apidom-ns-openapi-3-1'; + import WorkflowsSpecificationVisitor from './visitors/workflows-1/index'; import WorkflowsSpecVisitor from './visitors/workflows-1/WorkflowsSpecVisitor'; import InfoVisitor from './visitors/workflows-1/info'; @@ -11,6 +14,7 @@ import SuccessActionCriteriaVisitor from './visitors/workflows-1/SuccessActionCr import FailureActionVisitor from './visitors/workflows-1/failure-action'; import FailureActionCriteriaVisitor from './visitors/workflows-1/FailureActionCriteriaVisitor'; import CriterionVisitor from './visitors/workflows-1/criterion'; +import JSONSchemaVisitor from './visitors/workflows-1/json-schema'; import SpecificationExtensionVisitor from './visitors/SpecificationExtensionVisitor'; import FallbackVisitor from './visitors/FallbackVisitor'; @@ -23,6 +27,12 @@ import FallbackVisitor from './visitors/FallbackVisitor'; * Note: Specification object allows to use absolute internal JSON pointers. */ +const { fixedFields: schemaFixedFields } = OpenApi3_1Specification.visitors.document.objects.Schema; +const jsonSchemaFixedFields = omit( + ['discriminator', 'xml', 'externalDocs', 'example'], + schemaFixedFields, +); // getting rid of OAS base dialect keywords + const specification = { visitors: { value: FallbackVisitor, @@ -93,6 +103,19 @@ const specification = { type: { $ref: '#/visitors/value' }, }, }, + Schema: { + /** + * Internally the fixed field visitors are using references to `/document/objects/Schema`. + * Schema spec make sure it's pointing to our JSONSchema visitor and basically acts like + * an alias for it. + */ + $visitor: JSONSchemaVisitor, + fixedFields: jsonSchemaFixedFields, + }, + JSONSchema: { + $visitor: JSONSchemaVisitor, + fixedFields: jsonSchemaFixedFields, + }, }, extension: { $visitor: SpecificationExtensionVisitor, diff --git a/packages/apidom-ns-workflows-1/src/refractor/visitors/workflows-1/json-schema/index.ts b/packages/apidom-ns-workflows-1/src/refractor/visitors/workflows-1/json-schema/index.ts new file mode 100644 index 0000000000..e44d6fffea --- /dev/null +++ b/packages/apidom-ns-workflows-1/src/refractor/visitors/workflows-1/json-schema/index.ts @@ -0,0 +1,20 @@ +import { always } from 'ramda'; +import stampit from 'stampit'; +import { specificationObj as OpenApi3_1Specification } from '@swagger-api/apidom-ns-openapi-3-1'; + +import JSONSchemaElement from '../../../../elements/JSONSchema'; + +const { $visitor: SchemaVisitor } = OpenApi3_1Specification.visitors.document.objects.Schema; + +const JSONSchemaVisitor = stampit(SchemaVisitor, { + props: { + specPath: always(['document', 'objects', 'JSONSchema']), + canSupportSpecificationExtensions: false, + jsonSchemaDefaultDialect: 'https://json-schema.org/draft/2020-12/schema', + }, + init() { + this.element = new JSONSchemaElement(); + }, +}); + +export default JSONSchemaVisitor; diff --git a/packages/apidom-ns-workflows-1/src/traversal/visitor.ts b/packages/apidom-ns-workflows-1/src/traversal/visitor.ts index 47be2bde4f..abd9fcc83a 100644 --- a/packages/apidom-ns-workflows-1/src/traversal/visitor.ts +++ b/packages/apidom-ns-workflows-1/src/traversal/visitor.ts @@ -20,5 +20,6 @@ export const keyMap = { SuccessActionElement: ['content'], FailureActionElement: ['content'], CriterionElement: ['content'], + JSONSSchemaDraft202012Element: ['content'], ...keyMapBase, }; diff --git a/packages/apidom-ns-workflows-1/test/refractor/elements/JSONSchema/__snapshots__/index.ts.snap b/packages/apidom-ns-workflows-1/test/refractor/elements/JSONSchema/__snapshots__/index.ts.snap new file mode 100644 index 0000000000..73ef440d5c --- /dev/null +++ b/packages/apidom-ns-workflows-1/test/refractor/elements/JSONSchema/__snapshots__/index.ts.snap @@ -0,0 +1,266 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`refractor elements JSONSchemaElement given Boolean JSON Schemas should refract to semantic ApiDOM tree 1`] = ` +(JSONSchemaDraft202012Element + (MemberElement + (StringElement) + (ObjectElement + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element + (MemberElement + (StringElement) + (BooleanElement)))))) + (MemberElement + (StringElement) + (ArrayElement + (BooleanElement) + (BooleanElement))) + (MemberElement + (StringElement) + (ObjectElement + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element + (MemberElement + (StringElement) + (BooleanElement))))))) +`; + +exports[`refractor elements JSONSchemaElement given embedded JSONSchemaElements should refract to semantic ApiDOM tree 1`] = ` +(JSONSchemaDraft202012Element + (MemberElement + (StringElement) + (ObjectElement + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element)))))) + (MemberElement + (StringElement) + (ArrayElement + (JSONSchemaDraft202012Element + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element))))) + (MemberElement + (StringElement) + (ObjectElement + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element)))))) + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element))))) +`; + +exports[`refractor elements JSONSchemaElement should refract to semantic ApiDOM tree 1`] = ` +(JSONSchemaDraft202012Element + (MemberElement + (StringElement) + (StringElement)) + (MemberElement + (StringElement) + (StringElement)) + (MemberElement + (StringElement) + (ObjectElement + (MemberElement + (StringElement) + (BooleanElement)))) + (MemberElement + (StringElement) + (StringElement)) + (MemberElement + (StringElement) + (StringElement)) + (MemberElement + (StringElement) + (StringElement)) + (MemberElement + (StringElement) + (StringElement)) + (MemberElement + (StringElement) + (ObjectElement + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element)))) + (MemberElement + (StringElement) + (StringElement)) + (MemberElement + (StringElement) + (ArrayElement + (JSONSchemaDraft202012Element))) + (MemberElement + (StringElement) + (ArrayElement + (JSONSchemaDraft202012Element))) + (MemberElement + (StringElement) + (ArrayElement + (JSONSchemaDraft202012Element))) + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element)) + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element)) + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element)) + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element)) + (MemberElement + (StringElement) + (ObjectElement + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element)))) + (MemberElement + (StringElement) + (ArrayElement + (JSONSchemaDraft202012Element))) + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element)) + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element)) + (MemberElement + (StringElement) + (ObjectElement + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element)))) + (MemberElement + (StringElement) + (ObjectElement + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element)))) + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element)) + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element)) + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element)) + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element)) + (MemberElement + (StringElement) + (StringElement)) + (MemberElement + (StringElement) + (ArrayElement + (StringElement) + (NumberElement))) + (MemberElement + (StringElement) + (NullElement)) + (MemberElement + (StringElement) + (NumberElement)) + (MemberElement + (StringElement) + (NumberElement)) + (MemberElement + (StringElement) + (NumberElement)) + (MemberElement + (StringElement) + (NumberElement)) + (MemberElement + (StringElement) + (NumberElement)) + (MemberElement + (StringElement) + (NumberElement)) + (MemberElement + (StringElement) + (NumberElement)) + (MemberElement + (StringElement) + (StringElement)) + (MemberElement + (StringElement) + (NumberElement)) + (MemberElement + (StringElement) + (NumberElement)) + (MemberElement + (StringElement) + (BooleanElement)) + (MemberElement + (StringElement) + (NumberElement)) + (MemberElement + (StringElement) + (NumberElement)) + (MemberElement + (StringElement) + (NumberElement)) + (MemberElement + (StringElement) + (NumberElement)) + (MemberElement + (StringElement) + (ArrayElement + (StringElement))) + (MemberElement + (StringElement) + (ObjectElement + (MemberElement + (StringElement) + (ArrayElement + (StringElement))))) + (MemberElement + (StringElement) + (StringElement)) + (MemberElement + (StringElement) + (StringElement)) + (MemberElement + (StringElement) + (StringElement)) + (MemberElement + (StringElement) + (BooleanElement)) + (MemberElement + (StringElement) + (BooleanElement)) + (MemberElement + (StringElement) + (BooleanElement)) + (MemberElement + (StringElement) + (ArrayElement + (StringElement) + (NumberElement))) + (MemberElement + (StringElement) + (StringElement)) + (MemberElement + (StringElement) + (StringElement)) + (MemberElement + (StringElement) + (StringElement)) + (MemberElement + (StringElement) + (JSONSchemaDraft202012Element))) +`; diff --git a/packages/apidom-ns-workflows-1/test/refractor/elements/JSONSchema/embedded-resources-$id.ts b/packages/apidom-ns-workflows-1/test/refractor/elements/JSONSchema/embedded-resources-$id.ts new file mode 100644 index 0000000000..25c2f193ba --- /dev/null +++ b/packages/apidom-ns-workflows-1/test/refractor/elements/JSONSchema/embedded-resources-$id.ts @@ -0,0 +1,105 @@ +import { assert } from 'chai'; +import { find, toValue, isElement } from '@swagger-api/apidom-core'; + +import { isJSONSchemaElement, JSONSchemaElement } from '../../../../src'; + +describe('refractor', function () { + context('elements', function () { + context('JSONSchemaElement', function () { + context('$id keyword in embedded resources', function () { + context('given JSONSchema Object without $id keyword', function () { + specify('should have empty inherited$id', function () { + const jsonSchemaElement = JSONSchemaElement.refract({}); + const actual = toValue(jsonSchemaElement.meta.get('inherited$id')); + + assert.deepEqual(actual, []); + }); + }); + + context('given JSONSchema Object with arbitrary fields boundaries', function () { + specify('should annotate Schema($anchor=1) with inherited$id', function () { + const jsonSchemaElement = JSONSchemaElement.refract({ + $id: './nested/', + type: 'object', + properties: { + profile: { + $anchor: '1', + $ref: './ex.json', + }, + }, + }); + const actual = toValue(jsonSchemaElement.meta.get('inherited$id')); + + assert.deepEqual(actual, ['./nested/']); + }); + }); + + context('given JSONSchema Object with inner Schemas', function () { + let jsonSchemaElement: any; + + beforeEach(function () { + jsonSchemaElement = JSONSchemaElement.refract({ + $anchor: '1', + type: 'object', + oneOf: [ + { + $id: '$id1', + $anchor: '2', + type: 'number', + contains: { $id: '$id2', $anchor: '3', type: 'object' }, + }, + ], + contains: { + $anchor: '4', + type: 'string', + }, + }); + }); + + specify('should annotate JSONSchema Object($anchor=1) with inherited$id', function () { + const foundJsonSchemaElement = find( + (e) => isJSONSchemaElement(e) && isElement(e.$anchor) && e.$anchor.equals('1'), + jsonSchemaElement, + ); + const actual = toValue(foundJsonSchemaElement.meta.get('inherited$id')); + + assert.deepEqual(actual, []); + }); + + specify('should annotate JSONSchema Object($anchor=2) with inherited$id', function () { + const foundJsonSchemaElement = find( + (e) => isJSONSchemaElement(e) && isElement(e.$anchor) && e.$anchor.equals('2'), + jsonSchemaElement, + ); + const actual = toValue(foundJsonSchemaElement.meta.get('inherited$id')); + + assert.deepEqual(actual, ['$id1']); + }); + + specify('should annotate JSONSchema Object($anchor=3) with inherited$id', function () { + const foundJsonSchemaElement = find( + (e) => isJSONSchemaElement(e) && isElement(e.$anchor) && e.$anchor.equals('3'), + jsonSchemaElement, + ); + const actual = toValue(foundJsonSchemaElement.meta.get('inherited$id')); + + assert.deepEqual(actual, ['$id1', '$id2']); + }); + + specify( + 'should not annotate JSONSchema Object($anchor=4) with inherited$id', + function () { + const foundJsonSchemaElement = find( + (e) => isJSONSchemaElement(e) && isElement(e.$anchor) && e.$anchor.equals('4'), + jsonSchemaElement, + ); + const actual = toValue(foundJsonSchemaElement.meta.get('inherited$id')); + + assert.deepEqual(actual, []); + }, + ); + }); + }); + }); + }); +}); diff --git a/packages/apidom-ns-workflows-1/test/refractor/elements/JSONSchema/embedded-resources-$schema.ts b/packages/apidom-ns-workflows-1/test/refractor/elements/JSONSchema/embedded-resources-$schema.ts new file mode 100644 index 0000000000..7ea76673b2 --- /dev/null +++ b/packages/apidom-ns-workflows-1/test/refractor/elements/JSONSchema/embedded-resources-$schema.ts @@ -0,0 +1,110 @@ +import { assert } from 'chai'; +import { find, toValue, isElement } from '@swagger-api/apidom-core'; + +import { JSONSchemaElement, isJSONSchemaElement } from '../../../../src'; + +describe('refractor', function () { + context('elements', function () { + context('JSONSchemaElement', function () { + context('$schema keyword in embedded resources', function () { + context('given JSONSchema Object without $schema keyword', function () { + specify('should annotate JSONSchema Object with default dialect', function () { + const jsonSchemaElement = JSONSchemaElement.refract({ + $id: '1', + type: 'object', + not: {}, + }) as JSONSchemaElement; + const actual = toValue(jsonSchemaElement.not?.meta.get('inherited$schema')); + const expected = toValue('https://json-schema.org/draft/2020-12/schema'); + + assert.strictEqual(actual, expected); + }); + }); + + context( + 'given direct refracting to JSONSchema Element from generic structure', + function () { + specify('should annotate Schema Object with default dialect', function () { + const jsonSchemaElement = JSONSchemaElement.refract({ + $id: '1', + type: 'object', + }) as JSONSchemaElement; + const actual = toValue(jsonSchemaElement.meta.get('inherited$schema')); + const expected = 'https://json-schema.org/draft/2020-12/schema'; + + assert.strictEqual(actual, expected); + }); + }, + ); + + context('given JSONSchema Object with inner Schemas', function () { + let jsonSchemaElement: any; + + beforeEach(function () { + jsonSchemaElement = JSONSchemaElement.refract({ + $id: '1', + type: 'object', + oneOf: [ + { + $id: '2', + type: 'number', + $schema: '$schema1', + contains: { $id: '3', type: 'object' }, + }, + ], + contains: { + $id: '4', + type: 'string', + }, + }); + }); + + specify('should annotate Schema Object($id=1) with appropriate dialect', function () { + const foundJsonSchemaElement = find( + (e) => isJSONSchemaElement(e) && isElement(e.$id) && e.$id.equals('1'), + jsonSchemaElement, + ); + const actual = toValue(foundJsonSchemaElement.meta.get('inherited$schema')); + const expected = 'https://json-schema.org/draft/2020-12/schema'; + + assert.strictEqual(actual, expected); + }); + + specify('should not annotate Schema Object($id=2) with any dialect', function () { + const foundJsonSchemaElement = find( + (e) => isJSONSchemaElement(e) && isElement(e.$id) && e.$id.equals('2'), + jsonSchemaElement, + ); + const actual = toValue(foundJsonSchemaElement?.$schema); + const expected = '$schema1'; + + assert.strictEqual(actual, expected); + assert.isFalse(foundJsonSchemaElement?.meta.hasKey('inherited$schema')); + }); + + specify('should annotate Schema Object($id=3) with appropriate dialect', function () { + const foundJsonSchemaElement = find( + (e) => isJSONSchemaElement(e) && isElement(e.$id) && e.$id.equals('3'), + jsonSchemaElement, + ); + const actual = toValue(foundJsonSchemaElement?.meta.get('inherited$schema')); + const expected = '$schema1'; + + assert.strictEqual(actual, expected); + }); + + specify('should annotate Schema Object($id=4) with appropriate dialect', function () { + const foundJsonSchemaElement = find( + (e) => isJSONSchemaElement(e) && isElement(e.$id) && e.$id.equals('4'), + jsonSchemaElement, + ); + const actual = toValue(foundJsonSchemaElement?.meta.get('inherited$schema')); + const expected = 'https://json-schema.org/draft/2020-12/schema'; + + assert.strictEqual(actual, expected); + }); + }); + }); + }); + }); +}); diff --git a/packages/apidom-ns-workflows-1/test/refractor/elements/JSONSchema/index.ts b/packages/apidom-ns-workflows-1/test/refractor/elements/JSONSchema/index.ts new file mode 100644 index 0000000000..de170951b0 --- /dev/null +++ b/packages/apidom-ns-workflows-1/test/refractor/elements/JSONSchema/index.ts @@ -0,0 +1,131 @@ +import { expect } from 'chai'; +import { sexprs } from '@swagger-api/apidom-core'; + +import { JSONSchemaElement } from '../../../../src'; + +describe('refractor', function () { + context('elements', function () { + context('JSONSchemaElement', function () { + specify('should refract to semantic ApiDOM tree', function () { + const jsonSchemaElement = JSONSchemaElement.refract({ + // core vocabulary + $schema: 'https://example.com/', + $id: 'https://example.com', + $vocabulary: { + 'https://json-schema.org/draft/2020-12/vocab/core': true, + }, + $anchor: 'anchor', + $dynamicAnchor: 'dynamicAnchor', + $dynamicRef: '#node', + $ref: '#/components/Schemas/Schema1', + $defs: { + enabledToggle: {}, + }, + $comment: 'comment', + // applicator vocabulary + allOf: [{}], + anyOf: [{}], + oneOf: [{}], + not: {}, + if: {}, + then: {}, + else: {}, + dependentSchemas: { + key: {}, + }, + prefixItems: [{}], + items: {}, + contains: {}, + properties: { + enabled: {}, + }, + patternProperties: { + abc: {}, + }, + additionalProperties: {}, + propertyNames: {}, + // unevaluated Locations vocabulary + unevaluatedItems: {}, + unevaluatedProperties: {}, + // validation vocabulary + // validation Keywords for Any Instance Type + type: 'object', + enum: ['a', 1], + const: null, + // validation Keywords for Numeric Instances (number and integer) + multipleOf: 2, + maximum: 100, + exclusiveMaximum: 99, + minimum: 20, + exclusiveMinimum: 19, + // validation Keywords for Strings + maxLength: 20, + minLength: 10, + pattern: 'abc', + // validation Keywords for Arrays + maxItems: 5, + minItems: 1, + uniqueItems: true, + maxContains: 4, + minContains: 2, + // validation Keywords for Objects + maxProperties: 5, + minProperties: 4, + require: ['prop1'], + dependentRequired: { + prop: ['prop1'], + }, + // basic Meta-Data Annotations vocabulary + title: 'schema-title', + description: 'schema-description', + default: 'test', + deprecated: true, + readOnly: true, + writeOnly: false, + examples: ['a', 1], + // semantic Content With "format" vocabulary + format: 'time', + // contents of String-Encoded Data vocabulary + contentEncoding: 'base64', + contentMediaType: 'image/png', + contentSchema: {}, + }); + + expect(sexprs(jsonSchemaElement)).toMatchSnapshot(); + }); + + context('given embedded JSONSchemaElements', function () { + specify('should refract to semantic ApiDOM tree', function () { + const schemaElement = JSONSchemaElement.refract({ + $defs: { + enabledToggle: { not: {} }, + }, + allOf: [{ not: {} }], + dependentSchemas: { + key: { not: {} }, + }, + contentSchema: { not: {} }, + }); + + expect(sexprs(schemaElement)).toMatchSnapshot(); + }); + }); + + context('given Boolean JSON Schemas', function () { + specify('should refract to semantic ApiDOM tree', function () { + const schemaElement = JSONSchemaElement.refract({ + $defs: { + enabledToggle: { not: true }, + }, + allOf: [true, false], + dependentSchemas: { + key: { not: false }, + }, + }); + + expect(sexprs(schemaElement)).toMatchSnapshot(); + }); + }); + }); + }); +});