Skip to content

Commit

Permalink
feat(resolver): add support for mode resolver option
Browse files Browse the repository at this point in the history
This option activates allOf plugin/visitor.

Refs #2750
  • Loading branch information
char0n committed Jan 19, 2023
1 parent cd5000c commit e1437a8
Show file tree
Hide file tree
Showing 9 changed files with 982 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import openApi3_1Namespace, { getNodeType, keyMap } from '@swagger-api/apidom-ns
import OpenApi3_1SwaggerClientDereferenceVisitor from './visitors/dereference.js';
import ParameterMacroVisitor from './visitors/parameters.js';
import ModelPropertyMacroVisitor from './visitors/properties.js';
import AllOfVisitor from './visitors/all-of.js';

const visitAsync = visit[Symbol.for('nodejs.util.promisify.custom')];

Expand All @@ -16,18 +17,21 @@ const OpenApi3_1SwaggerClientDereferenceStrategy = OpenApi3_1DereferenceStrategy
allowMetaPatches: false,
parameterMacro: null,
modelPropertyMacro: null,
mode: 'non-strict',
},
init({
useCircularStructures = this.useCircularStructures,
allowMetaPatches = this.allowMetaPatches,
parameterMacro = this.parameterMacro,
modelPropertyMacro = this.modelPropertyMacro,
mode = this.mode,
} = {}) {
this.name = 'openapi-3-1-swagger-client';
this.useCircularStructures = useCircularStructures;
this.allowMetaPatches = allowMetaPatches;
this.parameterMacro = parameterMacro;
this.modelPropertyMacro = modelPropertyMacro;
this.mode = mode;
},
methods: {
async dereference(file, options) {
Expand Down Expand Up @@ -70,6 +74,12 @@ const OpenApi3_1SwaggerClientDereferenceStrategy = OpenApi3_1DereferenceStrategy
visitors.push(modelPropertyMacroVisitor);
}

// create allOf visitor (if necessary)
if (this.mode !== 'strict') {
const allOfVisitor = AllOfVisitor();
visitors.push(allOfVisitor);
}

// determine the root visitor
const rootVisitor =
visitors.length === 1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { isArrayElement, deepmerge } from '@swagger-api/apidom-core';
import { isSchemaElement, SchemaElement } from '@swagger-api/apidom-ns-openapi-3-1';

const AllOfVisitor = () => ({
SchemaElement: {
leave(schemaElement) {
// do nothing
if (typeof schemaElement.allOf === 'undefined') return undefined;
// throw if allOf keyword is not an array
if (!isArrayElement(schemaElement.allOf)) {
throw new TypeError('allOf must be an array');
}
// remove allOf keyword if empty
if (schemaElement.allOf.isEmpty) {
return new SchemaElement(
schemaElement.content.filter((memberElement) => memberElement.key.toValue() !== 'allOf'),
schemaElement.meta.clone(),
schemaElement.attributes.clone()
);
}
// throw if allOf keyword contains anything else than Schema Object
schemaElement.allOf.forEach((item) => {
if (!isSchemaElement(item)) {
throw new TypeError('Elements in allOf must be objects');
}
});

const mergedSchemaElement = deepmerge.all([...schemaElement.allOf.content, schemaElement]);

/**
* If there was not an original $$ref value, make sure to remove
* any $$ref value that may exist from the result of `allOf` merges.
*/
if (!schemaElement.hasKey('$$ref')) {
mergedSchemaElement.remove('$$ref');
}

/**
* If there was an example keyword in the original definition,
* keep it instead of merging with example from other schema.
*/
if (schemaElement.hasKey('example')) {
const member = mergedSchemaElement.getMember('example');
member.value = schemaElement.get('example');
}

/**
* If there was an examples keyword in the original definition,
* keep it instead of merging with examples from other schema.
*/
if (schemaElement.hasKey('examples')) {
const member = mergedSchemaElement.getMember('examples');
member.value = schemaElement.get('examples');
}

// remove allOf keyword after the merge
mergedSchemaElement.remove('allOf');
return mergedSchemaElement;
},
},
});

export default AllOfVisitor;
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const ParameterMacroVisitor = ({ parameterMacro }) => {
},
},
ParameterElement: {
leave: (parameterElement) => {
leave(parameterElement) {
const pojoOperation = macroOperation === null ? null : toValue(macroOperation);
const pojoParameter = toValue(parameterElement);
const defaultValue = parameterMacro(pojoOperation, pojoParameter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { isObjectElement, toValue } from '@swagger-api/apidom-core';

const ModelPropertyMacroVisitor = ({ modelPropertyMacro }) => ({
SchemaElement: {
leave: (schemaElement) => {
leave(schemaElement) {
if (typeof schemaElement.properties === 'undefined') return;
if (!isObjectElement(schemaElement.properties)) return;

Expand Down
2 changes: 2 additions & 0 deletions src/resolver/strategies/openapi-3-1.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const resolveOpenAPI31Strategy = async (options) => {
skipNormalization = false,
parameterMacro = null,
modelPropertyMacro = null,
mode = 'non-strict',
} = options;
try {
// determining BaseURI
Expand Down Expand Up @@ -101,6 +102,7 @@ const resolveOpenAPI31Strategy = async (options) => {
useCircularStructures,
parameterMacro,
modelPropertyMacro,
mode,
}),
],
refSet,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@
},
"schema3": {
"type": "object"
},
"schema4": {
"type": "string"
},
"Animal": {
"properties": {
"pet": {
"$$ref": "http://localhost:8123/root.json#/components/schemas/schema3",
"type": "object"
},
"cat": {
"$$ref": "http://localhost:8123/root.json#/components/schemas/schema4",
"type": "string"
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@
},
"schema3": {
"type": "object"
},
"schema4": {
"type": "string"
},
"Animal": {
"properties": {
"pet": {
"$ref": "#/components/schemas/schema3"
},
"cat": {
"$ref": "#/components/schemas/schema4"
}
}
}
}
}
Expand Down
Loading

0 comments on commit e1437a8

Please sign in to comment.