jsonschema-builder

1.1.4 • Public • Published

Build status Coverage Status

jsonschema-builder

Command line tool to generate JSON-schemas by the Mongoose model definition

The tool puts to standard output stream the json schema or an array of such schemas.

It supports two formats for resulting schemas:

  • javascript (produced by console.dir(...))
  • json (produced by JSON.stringify())

Contents

Installation

npm i -g jsonschema-builder

Usage

Getting options:

jsonschema-builder --help

Output:

Usage: jsonschema-builder [options] <pathToModels>
 
Options:
 
  -h, --help        output usage information
  -V, --version     output the version number
  -d, --dir         Process <pathToModels> as a directory
  -r, --recursive   Process directory recursively
  -j, --json        JSON format for output
  -n, --noid        Removes id field from resulting schema
  -o, --object-def  Output as json-schema definitions object
  -i, --id [style]  Style for json-schema identifiers
  --no-color        Prevents colorized output

Samples

Guessing you have some module with a model definition:

'use strict';
// models.js
 
const mongoose = require('mongoose');
 
const Schema = mongoose.Schema;
 
const BookSchema = new Schema({
  title: {type: String, required: true},
  year: Number,
  author: {type: Schema.Types.ObjectId, required: true, ref: 'Person'}
});
 
const PersonSchema = new Schema({
  firstName: {type: String, required: true},
  lastName: {type: String, required: true},
  dateOfBirth: Date
});
 
module.exports = exports = {
  Book: mongoose.model('Book', BookSchema),
  Person: mongoose.model('Person', PersonSchema)
};

Building json schema in javascript-object format:

jsonschema-builder ./models

Output:

[ { id: '#book',
    title: 'Book',
    type: 'object',
    properties:
     { title: { type: 'string' },
       year: { type: 'number' },
       author:
        { type: 'string',
          'x-ref': 'Person',
          description: 'Refers to Person',
          pattern: '^[0-9a-fA-F]{24}$' },
       _id: { type: 'string', pattern: '^[0-9a-fA-F]{24}$' },
       __v: { type: 'number' } },
    required: [ 'title', 'author' ] },
  { id: '#person',
    title: 'Person',
    type: 'object',
    properties:
     { firstName: { type: 'string' },
       lastName: { type: 'string' },
       dateOfBirth: { type: 'string', format: 'date-time' },
       _id: { type: 'string', pattern: '^[0-9a-fA-F]{24}$' },
       __v: { type: 'number' } },
    required: [ 'firstName', 'lastName' ] } ]

The same case with JSON formatted output

jsonschema-builder --json ./models

Output:

[
  {
    "id": "#book",
    "title": "Book",
    "type": "object",
    "properties": {
      "title": {
        "type": "string"
      },
      "year": {
        "type": "number"
      },
      "author": {
        "type": "string",
        "x-ref": "Person",
        "description": "Refers to Person",
        "pattern": "^[0-9a-fA-F]{24}$"
      },
      "_id": {
        "type": "string",
        "pattern": "^[0-9a-fA-F]{24}$"
      },
      "__v": {
        "type": "number"
      }
    },
    "required": [
      "title",
      "author"
    ]
  },
  {
    "id": "#person",
    "title": "Person",
    "type": "object",
    "properties": {
      "firstName": {
        "type": "string"
      },
      "lastName": {
        "type": "string"
      },
      "dateOfBirth": {
        "type": "string",
        "format": "date-time"
      },
      "_id": {
        "type": "string",
        "pattern": "^[0-9a-fA-F]{24}$"
      },
      "__v": {
        "type": "number"
      }
    },
    "required": [
      "firstName",
      "lastName"
    ]
  }
]

The module is passing to the tool could also export single instance of Mongoose.Model or an array of such instances.

Single instance:

'use strict';
//book.js
 
module.exports = exports = require('./models').Book;

Building schema for single model:

jsonschema-builder -j ./book > book.json

Opening book.json:

{
  "id": "#book",
  "title": "Book",
  "type": "object",
  "properties": {
    "title": {
      "type": "string"
    },
    "year": {
      "type": "number"
    },
    "author": {
      "type": "string",
      "x-ref": "Person",
      "description": "Refers to Person",
      "pattern": "^[0-9a-fA-F]{24}$"
    },
    "_id": {
      "type": "string",
      "pattern": "^[0-9a-fA-F]{24}$"
    },
    "__v": {
      "type": "number"
    }
  },
  "required": [
    "title",
    "author"
  ]
}

Array of models:

'use strict';
//list.js
 
const models = require('./models');
 
module.exports = exports = [
  models.Book, models.Person
];

Building schema for single model:

jsonschema-builder -j ./list > models.json

Opening models.json:

[
  {
    "id": "#book",
    "title": "Book",
    "type": "object",
    "properties": {
      "title": {
        "type": "string"
      },
      "year": {
        "type": "number"
      },
      "author": {
        "type": "string",
        "x-ref": "Person",
        "description": "Refers to Person",
        "pattern": "^[0-9a-fA-F]{24}$"
      },
      "_id": {
        "type": "string",
        "pattern": "^[0-9a-fA-F]{24}$"
      },
      "__v": {
        "type": "number"
      }
    },
    "required": [
      "title",
      "author"
    ]
  },
  {
    "id": "#person",
    "title": "Person",
    "type": "object",
    "properties": {
      "firstName": {
        "type": "string"
      },
      "lastName": {
        "type": "string"
      },
      "dateOfBirth": {
        "type": "string",
        "format": "date-time"
      },
      "_id": {
        "type": "string",
        "pattern": "^[0-9a-fA-F]{24}$"
      },
      "__v": {
        "type": "number"
      }
    },
    "required": [
      "firstName",
      "lastName"
    ]
  }
]

Prepared samples

jsonschema-builder project includes some sample model definitions that located in the samples folder in the project root directory.

The structure is following:

In order to run jsonschema-builder with prepared samples you should:

git clone https://github.com/DScheglov/jsonschema-builder.git
cd jsonschema-builder
npm install
npm link

When you finish sample running, just do unlink:

cd jsonschema-builder
npm unlink

Using the jsonschema-builder for single model:

jsonschema-builder samples/models/book

Output:

{ id: '#book',
  title: 'Book',
  type: 'object',
  properties:
   { title: { type: 'string' },
     year: { type: 'number' },
     author:
      { type: 'string',
        'x-ref': 'Person',
        description: 'Refers to Person',
        pattern: '^[0-9a-fA-F]{24}$' },
     _id: { type: 'string', pattern: '^[0-9a-fA-F]{24}$' },
     __v: { type: 'number' } },
  required: [ 'title', 'author' ] }

To get schema for all models located in the samples/models directory in JSON format

jsonschema-builder --dir --json samples/models
[
  {
    "id": "#book",
    "title": "Book",
    "type": "object",
    "properties": {
      "title": {
        "type": "string"
      },
      "year": {
        "type": "number"
      },
      "author": {
        "type": "string",
        "x-ref": "Person",
        "description": "Refers to Person",
        "pattern": "^[0-9a-fA-F]{24}$"
      },
      "_id": {
        "type": "string",
        "pattern": "^[0-9a-fA-F]{24}$"
      },
      "__v": {
        "type": "number"
      }
    },
    "required": [
      "title",
      "author"
    ]
  },
  {
    "id": "#person",
    "title": "Person",
    "type": "object",
    "properties": {
      "firstName": {
        "type": "string"
      },
      "lastName": {
        "type": "string"
      },
      "dateOfBirth": {
        "type": "string",
        "format": "date-time"
      },
      "_id": {
        "type": "string",
        "pattern": "^[0-9a-fA-F]{24}$"
      },
      "__v": {
        "type": "number"
      }
    },
    "required": [
      "firstName",
      "lastName"
    ]
  }
]

Please consider the difference between result of jsonschema-builder call with in option --dir and without that option:

jsonschema-builder --json samples/models

The jsonschema-builder will search for module by path samples/models and without --dir option will find samples/models.js instead of samples/models/ folder in case when --dir option specified

Output:

[
  {
    "id": "#point",
    "title": "Point",
    "type": "object",
    "properties": {
      "x": {
        "type": "number"
      },
      "y": {
        "type": "number"
      },
      "title": {
        "type": "string"
      },
      "_id": {
        "type": "string",
        "pattern": "^[0-9a-fA-F]{24}$"
      },
      "__v": {
        "type": "number"
      }
    }
  },
  {
    "id": "#line",
    "title": "Line",
    "type": "object",
    "properties": {
      "start": {
        "title": "start",
        "type": "object",
        "properties": {
          "x": {
            "type": "number"
          },
          "y": {
            "type": "number"
          },
          "title": {
            "type": "string"
          },
          "_id": {
            "type": "string",
            "pattern": "^[0-9a-fA-F]{24}$"
          },
          "__v": {
            "type": "number"
          }
        }
      },
      "end": {
        "title": "end",
        "type": "object",
        "properties": {
          "x": {
            "type": "number"
          },
          "y": {
            "type": "number"
          },
          "title": {
            "type": "string"
          },
          "_id": {
            "type": "string",
            "pattern": "^[0-9a-fA-F]{24}$"
          },
          "__v": {
            "type": "number"
          }
        }
      },
      "title": {
        "type": "string"
      },
      "_id": {
        "type": "string",
        "pattern": "^[0-9a-fA-F]{24}$"
      },
      "__v": {
        "type": "number"
      }
    }
  }
]

Schema id

Please note that jsonschema-builder adds the id field to each schema. To avoid this behavior use --noid option.

You could specify the style of id field. Currently supported the following options:

  • dash (default) - creates id from model.name in dash-style (model-name)
  • underline - entails the dash_style of id (model_name)
  • camel - removes all underlines and dashes form the model.name and returns camelStyle id (modelName)
  • lower - transforms all letters in model.name in the lower case analogs (modelname)

API

You can use jsonschema-builder inside of your code:

'use strict';
 
const jsonSchemaBuilder = require('jsonschema-builder');
 
let schemas = jsonSchemaBuilder('samples', {
  dir: true,
  recursive: true,
  json: true
})

The result will be the same as you call jsonschema-builder via command-line:

jsonschema-builder -jrd samples

jsonSchemaBuilder

Builds the json schema based on the Mongooose model definition specified by the path to appropriate module

Declaration:

function jsonSchemaBuilder(pathToModels, options) { ... }

Parameters:

  • pathToModels: String - the path to model definition(s)
  • options: Object - the options for schema creation
    • noid: Boolean - prevents id
    • json: Boolean - entails the JSON-formated result
    • id: String - defines the id field format
    • dir: Boolean - enforces the function to consider pathToModels as a directory
    • recursive: Boolean - enforces to find all models in pathToModels and in all its sub-dirctories
  • Returns Object|String - json schema

Methods:

extendMongoose

Extends the mongoose.Model and mongoose.Schema with method jsonSchema and returns Mongoose instance

Declaration:

function extendMongoose(mongoose) { ... }

In case you need to create json schema for mongoose.Model or mongoose.Schema instance you should use mongoose-schema-jsonschema module that is the core of jsonschema-builder.

You can import core-module directly by its name or call extendMongoose method of jsonSchemaBuilder object;

'use strict';
 
const jsonSchemaBuilder = require('jsonschema-builder');
const mongoose = jsonSchemaBuilder.extendMongoose(
  require('mongoose')
);
 
const Book = require('samples/models/book');
 
console.dir(Book.jsonSchema(), {depth: null});

Output:

{ title: 'Book',
  type'object',
  properties:
   { title: { type'string' },
     year: { type'number' },
     author:
      { type'string',
        'x-ref''Person',
        description: 'Refers to Person',
        pattern: '^[0-9a-fA-F]{24}$' },
     _id: { type'string', pattern: '^[0-9a-fA-F]{24}$' },
     __v: { type'number' } },
  required: [ 'title''author' ] }

More details by the link mongoose-schema-jsonschema

Contribution

Please register issues you met in the github-repository: https://github.com/DScheglov/jsonschema-builder/issues

Also I'll be thankful for code review.

Package Sidebar

Install

npm i jsonschema-builder

Weekly Downloads

3

Version

1.1.4

License

MIT

Last publish

Collaborators

  • dmitry.scheglov