Giter Site home page Giter Site logo

wework / json-schema-to-openapi-schema Goto Github PK

View Code? Open in Web Editor NEW
214.0 21.0 44.0 108 KB

A little NodeJS package to convert JSON Schema to OpenAPI Schema Objects

JavaScript 100.00%
json-schema openapi openapi-schema api api-documentation api-documentation-tool api-specs

json-schema-to-openapi-schema's Introduction

JSON Schema to OpenAPI Schema

A little NodeJS package to convert JSON Schema to OpenAPI Schema Objects.

Features

  • converts JSON Schema Draft 00 Wright (a.k.a draft v5) to OpenAPI 3.0 Schema Object
  • switches type: ['foo', 'null'] to type: foo and nullable: true
  • supports deep structures with nested allOfs etc.
  • switches patternProperties to x-patternProperties
  • converts dependencies to an allOf + oneOf OpenAPI-valid equivalent

Installation

npm install --save json-schema-to-openapi-schema

Usage

Here's a small example to get the idea:

const toOpenApi = require('json-schema-to-openapi-schema');

const schema = {
  '$schema': 'http://json-schema.org/draft-04/schema#',
  type: ['string', 'null'],
  format: 'date-time',
};

const convertedSchema = toOpenApi(schema);

console.log(convertedSchema);

The example prints out

{
  type: 'string',
  format: 'date-time',
  nullable: true
}

NOTE: $refs are not dereferenced. Use a dereferencer such as json-schema-ref-parser prior to using this package.

Options

The function accepts options object as the second argument.

cloneSchema (boolean)

If set to false, converts the provided schema in place. If true, clones the schema by converting it to JSON and back. The overhead of the cloning is usually negligible. Defaults to true.

Why?

OpenAPI is often described as an extension of JSON Schema, but both specs have changed over time and grown independently. OpenAPI v2 was based on JSON Schema draft v4 with a long list of deviations, but OpenAPI v3 shrank that list, upping their support to draft v4 and making the list of discrepancies shorter. Despite OpenAPI v3 closing the gap, the issue of JSON Schema divergence has not been resolved fully.

Diagram showing data model (the objects, payload bodies, etc) and service model (endpoints, headers, metadata, etc)

Carefully writing JSON Schema for your data model kiiiinda works, but it is possible to write JSON Schema that creates invalid OpenAPI, and vice versa. For more on this, read the article OpenAPI and JSON Schema Divergence.

This tool sets out to allow folks to convert from JSON Schema (their one source of truth for everything) to OpenAPI (a thing for HTML docs and making SDKs).

Versions

โ€  Draft v5 is also known as Draft Wright 00, as the drafts are often named after the author, and this was the first one by A. Wright. Amongst other things, draft v5 aimed to rewrite the meta files, but the experiment failed, meaning we need to continue to use the draft v4 metafiles. Ugh.

TODO

Converting Back

To convert the other way, check out openapi-schema-to-json-schema, which this package was based on.

Tests

To run the test-suite:

npm test

Credits

json-schema-to-openapi-schema's People

Contributors

dangoosby avatar mikeralphson avatar mikunn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

json-schema-to-openapi-schema's Issues

Add GitHub releases

It is helpful to follow this repository with a RSS reader.

This is automatically done by using git tag and git push --tags.

Remove $id from subschemas too

