Skip to content

Commit 80b6d9a

Browse files
authored
Merge pull request #23 from JaredCE/move-default-into-of-properties
Move default into of properties
2 parents ae4a0db + 4ff2fd8 commit 80b6d9a

File tree

7 files changed

+151
-3
lines changed

7 files changed

+151
-3
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "json-schema-for-openapi",
3-
"version": "0.3.1",
3+
"version": "0.3.2",
44
"description": "Converts a regular JSON Schema to a compatible OpenAPI 3.0.X Schema Object",
55
"keywords": [
66
"json",

src/Convertor.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class Convertor {
119119
this.removeEmptyRequired(schema)
120120
this.convertNullProperty(schema)
121121
this.convertDefaultValues(schema)
122+
this.pullOrphanedPropertiesIntoOneAnyAllOf(schema)
122123
this.convertOneOfAnyOfNulls(schema)
123124
this.removeInvalidFields(schema)
124125
}
@@ -444,6 +445,36 @@ class Convertor {
444445
}
445446
}
446447
}
448+
449+
pullOrphanedPropertiesIntoOneAnyAllOf(schema) {
450+
const properties = ['default']
451+
452+
const addItem = (intersection, schemaOf) => {
453+
for (const property of intersection) {
454+
for (const item of schemaOf) {
455+
item[property] = schema[property]
456+
}
457+
}
458+
}
459+
460+
if (schema.allOf || schema.anyOf || schema.oneOf) {
461+
const intersection = Object.keys(schema).filter(property => properties.includes(property))
462+
463+
if (intersection.length) {
464+
if (schema.allOf) {
465+
addItem(intersection, schema.allOf)
466+
} else if (schema.oneOf) {
467+
addItem(intersection, schema.oneOf)
468+
} else {
469+
addItem(intersection, schema.anyOf)
470+
}
471+
}
472+
473+
for (const property of intersection) {
474+
delete schema[property]
475+
}
476+
}
477+
}
447478
}
448479

449480
module.exports = Convertor
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-04/schema#",
3+
"title": "JSON API Schema",
4+
"description": "This is a schema for responses in the JSON API format. For more, see http://jsonapi.org",
5+
"type": "object",
6+
"properties": {
7+
"payment": {
8+
"allOf": [
9+
{
10+
"type": "string"
11+
}
12+
],
13+
"default": "one"
14+
}
15+
}
16+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-04/schema#",
3+
"title": "JSON API Schema",
4+
"description": "This is a schema for responses in the JSON API format. For more, see http://jsonapi.org",
5+
"type": "object",
6+
"properties": {
7+
"payment": {
8+
"anyOf": [
9+
{
10+
"type": "string"
11+
},
12+
{
13+
"type": "number"
14+
}
15+
],
16+
"default": "one"
17+
}
18+
}
19+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-04/schema#",
3+
"title": "JSON API Schema",
4+
"description": "This is a schema for responses in the JSON API format. For more, see http://jsonapi.org",
5+
"type": "object",
6+
"properties": {
7+
"payment": {
8+
"oneOf": [
9+
{
10+
"type": "string"
11+
}
12+
],
13+
"default": "one"
14+
}
15+
}
16+
}

test/src/Convertor.spec.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ const listOfBannedSchemas = require('../schemas/SchemasThatCannotBeConverted/lis
5353
// anyOf/oneOf Nulls
5454
const oneOfNull = require('../schemas/ofNulls/oneOfNull.json')
5555
const anyOfNull = require('../schemas/ofNulls/anyOfNull.json')
56+
// anyOf/oneOf Nulls
57+
const allOfProperties = require('../schemas/propertiesOutsideOf/allOf.json')
58+
const oneOfProperties = require('../schemas/propertiesOutsideOf/oneOf.json')
59+
const anyOfProperties = require('../schemas/propertiesOutsideOf/anyOf.json')
60+
5661

5762
// OpenAPI
5863
const basicOpenAPI = require('../openAPI/basic.json')
@@ -633,6 +638,67 @@ describe('Convertor', () => {
633638
});
634639
});
635640

