Merge pull request #304 from postmanlabs/feature/improve-allof

Fixed issue where schemas in allOf were not resolved correctly.
This commit is contained in:
Vishal Shingala
2020-10-15 13:16:50 +05:30
committed by GitHub
7 changed files with 144 additions and 36 deletions

View File

@@ -1,7 +1,9 @@
language: node_js
node_js:
- "7"
- "8"
- "9"
- "10"
- "11"
- "12"
- "node"
- "lts/*"

View File

@@ -1,4 +1,5 @@
const _ = require('lodash'),
mergeAllOf = require('json-schema-merge-allof'),
type = {
integer: {
int32: '<integer>',
@@ -86,38 +87,23 @@ module.exports = {
resolveTo, stack, seenRef, stackLimit);
}
// generate one object for each schema
let indivObjects = schemaArr.map((schema) => {
return this.resolveRefs(schema, parameterSourceOption, components, schemaResolutionCache, resolveFor,
resolveTo, stack, seenRef, stackLimit);
}).filter((schema) => {
return schema.type === 'object';
}),
// generated object with properties from all allOf entries which we return
finalObject = {
type: 'object',
properties: {}
},
// set of properties which we've already handled, to avoid repitition
handledProps = {},
i,
j;
for (i = 0; i < indivObjects.length; i++) {
// go through the indiv props, and add to finalObject if not in handledProps
for (j in indivObjects[i].properties) {
if (indivObjects[i].properties.hasOwnProperty(j) && !handledProps[j]) {
handledProps[j] = true;
finalObject.properties[j] = indivObjects[i].properties[j];
try {
return mergeAllOf({
allOf: schemaArr.map((schema) => {
return this.resolveRefs(schema, parameterSourceOption, components, schemaResolutionCache, resolveFor,
resolveTo, stack, seenRef, stackLimit);
})
}, {
resolvers: {
// for keywords in OpenAPI schema that are not standard defined JSON schema keywords, use default resolver
defaultResolver: (compacted) => { return compacted[0]; }
}
}
finalObject.description = finalObject.description || indivObjects[i].description;
});
}
catch (e) {
console.warn('Error while resolving allOf schema: ', e);
return { value: '<Error: Could not resolve allOf schema' };
}
return finalObject;
},
/**
@@ -309,8 +295,7 @@ module.exports = {
}
else {
return {
type: 'string',
default: 'schema type not provided'
type: 'object'
};
}
if (!schema.type) {

71
package-lock.json generated
View File

@@ -471,6 +471,27 @@
"integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
"dev": true
},
"compute-gcd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/compute-gcd/-/compute-gcd-1.2.0.tgz",
"integrity": "sha1-/B7eW2UAHpUCJlAvRlQ4Y+T+oQ4=",
"requires": {
"validate.io-array": "^1.0.3",
"validate.io-function": "^1.0.2",
"validate.io-integer-array": "^1.0.0"
}
},
"compute-lcm": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/compute-lcm/-/compute-lcm-1.1.0.tgz",
"integrity": "sha1-q9ltBAtBsKFm+JlEtci3xRHiGtU=",
"requires": {
"compute-gcd": "^1.2.0",
"validate.io-array": "^1.0.3",
"validate.io-function": "^1.0.2",
"validate.io-integer-array": "^1.0.0"
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -1319,6 +1340,24 @@
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
"dev": true
},
"json-schema-compare": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz",
"integrity": "sha512-c4WYmDKyJXhs7WWvAWm3uIYnfyWFoIp+JEoX34rctVvEkMYCPGhXtvmFFXiffBbxfZsvQ0RNnV5H7GvDF5HCqQ==",
"requires": {
"lodash": "^4.17.4"
}
},
"json-schema-merge-allof": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.7.0.tgz",
"integrity": "sha512-kvsuSVnl1n5xnNEu5ed4o8r8ujSA4/IgRtHmpgfMfa7FOMIRAzN4F9qbuklouTn5J8bi83y6MQ11n+ERMMTXZg==",
"requires": {
"compute-lcm": "^1.1.0",
"json-schema-compare": "^0.2.2",
"lodash": "^4.17.4"
}
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -2652,6 +2691,38 @@
"spdx-expression-parse": "^3.0.0"
}
},
"validate.io-array": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/validate.io-array/-/validate.io-array-1.0.6.tgz",
"integrity": "sha1-W1osr9j4uFq7L4hroVPy2Tond00="
},
"validate.io-function": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/validate.io-function/-/validate.io-function-1.0.2.tgz",
"integrity": "sha1-NDoZgC7TsZaCaceA5VjpNBHAutc="
},
"validate.io-integer": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/validate.io-integer/-/validate.io-integer-1.0.5.tgz",
"integrity": "sha1-FoSWSAuVviJH7EQ/IjPeT4mHgGg=",
"requires": {
"validate.io-number": "^1.0.3"
}
},
"validate.io-integer-array": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/validate.io-integer-array/-/validate.io-integer-array-1.0.0.tgz",
"integrity": "sha1-LKveAzKTpry+Bj/q/pHq9GsToIk=",
"requires": {
"validate.io-array": "^1.0.3",
"validate.io-integer": "^1.0.4"
}
},
"validate.io-number": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/validate.io-number/-/validate.io-number-1.0.3.tgz",
"integrity": "sha1-9j/+2iSL8opnqNSODjtGGhZluvg="
},
"which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",

View File

@@ -109,7 +109,7 @@
}
},
"engines": {
"node": ">=4"
"node": ">=8"
},
"main": "index.js",
"bin": {
@@ -120,6 +120,7 @@
"async": "3.2.0",
"commander": "2.20.3",
"js-yaml": "3.13.1",
"json-schema-merge-allof": "0.7.0",
"lodash": "4.17.20",
"oas-resolver-browser": "2.3.3",
"path-browserify": "1.0.1",

View File

@@ -49,7 +49,7 @@ describe('project repository', function () {
expect(json.keywords).to.eql(['openapi', 'postman', 'api', 'schema', 'swagger', 'oas']);
expect(json).to.have.property('engines');
expect(json.engines).to.eql({ node: '>=4' });
expect(json.engines).to.eql({ node: '>=8' });
});
it('must have a valid version string in form of <major>.<minor>.<revision>', function () {

View File

@@ -25,7 +25,7 @@ describe('travis.yml', function () {
describe('strucure', function () {
it('language must be set to node', function () {
expect(travisYAML.language).to.be('node_js');
expect(travisYAML.node_js).to.eql(['7', '8', '9', 'node', 'lts/*']);
expect(travisYAML.node_js).to.eql(['8', '9', '10', '11', '12', 'node', 'lts/*']);
});
});
});

View File

@@ -218,6 +218,55 @@ describe('DEREF FUNCTION TESTS ', function() {
});
});
describe('resolveAllOf Function', function () {
it('should resolve allOf schemas correctly', function (done) {
var allOfschema = [
{
'type': 'object',
'properties': {
'source': {
'type': 'string',
'format': 'uuid'
},
'actionId': { 'type': 'integer', 'minimum': 5 },
'result': { 'type': 'object' }
},
'required': ['source', 'actionId', 'result']
},
{
'properties': {
'result': {
'type': 'object',
'properties': {
'err': { 'type': 'string' },
'data': { 'type': 'object' }
}
}
}
}
];
expect(deref.resolveAllOf(allOfschema, 'REQUEST', {}, {}, null, 'example')).to.deep.include({
type: 'object',
properties: {
source: {
type: 'string',
format: 'uuid'
},
actionId: { 'type': 'integer', 'minimum': 5 },
result: {
type: 'object',
properties: {
err: { 'type': 'string' },
data: { 'type': 'object' }
}
}
}
});
done();
});
});
describe('_getEscaped should', function() {
var rootObject = {
person: {