{
    "$id": "https://foo/bla",
    "$schema": "http://json-schema.org/draft-06/schema#",
    "type": "object",
    "properties": {
      "geogroupings": {
        "$id": "/properties/geogroupings",
        "type": "array",
        "items": {
          "$id": "/properties/geogroupings/items",
          "type": "object",
          "properties": {
            "id": {
              "$id": "/properties/geogroupings/items/properties/id",
              "type": "string",
              "title": "The Id Schema ",
              "default": ""
            }
        }
    }
}

Type ["null", "foo"] not converted correctly in "$ref"

I am trying to find a workaround for #26. This time, I tried creating a "nullable_schema" with type=["null", "object"] and then extending it in a different schema with type="object".

Input

{
    "allOf": [{"$ref": "#/nullable_schema"}, {"type": "object"}],
    "nullable_schema": {
        "type": ["null", "object"],
        "properties": {
            "my_string": {
                "type": "string"
            }
        },
        "required": ["my_string"],
        "additionalProperties": false
    }
}

I expected the output to be somehow like this. The extended schema was supposed to be left untouched and in the nullable schema the "type": "null" should have been casted to "nullable": true.

Expected Output

{
  "allOf": [
    {
      "$ref": "#/nullable_schema"
    },
    {
      "type": "object"
    }
  ],
  "nullable_schema": {
    "type": "object",
    "properties": {
      "my_string": {
        "type": "string"
      }
    },
    "required": [
      "my_string"
    ],
    "additionalProperties": false,
    "nullable": true
  }
}

As opposed to #26, this time the script did not crash. However, in the actual output the "type": "null" was not resolved. It was still "type": ["null", "object"].

Actual Output

{
  "allOf": [
    {
      "$ref": "#/nullable_schema"
    },
    {
      "type": "object"
    }
  ],
  "nullable_schema": {
    "type": [
      "null",
      "object"
    ],
    "properties": {
      "my_string": {
        "type": "string"
      }
    },
    "required": [
      "my_string"
    ],
    "additionalProperties": false
  }
}

types in definitions are not converted

Hi,

Types are not converted if they are defined in the definitions field.

Simple example to reproduce :

const toOpenApi = require('json-schema-to-openapi-schema');
const { inspect } = require('util');

const successfulSchema = {
	$schema: 'http://json-schema.org/draft-04/schema#',
	type: 'object',
	properties: {
		issue: {
			type: ['string', 'null']
		}
	}
};

const failingSchema = {
	$schema: 'http://json-schema.org/draft-04/schema#',
	type: 'object',
	properties: {
		issue: { $ref: '#/definitions/issue' }
	},
	definitions: {
		issue: {
			type: ['string', 'null']
		}
	}
};

const successfullyConvertedSchema = toOpenApi(successfulSchema);
const failedConvertedSchema = toOpenApi(failingSchema);

console.log('SUCCESS');
console.log(inspect(successfullyConvertedSchema, { compact: false, depth: 3 }));
console.log('FAILURE');
console.log(inspect(failedConvertedSchema, { compact: false, depth: 3 }));

Expected result : failingSchema should be converted

Hugo

Expected object or boolean as schema, got string

I wanted to convert the JSON schema here, but I get an error message:

D:\Repos\swagger-editor\node_modules@cloudflare\json-schema-walker\lib\schemaWalk.js:92
throw 'Expected object or boolean as schema, got ' +
^
Expected object or boolean as schema, got string

Golang

Thanks for writing this library and the blog posts. I find myself needing a version of this library in Go. I wonder if you know anything about it. I did not find useful Googling.

Add licence to project

As of right now, I am unsure if I am allowed to use this (and under which circumstances I might be allowed to). Please consider adding a licence (whichever you feel is appropriate), so that users interested in this project know if they can use this or not.

Relies on an outdated library

This project current relies on an outdated version of @stoplight/json-ref-resolver (2.3.0) which, in turn, relies on a vulnerable version of immer. Provided nothing breaks, it should probably be upgraded to the latest version (3.1.1).

Does not convert "type: null" correctly in most common use case.

Written in yaml because json is exhausting

someObject: 
  type: object 
  property: 
    nullableProperty: 
      oneOf:
        - type: "null"
        - type: object 
          properties: 
            yay: 
              type: string 

Resulting output (Incorrect )

someObject: 
  type: object 
  property: 
    nullableProperty: 
      oneOf:
        - nullable: true
        - type: object 
          properties: 
            yay: 
              type: string 

Expected Output (correct)

someObject: 
  type: object 
  property: 
    nullableProperty: 
      type: object 
      nullable: true
      properties: 
        yay: 
          type: string 

While this will validate (loosely) against Swagger 3.0 specification, it will indeed break code generators.

Cannot convert type null with $ref

I am trying to convert a json schema that should either be null or a $ref to another object. In this case the reference is just a simple string but this could be arbitrarily complicated.

The design of the json schema follows the advice given here:

Input

{
    "anyOf": [
        {
            "$ref": "#/my_object"
        },
        {
            "type": "null"
        }
    ],
    "my_object": {
        "type": "string"
    }
}

I expected the output to be somewhat similar to this:

Expected Output

{
  "nullable": true,
  "$ref": "#/my_object",
  "my_object": {
    "type": "string"
  }
}

However, it actually caused the package to crash:

Error

Error
    at Object.<anonymous> ([...]/json-schema-to-openapi-schema/index.js:8:30)
    at Module._compile (internal/modules/cjs/loader.js:1158:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
    at Module.load (internal/modules/cjs/loader.js:1002:32)
    at Function.Module._load (internal/modules/cjs/loader.js:901:14)
    at Module.require (internal/modules/cjs/loader.js:1044:19)
    at require (internal/modules/cjs/helpers.js:77:18)
    at Object.<anonymous> ([...]/json-schema-to-openapi/index.js:3:19)
    at Module._compile (internal/modules/cjs/loader.js:1158:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10) {
  name: 'InvalidTypeError',
  message: 'Type "null" is not a valid type'
}

I believe this issue is similar to #21. However, in that case you could easily adjust the json schema using the "type": [] syntax. Here it is different. I guess the only alternative would be to make all referenced objects nullable, which I would like to avoid.

I believe this would be a great addition for converting rather complicated schemata. :)

issue with up and running

I have followed the steps mentioned in the index page to download the module on ubuntu.
after that I created a file test.js with

const toOpenApi = require('json-schema-to-openapi-schema');

const schema = {
  '$schema': 'http://json-schema.org/draft-04/schema#',
  type: ['string', 'null'],
  format: 'date-time',
};

const convertedSchema = toOpenApi(schema);

console.log(convertedSchema);

when I am trying to run as below.

nodejs test.js I am getting the below error.

/home/developer/json/node_modules/json-schema-to-openapi-schema/index.js:10
function convert(schema, options = {}) {
^

SyntaxError: Unexpected token =
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:374:25)
at Object.Module._extensions..js (module.js:417:10)
at Module.load (module.js:344:32)
at Function.Module._load (module.js:301:12)
at Module.require (module.js:354:17)
at require (internal/module.js:12:17)
at Object. (/home/developer/json/test.js:1:81)
at Module._compile (module.js:410:26)
at Object.Module._extensions..js (module.js:417:10)

Please help if I am missing anything.

Document that OpenAPI 2.0 is supported

This package actually also support OpenAPI 2.0.

Most of the OpenAPI ecosystem is (unfortunately) still stuck on 2.0 version, so documenting the fact this library supports it might be a good idea?

The differences are as follow:

  • OpenAPI 2.0-only:
    • type file
  • OpenAPI 3.0-only:
    • oneOf, anyOf and not (from JSON schema v4)
    • writeOnly (from JSON schema v7)
    • deprecated
    • nullable
  • OpenAPI 2.0/3.0 differences:
    • discriminator is a string (property name) in 2.0 and is { propertyName: string, mapping object } in 3.0

Support for converting patternProperties?

Hi! Great package! I'd like to know if there are plans to support JSON Schema draft-07.
I really dream abount converting ajv schemas to swagger specifications : )

JSON Schema - Definitions

Hi, does this routine support the definitions keyword as described in the JSON Schema documentation? Using json-schema-to-openapi-schema, converting a JSON Schema with a "definitions" property does not seem to handle nullable types properly (sending the individual interfaces to json-schema-to-openapi-schema works. Note that I am not using #refs.

Here is an example:

JSON Schema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "Product": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "price": {
          "type": "number"
        },
        "rating": {
          "type": [
            "null",
            "number"
          ]
        }
      },
      "required": [
        "name",
        "price",
        "rating"
      ]
    },
    "ProductList": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "version": {
          "type": "string"
        },
        "products": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "price": {
                "type": "number"
              },
              "rating": {
                "type": [
                  "null",
                  "number"
                ]
              }
            },
            "required": [
              "name",
              "price",
              "rating"
            ]
          }
        }
      },
      "required": [
        "name",
        "products",
        "version"
      ]
    }
  }
}