641+
describe(`properties that exist outside of a oneOf|anyOf|allOf`, function () {
642+
it(`should put the property outside of an oneOf into the oneOf`, async function() {
643+
const newConvertor = new Convertor(oneOfProperties)
644+
const result = newConvertor.convert('basic')
645+
expect(result.schemas.basic.properties.payment).to.have.property('oneOf')
646+
expect(result.schemas.basic.properties.payment.oneOf).to.be.an('array')
647+
expect(result.schemas.basic.properties.payment.oneOf.length).to.be.equal(1)
648+
expect(result.schemas.basic.properties.payment).to.not.have.property('default')
649+
expect(result.schemas.basic.properties.payment.oneOf[0]).to.have.property('default')
650+
expect(result.schemas.basic.properties.payment.oneOf[0].default).to.be.equal('one')
651+
652+
const cloned = JSON.parse(JSON.stringify(basicOpenAPI))
653+
Object.assign(cloned, {components: result})
654+
expect(cloned).to.have.property('components')
655+
expect(cloned.components).to.have.property('schemas')
656+
expect(cloned.components.schemas).to.have.property('basic')
657+
let valid = await validator.validateInner(cloned, {})
658+
expect(valid).to.be.true
659+
});
660+
661+
it(`should put the property outside of an anyOf into the anyOf`, async function() {
662+
const newConvertor = new Convertor(anyOfProperties)
663+
const result = newConvertor.convert('basic')
664+
expect(result.schemas.basic.properties.payment).to.have.property('anyOf')
665+
expect(result.schemas.basic.properties.payment.anyOf).to.be.an('array')
666+
expect(result.schemas.basic.properties.payment.anyOf.length).to.be.equal(2)
667+
expect(result.schemas.basic.properties.payment).to.not.have.property('default')
668+
expect(result.schemas.basic.properties.payment.anyOf[0]).to.have.property('default')
669+
expect(result.schemas.basic.properties.payment.anyOf[0].default).to.be.equal('one')
670+
expect(result.schemas.basic.properties.payment.anyOf[1]).to.have.property('default')
671+
expect(result.schemas.basic.properties.payment.anyOf[1].default).to.be.equal(1)
672+
673+
const cloned = JSON.parse(JSON.stringify(basicOpenAPI))
674+
Object.assign(cloned, {components: result})
675+
expect(cloned).to.have.property('components')
676+
expect(cloned.components).to.have.property('schemas')
677+
expect(cloned.components.schemas).to.have.property('basic')
678+
let valid = await validator.validateInner(cloned, {})
679+
expect(valid).to.be.true
680+
});
681+
682+
it(`should put the property outside of an allOf into the allOf`, async function() {
683+
const newConvertor = new Convertor(allOfProperties)
684+
const result = newConvertor.convert('basic')
685+
expect(result.schemas.basic.properties.payment).to.have.property('allOf')
686+
expect(result.schemas.basic.properties.payment.allOf).to.be.an('array')
687+
expect(result.schemas.basic.properties.payment.allOf.length).to.be.equal(1)
688+
expect(result.schemas.basic.properties.payment).to.not.have.property('default')
689+
expect(result.schemas.basic.properties.payment.allOf[0]).to.have.property('default')
690+
expect(result.schemas.basic.properties.payment.allOf[0].default).to.be.equal('one')
691+
692+
const cloned = JSON.parse(JSON.stringify(basicOpenAPI))
693+
Object.assign(cloned, {components: result})
694+
expect(cloned).to.have.property('components')
695+
expect(cloned.components).to.have.property('schemas')
696+
expect(cloned.components.schemas).to.have.property('basic')
697+
let valid = await validator.validateInner(cloned, {})
698+
expect(valid).to.be.true
699+
});
700+
});
701+
636702
xdescribe('use a repo with lots of schemas to find failing ones', () => {
637703
it('should convert all schemas successfully', async function() {
638704
this.timeout(1000000);

0 commit comments

Comments
 (0)