Skip to content

Commit

Permalink
feat(ns-workflows-1): add support for JSONSchema Object (#3445)
Browse files Browse the repository at this point in the history
Refs #3392
  • Loading branch information
char0n committed Nov 23, 2023
1 parent 8435e5c commit 5b504e5
Show file tree
Hide file tree
Showing 19 changed files with 855 additions and 119 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions packages/apidom-ns-openapi-3-1/src/elements/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions packages/apidom-ns-openapi-3-1/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
230 changes: 115 additions & 115 deletions packages/apidom-ns-openapi-3-1/src/refractor/specification.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);

Expand Down
1 change: 1 addition & 0 deletions packages/apidom-ns-workflows-1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
1 change: 1 addition & 0 deletions packages/apidom-ns-workflows-1/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
47 changes: 47 additions & 0 deletions packages/apidom-ns-workflows-1/src/elements/JSONSchema.ts
Original file line number Diff line number Diff line change
@@ -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<string, unknown>, 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;
2 changes: 2 additions & 0 deletions packages/apidom-ns-workflows-1/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export {
isFailureActionElement,
isFailureActionCriteriaElement,
isCriterionElement,
isJSONSchemaElement,
} from './predicates';

export { isWorkflowsSpecificationExtension } from './refractor/predicates';
Expand All @@ -56,6 +57,7 @@ export {
SuccessActionElement,
FailureActionElement,
CriterionElement,
JSONSchemaElement,
} from './refractor/registration';
// NCE types
export { default as SourceDescriptionsElement } from './elements/nces/SourceDescriptions';
Expand Down
2 changes: 2 additions & 0 deletions packages/apidom-ns-workflows-1/src/namespace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand All @@ -21,6 +22,7 @@ const workflows1 = {
base.register('successAction', SuccessActionElement);
base.register('failureAction', FailureActionElement);
base.register('criterion', CriterionElement);
base.register('jSONSchemaDraft202012', JSONSchemaElement);

return base;
},
Expand Down
11 changes: 11 additions & 0 deletions packages/apidom-ns-workflows-1/src/predicates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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));
},
);
9 changes: 9 additions & 0 deletions packages/apidom-ns-workflows-1/src/refractor/registration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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']);
Expand Down Expand Up @@ -59,6 +60,13 @@ CriterionElement.refract = createRefractor([
'Criterion',
'$visitor',
]);
JSONSchemaElement.refract = createRefractor([
'visitors',
'document',
'objects',
'JSONSchema',
'$visitor',
]);

export {
WorkflowsSpecification1Element,
Expand All @@ -69,4 +77,5 @@ export {
SuccessActionElement,
FailureActionElement,
CriterionElement,
JSONSchemaElement,
};
23 changes: 23 additions & 0 deletions packages/apidom-ns-workflows-1/src/refractor/specification.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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';

Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
1 change: 1 addition & 0 deletions packages/apidom-ns-workflows-1/src/traversal/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ export const keyMap = {
SuccessActionElement: ['content'],
FailureActionElement: ['content'],
CriterionElement: ['content'],
JSONSSchemaDraft202012Element: ['content'],
...keyMapBase,
};

0 comments on commit 5b504e5

Please sign in to comment.