Results in OpenAPI JSON (note "null" types):

{
   "Product": {
      "type": "object",
      "properties": {
         "name": {
            "type": "string"
         },
         "price": {
            "type": "number"
         },
         "rating": {
            "type": [
               "null",
               "number"
            ]
         }
      },
      "required": [
         "name",
         "price",
         "rating"
      ]
   },
   "ProductList": {
      "type": "object",
      "properties": {
         "name": {
            "type": "string"
         },
         "version": {
            "type": "string"
         },
         "products": {
            "type": "array",
            "items": {
               "type": "object",
               "properties": {
                  "name": {
                     "type": "string"
                  },
                  "price": {
                     "type": "number"
                  },
                  "rating": {
                     "type": [
                        "null",
                        "number"
                     ]
                  }
               },
               "required": [
                  "name",
                  "price",
                  "rating"
               ]
            }
         }
      },
      "required": [
         "name",
         "products",
         "version"
      ]
   }
}

I was hoping to see something like this:

{
   "Product": {
      "type": "object",
      "properties": {
         "name": {
            "type": "string"
         },
         "price": {
            "type": "number"
         },
         "rating": {
            "type": "number",
            "nullable": true
         }
      },
      "required": [
         "name",
         "price",
         "rating"
      ]
   },
   "ProductList": {
      "type": "object",
      "properties": {
         "name": {
            "type": "string"
         },
         "version": {
            "type": "string"
         },
         "products": {
            "type": "array",
            "items": {
               "type": "object",
               "properties": {
                  "name": {
                     "type": "string"
                  },
                  "price": {
                     "type": "number"
                  },
                  "rating": {
                     "type": "number",
                     "nullable": true
                  }
               },
               "required": [
                  "name",
                  "price",
                  "rating"
               ]
            }
         }
      },
      "required": [
         "name",
         "products",
         "version"
      ]
   }
}

Upgrading to support examples from draft-06

We want to convert JSON Schema to OAI 3.0.
Your package seems to be the perfect solution for us.
Everything works perfectly with the exception of examples which have been added in Draft-06.
Is there any possibility to add the feature to convert examples of JSON Schema to example of OAI 3.0? E.g. only converting the first example?

"currency": { "type": [ "string", "null" ], "default": "EUR", "minLength": 3, "maxLength": 3, "title": "Currency", "description": "Currency code", "examples": [ "EUR", "GBP", "USD" ] },

If you have any other suggestions to address this problem, we would look forward to hear about them.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.