json-schema-to-openapi-schema
Advanced tools
+11
| # Changelog | ||
| All notable changes to this project will be documented in this file. | ||
| The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) | ||
| and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). | ||
| ## [Unreleased] | ||
| ## [0.1.1] - 2018-04-09 | ||
| ### Added | ||
| * Convert `dependencies` to an allOf + oneOf OpenAPI-valid equivalent |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| it('cloning schema by default', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: ['string', 'null'], | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'string', | ||
| nullable: true, | ||
| }; | ||
| should(result).deepEqual(expected, 'result does not match the expected'); | ||
| should(result).not.deepEqual(schema, 'the schema was modified in place'); | ||
| }); | ||
| it('cloning schema with cloneSchema option', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: ['string', 'null'], | ||
| }; | ||
| const result = convert(schema, { cloneSchema: true }); | ||
| const expected = { | ||
| type: 'string', | ||
| nullable: true, | ||
| }; | ||
| should(result).deepEqual(expected, 'result does not match the expected'); | ||
| should(result).not.deepEqual(schema, 'the schema was modified in place'); | ||
| }); | ||
| it('direct schema modification', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: ['string', 'null'], | ||
| }; | ||
| const result = convert(schema, { cloneSchema: false }); | ||
| const expected = { | ||
| type: 'string', | ||
| nullable: true, | ||
| }; | ||
| should(result).deepEqual(expected, 'result does not match the expected'); | ||
| should(result).deepEqual(schema, 'the schema was not modified in place'); | ||
| }); |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| it('iterates allOfs and converts types', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| allOf: [ | ||
| { | ||
| type: 'object', | ||
| required: ['foo'], | ||
| properties: { | ||
| foo: { | ||
| type: 'integer', | ||
| format: 'int64' | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| allOf: [ | ||
| { | ||
| type: 'number', | ||
| format: 'double' | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| allOf: [ | ||
| { | ||
| type: 'object', | ||
| required: ['foo'], | ||
| properties: { | ||
| foo: { | ||
| type: 'integer', | ||
| format: 'int64' | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| allOf: [ | ||
| { | ||
| type: 'number', | ||
| format: 'double' | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| }; | ||
| should(result).deepEqual(expected, 'iterated allOfs'); | ||
| }); | ||
| it('iterates anyOfs and converts types', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| anyOf: [ | ||
| { | ||
| type: 'object', | ||
| required: ['foo'], | ||
| properties: { | ||
| foo: { | ||
| type: 'integer', | ||
| format: 'int64' | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| anyOf: [ | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| bar: { | ||
| type: 'number', | ||
| format: 'double' | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| anyOf: [ | ||
| { | ||
| type: 'object', | ||
| required: ['foo'], | ||
| properties: { | ||
| foo: { | ||
| type: 'integer', | ||
| format: 'int64' | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| anyOf: [ | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| bar: { | ||
| type: 'number', | ||
| format: 'double' | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| }; | ||
| should(result).deepEqual(expected, 'anyOfs iterated'); | ||
| }); | ||
| it('iterates oneOfs and converts types', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| oneOf: [ | ||
| { | ||
| type: 'object', | ||
| required: ['foo'], | ||
| properties: { | ||
| foo: { | ||
| type: ['string', 'null'] | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| oneOf: [ | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| bar: { | ||
| type: ['string', 'null'] | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| oneOf: [ | ||
| { | ||
| type: 'object', | ||
| required: ['foo'], | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| nullable: true | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| oneOf: [ | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| bar: { | ||
| type: 'string', | ||
| nullable: true | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| }; | ||
| should(result).deepEqual(expected, 'oneOfs iterated'); | ||
| }); | ||
| it('converts types in not', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: 'object', | ||
| properties: { | ||
| not: { | ||
| type: ['string', 'null'], | ||
| minLength: 8 | ||
| } | ||
| } | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'object', | ||
| properties: { | ||
| not: { | ||
| type: 'string', | ||
| nullable: true, | ||
| minLength: 8 | ||
| } | ||
| } | ||
| }; | ||
| should(result).deepEqual(expected, 'not handled'); | ||
| }); | ||
| it('nested combination keywords', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| anyOf: [ | ||
| { | ||
| allOf: [ | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: ['string', 'null'] | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| bar: { | ||
| type: ['integer', 'null'] | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| not: { | ||
| type: 'string', | ||
| example: 'foobar' | ||
| } | ||
| } | ||
| ] | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| anyOf: [ | ||
| { | ||
| allOf: [ | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| nullable: true | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| bar: { | ||
| type: 'integer', | ||
| nullable: true | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| not: { | ||
| type: 'string', | ||
| example: 'foobar' | ||
| } | ||
| } | ||
| ] | ||
| }; | ||
| should(result).deepEqual(expected, 'nested combination keywords'); | ||
| }); |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| const getSchema = require('./helpers').getSchema; | ||
| ['basic', 'address', 'calendar'].forEach(test => { | ||
| it(`converts ${test}/openapi.json`, () => { | ||
| const schema = getSchema(test + '/json-schema.json'); | ||
| const result = convert(schema); | ||
| const expected = getSchema(test + '/openapi.json'); | ||
| should(result).deepEqual(expected, 'converted'); | ||
| }); | ||
| it(`converting ${test}/openapi.json in place`, () => { | ||
| const schema = getSchema(test + '/json-schema.json'); | ||
| const result = convert(schema, { cloneSchema: false }); | ||
| const expected = getSchema(test + '/openapi.json'); | ||
| should(schema).deepEqual(result, 'changed schema in place'); | ||
| should(result).deepEqual(expected, 'converted'); | ||
| }); | ||
| }); |
| const fs = require('fs'); | ||
| const join = require('path').join; | ||
| const getSchema = file => { | ||
| const path = join(__dirname, 'schemas', file); | ||
| return JSON.parse(fs.readFileSync(path)); | ||
| }; | ||
| module.exports = { getSchema }; |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| const getSchema = require('./helpers').getSchema; | ||
| it('dateTime is invalid type', () => { | ||
| const schema = { type: 'dateTime' }; | ||
| should.throws(() => { convert(schema); }, /InvalidTypeError/); | ||
| }); | ||
| it('foo is invalid type', () => { | ||
| const schema = { type: 'foo' }; | ||
| should.throws(() => { convert(schema); }, /InvalidTypeError/); | ||
| }); | ||
| it('invalid type inside complex schema', () => { | ||
| const schema = getSchema('invalid/json-schema.json'); | ||
| should.throws(() => { convert(schema); }, /InvalidTypeError.*invalidtype/); | ||
| }); |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| it('items', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: 'array', | ||
| items: { | ||
| type: 'string', | ||
| format: 'date-time', | ||
| example: '2017-01-01T12:34:56Z' | ||
| } | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'array', | ||
| items: { | ||
| type: 'string', | ||
| format: 'date-time', | ||
| example: '2017-01-01T12:34:56Z' | ||
| } | ||
| }; | ||
| should(result).deepEqual(expected, 'converted'); | ||
| }); |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| it('adds `nullable: true` for `type: [string, null]`', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: ['string', 'null'], | ||
| }; | ||
| const result = convert(schema); | ||
| should(result).deepEqual({ | ||
| type: 'string', | ||
| nullable: true | ||
| }); | ||
| }); | ||
| it('does not add nullable for non null types', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: 'string' | ||
| }; | ||
| const result = convert(schema); | ||
| should(result).deepEqual({ | ||
| type: 'string' | ||
| }); | ||
| }); |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| it('renames patternProperties to x-patternProperties', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: 'object', | ||
| additionalProperties: { | ||
| type: 'string' | ||
| }, | ||
| patternProperties: { | ||
| '^[a-z]*$': { | ||
| type: 'string' | ||
| } | ||
| } | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'object', | ||
| additionalProperties: { | ||
| type: 'string' | ||
| }, | ||
| 'x-patternProperties': { | ||
| '^[a-z]*$': { | ||
| type: 'string' | ||
| } | ||
| } | ||
| }; | ||
| should(result).deepEqual(expected); | ||
| }); |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| it('type array', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: ['string', 'null'] | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'string', | ||
| nullable: true | ||
| }; | ||
| should(result).deepEqual(expected); | ||
| }); | ||
| it('properties', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: 'object', | ||
| required: ['bar'], | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| }, | ||
| bar: { | ||
| type: ['string', 'null'] | ||
| } | ||
| } | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'object', | ||
| required: ['bar'], | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| }, | ||
| bar: { | ||
| type: 'string', | ||
| nullable: true | ||
| } | ||
| } | ||
| }; | ||
| should(result).deepEqual(expected); | ||
| }); | ||
| it('addionalProperties is false', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| } | ||
| }, | ||
| additionalProperties: false | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| } | ||
| }, | ||
| additionalProperties: false | ||
| }; | ||
| should(result).deepEqual(expected, 'properties converted'); | ||
| }); | ||
| it('addionalProperties is true', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| } | ||
| }, | ||
| additionalProperties: true | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| } | ||
| }, | ||
| additionalProperties: true | ||
| }; | ||
| should(result).deepEqual(expected); | ||
| }); | ||
| it('addionalProperties is an object', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| } | ||
| }, | ||
| additionalProperties: { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| format: 'date-time' | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string' | ||
| } | ||
| }, | ||
| additionalProperties: { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| format: 'date-time' | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| should(result).deepEqual(expected, 'properties and additionalProperties converted'); | ||
| }); |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| it('maintain readOnly and writeOnly props', () => { | ||
| const schema = { | ||
| type: 'object', | ||
| properties: { | ||
| prop1: { | ||
| type: 'string', | ||
| readOnly: true | ||
| }, | ||
| prop2: { | ||
| type: 'string', | ||
| writeOnly: true | ||
| } | ||
| } | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'object', | ||
| properties: { | ||
| prop1: { | ||
| type: 'string', | ||
| readOnly: true | ||
| }, | ||
| prop2: { | ||
| type: 'string', | ||
| writeOnly: true | ||
| } | ||
| } | ||
| }; | ||
| should(result).deepEqual(expected); | ||
| }); | ||
| it('deep schema', () => { | ||
| const schema = { | ||
| type: 'object', | ||
| required: ['prop1', 'prop2'], | ||
| properties: { | ||
| prop1: { | ||
| type: 'string', | ||
| readOnly: true | ||
| }, | ||
| prop2: { | ||
| allOf: [ | ||
| { | ||
| type: 'object', | ||
| required: ['prop3'], | ||
| properties: { | ||
| prop3: { | ||
| type: 'object', | ||
| readOnly: true | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| prop4: { | ||
| type: 'object', | ||
| readOnly: true | ||
| } | ||
| } | ||
| }, | ||
| ] | ||
| } | ||
| } | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'object', | ||
| required: ['prop1', 'prop2'], | ||
| properties: { | ||
| prop1: { | ||
| type: 'string', | ||
| readOnly: true | ||
| }, | ||
| prop2: { | ||
| allOf: [ | ||
| { | ||
| type: 'object', | ||
| required: ['prop3'], | ||
| properties: { | ||
| prop3: { | ||
| type: 'object', | ||
| readOnly: true | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| prop4: { | ||
| type: 'object', | ||
| readOnly: true | ||
| } | ||
| } | ||
| }, | ||
| ] | ||
| } | ||
| } | ||
| }; | ||
| should(result).deepEqual(expected); | ||
| }); |
| { | ||
| "$schema": "http://json-schema.org/draft-06/schema#", | ||
| "description": "An Address following the convention of http://microformats.org/wiki/hcard", | ||
| "type": "object", | ||
| "properties": { | ||
| "post-office-box": { "type": "string" }, | ||
| "extended-address": { "type": "string" }, | ||
| "street-address": { "type": "string" }, | ||
| "locality":{ "type": "string" }, | ||
| "region": { "type": "string" }, | ||
| "postal-code": { "type": "string" }, | ||
| "country-name": { "type": "string"} | ||
| }, | ||
| "required": ["locality", "region", "country-name"], | ||
| "dependencies": { | ||
| "post-office-box": ["street-address"], | ||
| "extended-address": ["street-address"] | ||
| } | ||
| } |
| { | ||
| "description": "An Address following the convention of http://microformats.org/wiki/hcard", | ||
| "type": "object", | ||
| "properties": { | ||
| "post-office-box": { "type": "string" }, | ||
| "extended-address": { "type": "string" }, | ||
| "street-address": { "type": "string" }, | ||
| "locality":{ "type": "string" }, | ||
| "region": { "type": "string" }, | ||
| "postal-code": { "type": "string" }, | ||
| "country-name": { "type": "string"} | ||
| }, | ||
| "required": ["locality", "region", "country-name"], | ||
| "allOf": [ | ||
| { | ||
| "oneOf": [ | ||
| {"not": {"required": ["post-office-box"]}}, | ||
| {"required": ["post-office-box", "street-address"]} | ||
| ] | ||
| }, | ||
| { | ||
| "oneOf": [ | ||
| {"not": {"required": ["extended-address"]}}, | ||
| {"required": ["extended-address", "street-address"]} | ||
| ] | ||
| } | ||
| ] | ||
| } |
| { | ||
| "$schema": "http://json-schema.org/draft-04/schema#", | ||
| "allOf": [ | ||
| { | ||
| "anyOf": [ | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "cats": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "integer", | ||
| "format": "int64", | ||
| "example": [ | ||
| 1 | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "dogs": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "integer", | ||
| "format": "int64", | ||
| "example": [ | ||
| 1 | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "bring_cats": { | ||
| "type": "array", | ||
| "items": { | ||
| "allOf": [ | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "email": { | ||
| "type": "string", | ||
| "example": "cats@email.com" | ||
| }, | ||
| "sms": { | ||
| "type": [ | ||
| "string", | ||
| "null" | ||
| ], | ||
| "example": "+12345678" | ||
| }, | ||
| "properties": { | ||
| "type": "object", | ||
| "additionalProperties": { | ||
| "type": "string" | ||
| }, | ||
| "example": { | ||
| "name": "Wookie" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "required": [ | ||
| "email" | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "playground": { | ||
| "type": "object", | ||
| "required": [ | ||
| "feeling", | ||
| "child" | ||
| ], | ||
| "properties": { | ||
| "feeling": { | ||
| "type": "string", | ||
| "example": "Good feeling" | ||
| }, | ||
| "child": { | ||
| "type": "object", | ||
| "required": [ | ||
| "name", | ||
| "age" | ||
| ], | ||
| "properties": { | ||
| "name": { | ||
| "type": "string", | ||
| "example": "Steven" | ||
| }, | ||
| "age": { | ||
| "type": "integer", | ||
| "example": 5 | ||
| } | ||
| } | ||
| }, | ||
| "toy": { | ||
| "type": "object", | ||
| "properties": { | ||
| "breaks_easily": { | ||
| "type": "boolean", | ||
| "default": false | ||
| }, | ||
| "color": { | ||
| "type": "string", | ||
| "description": "Color of the toy" | ||
| }, | ||
| "type": { | ||
| "type": "string", | ||
| "enum": ["bucket", "shovel"], | ||
| "description": "Toy type" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } |
| { | ||
| "allOf": [ | ||
| { | ||
| "anyOf": [ | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "cats": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "integer", | ||
| "format": "int64", | ||
| "example": [ | ||
| 1 | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "dogs": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "integer", | ||
| "format": "int64", | ||
| "example": [ | ||
| 1 | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "bring_cats": { | ||
| "type": "array", | ||
| "items": { | ||
| "allOf": [ | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "email": { | ||
| "type": "string", | ||
| "example": "cats@email.com" | ||
| }, | ||
| "sms": { | ||
| "type": "string", | ||
| "nullable": true, | ||
| "example": "+12345678" | ||
| }, | ||
| "properties": { | ||
| "type": "object", | ||
| "additionalProperties": { | ||
| "type": "string" | ||
| }, | ||
| "example": { | ||
| "name": "Wookie" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "required": [ | ||
| "email" | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "playground": { | ||
| "type": "object", | ||
| "required": [ | ||
| "feeling", | ||
| "child" | ||
| ], | ||
| "properties": { | ||
| "feeling": { | ||
| "type": "string", | ||
| "example": "Good feeling" | ||
| }, | ||
| "child": { | ||
| "type": "object", | ||
| "required": [ | ||
| "name", | ||
| "age" | ||
| ], | ||
| "properties": { | ||
| "name": { | ||
| "type": "string", | ||
| "example": "Steven" | ||
| }, | ||
| "age": { | ||
| "type": "integer", | ||
| "example": 5 | ||
| } | ||
| } | ||
| }, | ||
| "toy": { | ||
| "type": "object", | ||
| "properties": { | ||
| "breaks_easily": { | ||
| "type": "boolean", | ||
| "default": false | ||
| }, | ||
| "color": { | ||
| "type": "string", | ||
| "description": "Color of the toy" | ||
| }, | ||
| "type": { | ||
| "type": "string", | ||
| "enum": ["bucket", "shovel"], | ||
| "description": "Toy type" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } |
| { | ||
| "$schema": "http://json-schema.org/draft-06/schema#", | ||
| "description": "A representation of an event", | ||
| "type": "object", | ||
| "required": [ "dtstart", "summary" ], | ||
| "properties": { | ||
| "dtstart": { | ||
| "format": "date-time", | ||
| "type": "string", | ||
| "description": "Event starting time" | ||
| }, | ||
| "dtend": { | ||
| "format": "date-time", | ||
| "type": "string", | ||
| "description": "Event ending time" | ||
| }, | ||
| "summary": { "type": "string" }, | ||
| "location": { "type": "string" }, | ||
| "url": { "type": "string", "format": "uri" }, | ||
| "duration": { | ||
| "format": "time", | ||
| "type": "string", | ||
| "description": "Event duration" | ||
| }, | ||
| "rdate": { | ||
| "format": "date-time", | ||
| "type": "string", | ||
| "description": "Recurrence date" | ||
| }, | ||
| "rrule": { | ||
| "type": "string", | ||
| "description": "Recurrence rule" | ||
| }, | ||
| "category": { "type": "string" }, | ||
| "description": { "type": "string" }, | ||
| "geo": { "$ref": "http://json-schema.org/geo" } | ||
| } | ||
| } |
| { | ||
| "description": "A representation of an event", | ||
| "type": "object", | ||
| "required": [ "dtstart", "summary" ], | ||
| "properties": { | ||
| "dtstart": { | ||
| "format": "date-time", | ||
| "type": "string", | ||
| "description": "Event starting time" | ||
| }, | ||
| "dtend": { | ||
| "format": "date-time", | ||
| "type": "string", | ||
| "description": "Event ending time" | ||
| }, | ||
| "summary": { "type": "string" }, | ||
| "location": { "type": "string" }, | ||
| "url": { "type": "string", "format": "uri" }, | ||
| "duration": { | ||
| "format": "time", | ||
| "type": "string", | ||
| "description": "Event duration" | ||
| }, | ||
| "rdate": { | ||
| "format": "date-time", | ||
| "type": "string", | ||
| "description": "Recurrence date" | ||
| }, | ||
| "rrule": { | ||
| "type": "string", | ||
| "description": "Recurrence rule" | ||
| }, | ||
| "category": { "type": "string" }, | ||
| "description": { "type": "string" }, | ||
| "geo": { "$ref": "http://json-schema.org/geo" } | ||
| } | ||
| } |
| { | ||
| "id": "http://some.site.somewhere/entry-schema#", | ||
| "$schema": "http://json-schema.org/draft-06/schema#", | ||
| "description": "schema for an fstab entry", | ||
| "type": "object", | ||
| "required": [ "storage" ], | ||
| "properties": { | ||
| "storage": { | ||
| "type": "object", | ||
| "oneOf": [ | ||
| { "$ref": "#/definitions/diskDevice" }, | ||
| { "$ref": "#/definitions/diskUUID" }, | ||
| { "$ref": "#/definitions/nfs" }, | ||
| { "$ref": "#/definitions/tmpfs" } | ||
| ] | ||
| }, | ||
| "fstype": { | ||
| "enum": [ "ext3", "ext4", "btrfs" ] | ||
| }, | ||
| "options": { | ||
| "type": "array", | ||
| "minItems": 1, | ||
| "items": { "type": "string" }, | ||
| "uniqueItems": true | ||
| }, | ||
| "readonly": { "type": "boolean" } | ||
| }, | ||
| "definitions": { | ||
| "diskDevice": { | ||
| "properties": { | ||
| "type": { "enum": [ "disk" ] }, | ||
| "device": { | ||
| "type": "string", | ||
| "pattern": "^/dev/[^/]+(/[^/]+)*$" | ||
| } | ||
| }, | ||
| "required": [ "type", "device" ], | ||
| "additionalProperties": false | ||
| }, | ||
| "diskUUID": { | ||
| "properties": { | ||
| "type": { "enum": [ "disk" ] }, | ||
| "label": { | ||
| "type": "string", | ||
| "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$" | ||
| } | ||
| }, | ||
| "required": [ "type", "label" ], | ||
| "additionalProperties": false | ||
| }, | ||
| "nfs": { | ||
| "properties": { | ||
| "type": { "enum": [ "nfs" ] }, | ||
| "remotePath": { | ||
| "type": "string", | ||
| "pattern": "^(/[^/]+)+$" | ||
| }, | ||
| "server": { | ||
| "type": "string", | ||
| "oneOf": [ | ||
| { "format": "hostname" }, | ||
| { "format": "ipv4" }, | ||
| { "format": "ipv6" } | ||
| ] | ||
| } | ||
| }, | ||
| "required": [ "type", "server", "remotePath" ], | ||
| "additionalProperties": false | ||
| }, | ||
| "tmpfs": { | ||
| "properties": { | ||
| "type": { "enum": [ "tmpfs" ] }, | ||
| "sizeInMB": { | ||
| "type": "integer", | ||
| "minimum": 16, | ||
| "maximum": 512 | ||
| } | ||
| }, | ||
| "required": [ "type", "sizeInMB" ], | ||
| "additionalProperties": false | ||
| } | ||
| } | ||
| } |
| { | ||
| "description": "schema for an fstab entry", | ||
| "type": "object", | ||
| "required": [ "storage" ], | ||
| "properties": { | ||
| "storage": { | ||
| "type": "object", | ||
| "oneOf": [ | ||
| { "$ref": "#/definitions/diskDevice" }, | ||
| { "$ref": "#/definitions/diskUUID" }, | ||
| { "$ref": "#/definitions/nfs" }, | ||
| { "$ref": "#/definitions/tmpfs" } | ||
| ] | ||
| }, | ||
| "fstype": { | ||
| "enum": [ "ext3", "ext4", "btrfs" ] | ||
| }, | ||
| "options": { | ||
| "type": "array", | ||
| "minItems": 1, | ||
| "items": { "type": "string" }, | ||
| "uniqueItems": true | ||
| }, | ||
| "readonly": { "type": "boolean" } | ||
| }, | ||
| "definitions": { | ||
| "diskDevice": { | ||
| "properties": { | ||
| "type": { "enum": [ "disk" ] }, | ||
| "device": { | ||
| "type": "string", | ||
| "pattern": "^/dev/[^/]+(/[^/]+)*$" | ||
| } | ||
| }, | ||
| "required": [ "type", "device" ], | ||
| "additionalProperties": false | ||
| }, | ||
| "diskUUID": { | ||
| "properties": { | ||
| "type": { "enum": [ "disk" ] }, | ||
| "label": { | ||
| "type": "string", | ||
| "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$" | ||
| } | ||
| }, | ||
| "required": [ "type", "label" ], | ||
| "additionalProperties": false | ||
| }, | ||
| "nfs": { | ||
| "properties": { | ||
| "type": { "enum": [ "nfs" ] }, | ||
| "remotePath": { | ||
| "type": "string", | ||
| "pattern": "^(/[^/]+)+$" | ||
| }, | ||
| "server": { | ||
| "type": "string", | ||
| "oneOf": [ | ||
| { "format": "hostname" }, | ||
| { "format": "ipv4" }, | ||
| { "format": "ipv6" } | ||
| ] | ||
| } | ||
| }, | ||
| "required": [ "type", "server", "remotePath" ], | ||
| "additionalProperties": false | ||
| }, | ||
| "tmpfs": { | ||
| "properties": { | ||
| "type": { "enum": [ "tmpfs" ] }, | ||
| "sizeInMB": { | ||
| "type": "integer", | ||
| "minimum": 16, | ||
| "maximum": 512 | ||
| } | ||
| }, | ||
| "required": [ "type", "sizeInMB" ], | ||
| "additionalProperties": false | ||
| } | ||
| } | ||
| } |
| { | ||
| "allOf": [ | ||
| { | ||
| "anyOf": [ | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "cats": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "integer", | ||
| "format": "int64", | ||
| "example": [ | ||
| 1 | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "dogs": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "integer", | ||
| "format": "int64", | ||
| "example": [ | ||
| 1 | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "bring_cats": { | ||
| "type": "array", | ||
| "items": { | ||
| "allOf": [ | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "email": { | ||
| "type": "string", | ||
| "example": "cats@email.com" | ||
| }, | ||
| "sms": { | ||
| "type": "string", | ||
| "nullable": true, | ||
| "example": "+12345678" | ||
| }, | ||
| "properties": { | ||
| "type": "object", | ||
| "additionalProperties": { | ||
| "type": "invalidtype" | ||
| }, | ||
| "example": { | ||
| "name": "Wookie" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "required": [ | ||
| "email" | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "playground": { | ||
| "type": "object", | ||
| "required": [ | ||
| "feeling", | ||
| "child" | ||
| ], | ||
| "properties": { | ||
| "feeling": { | ||
| "type": "string", | ||
| "example": "Good feeling" | ||
| }, | ||
| "child": { | ||
| "type": "object", | ||
| "required": [ | ||
| "name", | ||
| "age" | ||
| ], | ||
| "properties": { | ||
| "name": { | ||
| "type": "string", | ||
| "example": "Steven" | ||
| }, | ||
| "age": { | ||
| "type": "integer", | ||
| "example": 5 | ||
| } | ||
| } | ||
| }, | ||
| "toy": { | ||
| "type": "object", | ||
| "properties": { | ||
| "breaks_easily": { | ||
| "type": "boolean", | ||
| "default": false | ||
| }, | ||
| "color": { | ||
| "type": "string", | ||
| "description": "Color of the toy" | ||
| }, | ||
| "type": { | ||
| "type": "string", | ||
| "enum": ["bucket", "shovel"], | ||
| "description": "Toy type" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } |
+74
-5
| const structs = ['allOf', 'anyOf', 'oneOf', 'not', 'items', 'additionalProperties']; | ||
| function InvalidTypeError(message) { | ||
| this.name = 'InvalidTypeError'; | ||
| this.message = message; | ||
| } | ||
| InvalidTypeError.prototype = new Error(); | ||
| function convert(schema, options) { | ||
@@ -11,3 +18,3 @@ options = options || {}; | ||
| delete schema['$schema']; | ||
| schema = removeRootKeywords(schema); | ||
| schema = convertSchema(schema); | ||
@@ -18,2 +25,8 @@ | ||
| function removeRootKeywords(schema) { | ||
| delete schema['$schema']; | ||
| delete schema['id']; | ||
| return schema; | ||
| } | ||
| function convertSchema(schema) { | ||
@@ -52,3 +65,6 @@ let i = 0; | ||
| validateType(schema.type); | ||
| schema = convertTypes(schema); | ||
| schema = convertDependencies(schema); | ||
@@ -62,7 +78,15 @@ if (typeof schema['patternProperties'] === 'object') { | ||
| function validateType(type) { | ||
| const validTypes = ['null', 'boolean', 'object', 'array', 'number', 'string', 'integer']; | ||
| const types = Array.isArray(type) ? type : [type]; | ||
| types.forEach(type => { | ||
| if (validTypes.indexOf(type) < 0 && type !== undefined) | ||
| throw new InvalidTypeError('Type "' + type + '" is not a valid type'); | ||
| }); | ||
| } | ||
| function convertProperties(properties) { | ||
| var key | ||
| , property | ||
| , props = {} | ||
| ; | ||
| let key = {}; | ||
| let property = {}; | ||
| let props = {}; | ||
@@ -77,2 +101,47 @@ for (key in properties) { | ||
| function convertDependencies(schema) { | ||
| const deps = schema.dependencies; | ||
| if (typeof deps !== 'object') { | ||
| return schema; | ||
| } | ||
| // Turns the dependencies keyword into an allOf of oneOf's | ||
| // "dependencies": { | ||
| // "post-office-box": ["street-address"] | ||
| // }, | ||
| // | ||
| // becomes | ||
| // | ||
| // "allOf": [ | ||
| // { | ||
| // "oneOf": [ | ||
| // {"not": {"required": ["post-office-box"]}}, | ||
| // {"required": ["post-office-box", "street-address"]} | ||
| // ] | ||
| // } | ||
| // | ||
| delete schema['dependencies']; | ||
| if (!Array.isArray(schema.allOf)) { | ||
| schema.allOf = []; | ||
| } | ||
| for (const key in deps) { | ||
| const foo = { | ||
| 'oneOf': [ | ||
| { | ||
| 'not': { | ||
| 'required': [key] | ||
| } | ||
| }, | ||
| { | ||
| 'required': [].concat(key, deps[key]) | ||
| } | ||
| ] | ||
| }; | ||
| schema.allOf.push(foo); | ||
| } | ||
| return schema; | ||
| } | ||
| function convertTypes(schema) { | ||
@@ -79,0 +148,0 @@ var newType; |
+1
-1
| { | ||
| "name": "json-schema-to-openapi-schema", | ||
| "version": "0.1.0", | ||
| "version": "0.1.1", | ||
| "description": "Converts a JSON Schema to OpenAPI Schema Object", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
+3
-2
@@ -1,2 +0,2 @@ | ||
| # OpenAPI Schema to JSON Schema | ||
| # JSON Schema to OpenAPI Schema | ||
@@ -10,3 +10,4 @@ A little NodeJS package to convert JSON Schema to [OpenAPI Schema Objects](https://swagger.io/specification/#schemaObject). | ||
| * supports deep structures with nested `allOf`s etc. | ||
| * switches `patternProperties` to `x-patternProperties` in the Schema Object | ||
| * switches `patternProperties` to `x-patternProperties` | ||
| * converts `dependencies` to an allOf + oneOf OpenAPI-valid equivalent | ||
@@ -13,0 +14,0 @@ ## Installation |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| it('cloning schema by default', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: ['string', 'null'], | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'string', | ||
| nullable: true, | ||
| }; | ||
| should(result).deepEqual(expected, 'result does not match the expected'); | ||
| should(result).not.deepEqual(schema, 'the schema was modified in place'); | ||
| }); | ||
| it('cloning schema with cloneSchema option', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: ['string', 'null'], | ||
| }; | ||
| const result = convert(schema, { cloneSchema: true }); | ||
| const expected = { | ||
| type: 'string', | ||
| nullable: true, | ||
| }; | ||
| should(result).deepEqual(expected, 'result does not match the expected'); | ||
| should(result).not.deepEqual(schema, 'the schema was modified in place'); | ||
| }); | ||
| it('direct schema modification', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: ['string', 'null'], | ||
| }; | ||
| const result = convert(schema, { cloneSchema: false }); | ||
| const expected = { | ||
| type: 'string', | ||
| nullable: true, | ||
| }; | ||
| should(result).deepEqual(expected, 'result does not match the expected'); | ||
| should(result).deepEqual(schema, 'the schema was not modified in place'); | ||
| }); |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| it('iterates allOfs and converts types', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| allOf: [ | ||
| { | ||
| type: 'object', | ||
| required: ['foo'], | ||
| properties: { | ||
| foo: { | ||
| type: 'integer', | ||
| format: 'int64' | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| allOf: [ | ||
| { | ||
| type: 'number', | ||
| format: 'double' | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| allOf: [ | ||
| { | ||
| type: 'object', | ||
| required: ['foo'], | ||
| properties: { | ||
| foo: { | ||
| type: 'integer', | ||
| format: 'int64' | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| allOf: [ | ||
| { | ||
| type: 'number', | ||
| format: 'double' | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| }; | ||
| should(result).deepEqual(expected, 'iterated allOfs'); | ||
| }); | ||
| it('iterates anyOfs and converts types', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| anyOf: [ | ||
| { | ||
| type: 'object', | ||
| required: ['foo'], | ||
| properties: { | ||
| foo: { | ||
| type: 'integer', | ||
| format: 'int64' | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| anyOf: [ | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| bar: { | ||
| type: 'number', | ||
| format: 'double' | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| anyOf: [ | ||
| { | ||
| type: 'object', | ||
| required: ['foo'], | ||
| properties: { | ||
| foo: { | ||
| type: 'integer', | ||
| format: 'int64' | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| anyOf: [ | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| bar: { | ||
| type: 'number', | ||
| format: 'double' | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| }; | ||
| should(result).deepEqual(expected, 'anyOfs iterated'); | ||
| }); | ||
| it('iterates oneOfs and converts types', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| oneOf: [ | ||
| { | ||
| type: 'object', | ||
| required: ['foo'], | ||
| properties: { | ||
| foo: { | ||
| type: ['string', 'null'] | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| oneOf: [ | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| bar: { | ||
| type: ['string', 'null'] | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| oneOf: [ | ||
| { | ||
| type: 'object', | ||
| required: ['foo'], | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| nullable: true | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| oneOf: [ | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| bar: { | ||
| type: 'string', | ||
| nullable: true | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| }; | ||
| should(result).deepEqual(expected, 'oneOfs iterated'); | ||
| }); | ||
| it('converts types in not', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: 'object', | ||
| properties: { | ||
| not: { | ||
| type: ['string', 'null'], | ||
| minLength: 8 | ||
| } | ||
| } | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'object', | ||
| properties: { | ||
| not: { | ||
| type: 'string', | ||
| nullable: true, | ||
| minLength: 8 | ||
| } | ||
| } | ||
| }; | ||
| should(result).deepEqual(expected, 'not handled'); | ||
| }); | ||
| it('nested combination keywords', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| anyOf: [ | ||
| { | ||
| allOf: [ | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: ['string', 'null'] | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| bar: { | ||
| type: ['integer', 'null'] | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| not: { | ||
| type: 'string', | ||
| example: 'foobar' | ||
| } | ||
| } | ||
| ] | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| anyOf: [ | ||
| { | ||
| allOf: [ | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| nullable: true | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| bar: { | ||
| type: 'integer', | ||
| nullable: true | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| not: { | ||
| type: 'string', | ||
| example: 'foobar' | ||
| } | ||
| } | ||
| ] | ||
| }; | ||
| should(result).deepEqual(expected, 'nested combination keywords'); | ||
| }); |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| const fs = require('fs'); | ||
| const join = require('path').join; | ||
| it('complex schema', () => { | ||
| const schema = getSchema('json-schema-expected.json'); | ||
| const result = convert(schema); | ||
| const expected = getSchema('openapi-schema.json'); | ||
| should(result).deepEqual(expected, 'converted'); | ||
| }); | ||
| it('converting complex schema in place', () => { | ||
| const schema = getSchema('json-schema-expected.json'); | ||
| const result = convert(schema, { cloneSchema: false }); | ||
| const expected = getSchema('openapi-schema.json'); | ||
| should(schema).deepEqual(result, 'changed schema in place'); | ||
| should(result).deepEqual(expected, 'converted'); | ||
| }); | ||
| function getSchema(file) { | ||
| const path = join(__dirname, 'schemas', file); | ||
| return JSON.parse(fs.readFileSync(path)); | ||
| } |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| it('items', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: 'array', | ||
| items: { | ||
| type: 'string', | ||
| format: 'date-time', | ||
| example: '2017-01-01T12:34:56Z' | ||
| } | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'array', | ||
| items: { | ||
| type: 'string', | ||
| format: 'date-time', | ||
| example: '2017-01-01T12:34:56Z' | ||
| } | ||
| }; | ||
| should(result).deepEqual(expected, 'converted'); | ||
| }); |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| it('adds `nullable: true` for `type: [string, null]`', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: ['string', 'null'], | ||
| }; | ||
| const result = convert(schema); | ||
| should(result).deepEqual({ | ||
| type: 'string', | ||
| nullable: true | ||
| }); | ||
| }); | ||
| it('does not add nullable for non null types', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: 'string' | ||
| }; | ||
| const result = convert(schema); | ||
| should(result).deepEqual({ | ||
| type: 'string' | ||
| }); | ||
| }); |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| it('renames patternProperties to x-patternProperties', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: 'object', | ||
| additionalProperties: { | ||
| type: 'string' | ||
| }, | ||
| patternProperties: { | ||
| '^[a-z]*$': { | ||
| type: 'string' | ||
| } | ||
| } | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'object', | ||
| additionalProperties: { | ||
| type: 'string' | ||
| }, | ||
| 'x-patternProperties': { | ||
| '^[a-z]*$': { | ||
| type: 'string' | ||
| } | ||
| } | ||
| }; | ||
| should(result).deepEqual(expected); | ||
| }); |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| it('type array', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: ['string', 'null'] | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'string', | ||
| nullable: true | ||
| }; | ||
| should(result).deepEqual(expected); | ||
| }); | ||
| it('properties', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: 'object', | ||
| required: ['bar'], | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| }, | ||
| bar: { | ||
| type: ['string', 'null'] | ||
| } | ||
| } | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'object', | ||
| required: ['bar'], | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| }, | ||
| bar: { | ||
| type: 'string', | ||
| nullable: true | ||
| } | ||
| } | ||
| }; | ||
| should(result).deepEqual(expected); | ||
| }); | ||
| it('addionalProperties is false', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| } | ||
| }, | ||
| additionalProperties: false | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| } | ||
| }, | ||
| additionalProperties: false | ||
| }; | ||
| should(result).deepEqual(expected, 'properties converted'); | ||
| }); | ||
| it('addionalProperties is true', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| } | ||
| }, | ||
| additionalProperties: true | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| } | ||
| }, | ||
| additionalProperties: true | ||
| }; | ||
| should(result).deepEqual(expected); | ||
| }); | ||
| it('addionalProperties is an object', () => { | ||
| const schema = { | ||
| $schema: 'http://json-schema.org/draft-04/schema#', | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| } | ||
| }, | ||
| additionalProperties: { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| format: 'date-time' | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string' | ||
| } | ||
| }, | ||
| additionalProperties: { | ||
| type: 'object', | ||
| properties: { | ||
| foo: { | ||
| type: 'string', | ||
| format: 'date-time' | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| should(result).deepEqual(expected, 'properties and additionalProperties converted'); | ||
| }); |
| 'use strict'; | ||
| const convert = require('../'); | ||
| const should = require('should'); | ||
| it('maintain readOnly and writeOnly props', () => { | ||
| const schema = { | ||
| type: 'object', | ||
| properties: { | ||
| prop1: { | ||
| type: 'string', | ||
| readOnly: true | ||
| }, | ||
| prop2: { | ||
| type: 'string', | ||
| writeOnly: true | ||
| } | ||
| } | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'object', | ||
| properties: { | ||
| prop1: { | ||
| type: 'string', | ||
| readOnly: true | ||
| }, | ||
| prop2: { | ||
| type: 'string', | ||
| writeOnly: true | ||
| } | ||
| } | ||
| }; | ||
| should(result).deepEqual(expected); | ||
| }); | ||
| it('deep schema', () => { | ||
| const schema = { | ||
| type: 'object', | ||
| required: ['prop1', 'prop2'], | ||
| properties: { | ||
| prop1: { | ||
| type: 'string', | ||
| readOnly: true | ||
| }, | ||
| prop2: { | ||
| allOf: [ | ||
| { | ||
| type: 'object', | ||
| required: ['prop3'], | ||
| properties: { | ||
| prop3: { | ||
| type: 'object', | ||
| readOnly: true | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| prop4: { | ||
| type: 'object', | ||
| readOnly: true | ||
| } | ||
| } | ||
| }, | ||
| ] | ||
| } | ||
| } | ||
| }; | ||
| const result = convert(schema); | ||
| const expected = { | ||
| type: 'object', | ||
| required: ['prop1', 'prop2'], | ||
| properties: { | ||
| prop1: { | ||
| type: 'string', | ||
| readOnly: true | ||
| }, | ||
| prop2: { | ||
| allOf: [ | ||
| { | ||
| type: 'object', | ||
| required: ['prop3'], | ||
| properties: { | ||
| prop3: { | ||
| type: 'object', | ||
| readOnly: true | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| prop4: { | ||
| type: 'object', | ||
| readOnly: true | ||
| } | ||
| } | ||
| }, | ||
| ] | ||
| } | ||
| } | ||
| }; | ||
| should(result).deepEqual(expected); | ||
| }); |
| { | ||
| "$schema": "http://json-schema.org/draft-04/schema#", | ||
| "allOf": [ | ||
| { | ||
| "anyOf": [ | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "cats": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "integer", | ||
| "format": "int64", | ||
| "example": [ | ||
| 1 | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "dogs": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "integer", | ||
| "format": "int64", | ||
| "example": [ | ||
| 1 | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "bring_cats": { | ||
| "type": "array", | ||
| "items": { | ||
| "allOf": [ | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "email": { | ||
| "type": "string", | ||
| "example": "cats@email.com" | ||
| }, | ||
| "sms": { | ||
| "type": [ | ||
| "string", | ||
| "null" | ||
| ], | ||
| "example": "+12345678" | ||
| }, | ||
| "properties": { | ||
| "type": "object", | ||
| "additionalProperties": { | ||
| "type": "string" | ||
| }, | ||
| "example": { | ||
| "name": "Wookie" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "required": [ | ||
| "email" | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "playground": { | ||
| "type": "object", | ||
| "required": [ | ||
| "feeling", | ||
| "child" | ||
| ], | ||
| "properties": { | ||
| "feeling": { | ||
| "type": "string", | ||
| "example": "Good feeling" | ||
| }, | ||
| "child": { | ||
| "type": "object", | ||
| "required": [ | ||
| "name", | ||
| "age" | ||
| ], | ||
| "properties": { | ||
| "name": { | ||
| "type": "string", | ||
| "example": "Steven" | ||
| }, | ||
| "age": { | ||
| "type": "integer", | ||
| "example": 5 | ||
| } | ||
| } | ||
| }, | ||
| "toy": { | ||
| "type": "object", | ||
| "properties": { | ||
| "breaks_easily": { | ||
| "type": "boolean", | ||
| "default": false | ||
| }, | ||
| "color": { | ||
| "type": "string", | ||
| "description": "Color of the toy" | ||
| }, | ||
| "type": { | ||
| "type": "string", | ||
| "enum": ["bucket", "shovel"], | ||
| "description": "Toy type" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } |
| { | ||
| "allOf": [ | ||
| { | ||
| "anyOf": [ | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "cats": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "integer", | ||
| "format": "int64", | ||
| "example": [ | ||
| 1 | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "dogs": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "integer", | ||
| "format": "int64", | ||
| "example": [ | ||
| 1 | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "bring_cats": { | ||
| "type": "array", | ||
| "items": { | ||
| "allOf": [ | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "email": { | ||
| "type": "string", | ||
| "example": "cats@email.com" | ||
| }, | ||
| "sms": { | ||
| "type": "string", | ||
| "nullable": true, | ||
| "example": "+12345678" | ||
| }, | ||
| "properties": { | ||
| "type": "object", | ||
| "additionalProperties": { | ||
| "type": "string" | ||
| }, | ||
| "example": { | ||
| "name": "Wookie" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "required": [ | ||
| "email" | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "playground": { | ||
| "type": "object", | ||
| "required": [ | ||
| "feeling", | ||
| "child" | ||
| ], | ||
| "properties": { | ||
| "feeling": { | ||
| "type": "string", | ||
| "example": "Good feeling" | ||
| }, | ||
| "child": { | ||
| "type": "object", | ||
| "required": [ | ||
| "name", | ||
| "age" | ||
| ], | ||
| "properties": { | ||
| "name": { | ||
| "type": "string", | ||
| "example": "Steven" | ||
| }, | ||
| "age": { | ||
| "type": "integer", | ||
| "example": 5 | ||
| } | ||
| } | ||
| }, | ||
| "toy": { | ||
| "type": "object", | ||
| "properties": { | ||
| "breaks_easily": { | ||
| "type": "boolean", | ||
| "default": false | ||
| }, | ||
| "color": { | ||
| "type": "string", | ||
| "description": "Color of the toy" | ||
| }, | ||
| "type": { | ||
| "type": "string", | ||
| "enum": ["bucket", "shovel"], | ||
| "description": "Toy type" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
40780
56.73%24
71.43%1540
47.65%101
1%1
Infinity%