Create a JSON Schema without the pain of writing it
This module let you write JSON Schemas v4 in a "sugar" way (using a chainable API).
The API and style is stolen heavily inspired by Joi and Yup.
- Usage
- API
sugar
- mixed
mixed.clone(): Schema
mixed.title(title: string): Schema
mixed.description(description: string): Schema
mixed.default(default: any): Schema
mixed.meta(field: string | object, value: ?any): Schema
Alias:extra
mixed.enum(values: Array<any>): Schema
mixed.required(): Schema
mixed.requiredWhen(dependantProp: string | Array<string>): Schema
mixed.when(dependantProp: string | Array<string>): Schema
mixed.definitions(definitions: object): Schema
mixed.allOf(schemas: Array<Schema>): Schema
mixed.anyOf(schemas: Array<Schema>): Schema
mixed.oneOf(schemas: Array<Schema>): Schema
mixed.not(schema: Schema): Schema
mixed.noType(): Schema
mixed.canBe(type: Schema | Array<Schema>): Schema
mixed.ref(refUri: string): Schema
mixed.generate(options: ?object): string
- nullable
- boolean
- number
- string
- object
- array
Define and create schema objects. Schema objects are immutable, so each call of a method returns a new schema object.
var sugar = require('json-schema-sugar');
var schema = sugar.object().keys({
name: sugar.string().required(),
age: sugar.number().integer().required(),
email: sugar.string(),
website: sugar.string()
});
var jsonSchema = schema.generate({
name: 'jimmy',
age: 24
});
console.log(jsonSchema);
Output:
{
type: 'object',
properties: {
name: {
type: 'string'
},
age: {
type: 'integer'
},
email: {
type: 'string'
},
website: {
type: 'string'
}
},
required: ['name', 'age']
}
The module export.
var sugar = require('json-schema-sugar');
sugar.mixed // also aliased as sugar.any
sugar.nullable
sugar.string
sugar.number
sugar.boolean
sugar.object
sugar.array
Creates a schema that matches a general type. All types inherit from this base type
var schema = sugar.mixed();
schema.generate();
// => {}
Creates a deep copy of the schema. Clone is used internally to return a new schema with every schema state change (making schema instances inmutable).
Adds a title in the schema.
Adds a description in the schema.
Adds a default value in the schema.
Adds custom fields to the schema, multiple calls to .meta
will accumulate data with previous calls.
With field:
var schema = sugar.object().keys({
name: sugar.string().required().meta('example', 'Bob').meta('isMain', true),
});
schema.generate();
Output:
{
type: 'object',
properties: {
name: {
type: 'string',
example: 'Bob',
isMain: true
}
}
}
With an Object:
var schema = sugar.object().keys({
name: sugar.string().required().meta({ example: 'Bob', isMain: true }),
});
schema.generate();
Output:
{
type: 'object',
properties: {
name: {
type: 'string',
example: 'Bob',
isMain: true
}
}
}
Restricts a value in the schema to a fixed set of values.
When used inside an object schema specifies that a property is required.
var schema = sugar.object().keys({
name: sugar().string().required(),
email: sugar().string().required(),
address: sugar.string()
});
schema.generate();
Output:
{
type: 'object',
properties: {
name: {
type: 'string'
},
email: {
type: 'string'
},
address: {
type: 'string'
}
},
required: ['name', 'email']
}
When used inside an object schema specifies that a property must be present (required)
when another property/properties are present, making a property dependency
.
dependantProp
can be an array of strings, or multiple strings can be passed as individual arguments.
var schema = sugar.object().keys({
name: sugar.string().required(),
creditCard: sugar.number(),
billingAddress: sugar.string().requiredWhen('creditCard', 'name'),
billingDistrict: sugar.string().requiredWhen('creditCard')
});
schema.generate();
Output:
{
type: 'object',
properties: {
name: {
type: 'string'
},
creditCard: {
type: 'number'
},
billingAddress: {
type: 'string'
},
billingDistrict: {
type: 'string'
}
},
required: ['name'],
dependencies: {
creditCard: ['billingAddress', 'billingDistrict'],
name: ['billingAddress']
}
}
When used inside an object schema specifies that when a property is present the schema
should be different, making a schema dependency
.
dependantProp
can be an array of strings, or multiple strings can be passed as individual arguments.
var schema = sugar.object().keys({
name: sugar.string(),
creditCard: sugar.number(),
billingAddress: sugar.mixed().when('creditCard', sugar.string().required())
});
schema.generate();
Output:
{
type: 'object',
properties: {
name: {
type: 'string'
},
creditCard: {
type: 'number'
}
},
dependencies: {
creditCard: {
properties: {
billingAddress: {
type: 'string'
}
},
required: ['billingAddress']
}
}
}
Adds definitions to the schema, definitions are standardized placeholder in which you can define inline subschemas to be used in a schema.
var schema = sugar.object().keys({
billingAddress: sugar.any().ref('#/definitions/address')
}).definitions({
address: sugar.object().keys({
streetAddress: sugar.string().required(),
city: sugar.string().required(),
state: sugar.string().required()
})
});
schema.generate();
Output:
{
type: 'object',
properties: {
billingAddress: {
$ref: '#/definitions/address'
}
},
definitions: {
address: {
type: 'object',
properties: {
streetAddress: {
type: 'string'
},
city: {
type: 'string'
},
state: {
type: 'string'
}
},
required: ['streetAddress', 'city', 'state']
}
}
}
Adds a restriction that the given data must be valid against all of the given subschemas.
var schema = sugar.mixed().allOf([
sugar.string(),
sugar.string().minLength(2),
sugar.string().maxLength(5)
]);
Output:
{
allOf: [{
type: 'string'
}, {
minLength: 2
}, {
maxLength: 5
}]
}
Adds a restriction that the given data must be valid against any (one or more) of the given subschemas.
var schema = sugar.mixed().anyOf([
sugar.string().maxLength(5),
sugar.number().minimum(0)
]);
Output:
{
anyOf: [{
type: 'string',
maxLength: 5
}, {
type: 'number',
minimum: 0
}]
}
Adds a restriction that the given data must be valid against exactly one of the given subschemas.
var schema = sugar.mixed().oneOf([
sugar.number().multipleOf(3),
sugar.number().multipleOf(5)
]);
Output:
{
oneOf: [{
type: 'number',
multipleOf: 3
}, {
type: 'number',
multipleOf: 5
}]
}
Declares that a instance validates if it doesn’t validate against the given subschema.
var schema = sugar.mixed().not(sugar.string());
Output:
{
not: {
type: 'string'
}
}
Declares that a schema should not include the type
property in the output.
var schema = sugar.number().multipleOf(5).noType();
Output:
{
multipleOf: 5
}
Specify multiple types for a schema. type
can be an array of schemas, or multiple schemas can be passed as individual arguments.
This method is only available to mixed
schemas (schemas created directly with sugar.mixed()
)
var schema = sugar.mixed().canBe(sugar.string(), sugar.number());
schema.generate();
// => { type: ['string', 'number'] }
Creates a reference to a schema located in refUri
. This method is only available to mixed
schemas (schemas created directly with sugar.mixed()
)
var schema = sugar.object().keys({
billingAddress: sugar.any().ref('#/definitions/address'),
shippingAddress: sugar.any().allOf([
sugar.any().ref('#/definitions/address'),
sugar.object().keys({
type: sugar.any().enum(['residential', 'business']).required()
})
])
}).definitions({
address: sugar.object().keys({
streetAddress: sugar.string().required(),
city: sugar.string().required(),
state: sugar.string().required()
})
});
Output:
{
type: 'object',
properties: {
billingAddress: {
$ref: '#/definitions/address'
},
shippingAddress: {
allOf: [{
$ref: '#/definitions/address'
}, {
properties: {
type: {
enum: ['residential', 'business']
}
},
required: ['type']
}]
}
},
definitions: {
address: {
type: 'object',
properties: {
streetAddress: {
type: 'string'
},
city: {
type: 'string'
},
state: {
type: 'string'
}
},
required: ['streetAddress', 'city', 'state']
}
}
}
Generates a JSON Schema
based on the constructed schema.
The options
(optional) argument is an object hash and can contain the following properties:
options = {
obj: boolean = false,
removeType: boolean = false,
space: ?number = undefined,
$schema: ?string = undefined,
id: ?string = undefined
};
obj
: return theJSON Schema
as object instead of string.removeType
: don't include thetype
property in theJSON Schema
.space
: Specifies thespace
option forJSON.stringify
, adding the ability to return the json string with white space.$schema
: Specifies a custom$schema
entry in theJSON Schema
.id
: Specifies anid
entry in theJSON Schema
.
Creates a schema that matches a null
type. Supports all the same methods as mixed
.
var schema = sugar.nullable();
schema.generate();
// => { type: 'null' }
Creates a schema that matches a boolean
type. Supports all the same methods as mixed
.
var schema = sugar.boolean();
schema.generate();
// => { type: 'boolean' }
Creates a schema that matches a number
type. Supports all the same methods as mixed
.
var schema = sugar.number();
schema.generate();
// => { type: 'number' }
Defines that the schema should be an integer
.
var schema = sugar.number().integer();
schema.generate();
Output:
{
type: 'integer'
}
Defines that the schema should be multiple of value
.
var schema = sugar.number().multipleOf(3);
schema.generate();
Output:
{
type: 'number',
multipleOf: 3
}
Defines that the schema should be a minimum numeric value
.
var schema = sugar.number().minimum(5);
schema.generate();
Output:
{
type: 'number',
minimum: 5
}
Defines that the schema should be a maximum numeric value
.
var schema = sugar.number().maximum(10);
schema.generate();
Output:
{
type: 'number',
maximum: 10
}
When value
is true
, it indicates that the range excludes the minimum
value,
i.e., x > minx > min
. When false
(or not included), it indicates that the range includes the minimum
value, i.e., x ≥ minx ≥ min
.
var schema = sugar.number().minimum(5).exclusiveMinimum(true);
schema.generate();
Output:
{
type: 'number',
minimum: 5,
exclusiveMinimum: true
}
When value
is true
, it indicates that the range excludes the maximum
value,
i.e., x < maxx <max
. When false
(or not included), it indicates that the range includes the maximum
value, i.e., x ≤ maxx ≤ max
.
var schema = sugar.number().maximum(10).exclusiveMaximum(true);
schema.generate();
Output:
{
type: 'number',
maximum: 10,
exclusiveMaximum: true
}
Creates a schema that matches a string
type. Supports all the same methods as mixed
.
var schema = sugar.string();
schema.generate();
// => { type: 'string' }
Defines that a string should have a minimum length of value
.
var schema = sugar.string().minLength(2);
schema.generate();
Output:
{
type: 'string',
minLength: 2
}
Defines that a string should have a maximum length of value
.
var schema = sugar.string().maxLength(8);
schema.generate();
Output:
{
type: 'string',
maxLength: 8
}
Defines that a string should satisfies a pattern
.
var schema = sugar.string().pattern(/abc/);
schema.generate();
Output:
{
type: 'string',
pattern: 'abc'
}
Defines a format for the string. format
can be any standardized format like date-time
, email
, etc.
var schema = sugar.string().format('email');
schema.generate();
Output:
{
type: 'string',
format: 'email'
}
Creates a schema that matches a object
type. Supports all the same methods as mixed
.
var schema = sugar.object().keys({
name: sugar.string()
});
schema.generate();
// => { type: 'object', properties: { name: { type: 'string' } } }
Defines properties for the object. Each key in the properties
hash object must have a Schema
as value.
var schema = sugar.object().keys({
foo: sugar.boolean(),
value: sugar.number(),
address: sugar.string(),
unknown: sugar.nullable()
});
schema.generate();
Output:
{
type: 'object',
properties: {
foo: {
type: 'boolean'
},
value: {
type: 'number'
},
address: {
type: 'string'
},
unknown: {
type: 'null'
}
}
}
Defines if an object can have additional properties or not.
If value
is a Schema
then all additional properties must be valid against the given schema.
var schema = sugar.object().keys({
foo: sugar.boolean(),
value: sugar.number(),
address: sugar.string(),
unknown: sugar.nullable()
}).additionalProperties(sugar.string());
schema.generate();
Output:
{
type: 'object',
properties: {
foo: {
type: 'boolean'
},
value: {
type: 'number'
},
address: {
type: 'string'
},
unknown: {
type: 'null'
}
},
additionalProperties: {
type: 'string'
}
}
Defines that if there is any property in an object that match a given pattern, that property must be valid against a schema.
Each key in the value
hash object must have a Schema
as value.
var schema = sugar.object().keys({
foo: sugar.boolean(),
value: sugar.number(),
address: sugar.string(),
unknown: sugar.nullable()
}).patternProperties({
'^S_': sugar.string(),
'^I_': sugar.number().integer()
});
schema.generate();
Output:
{
type: 'object',
properties: {
foo: {
type: 'boolean'
},
value: {
type: 'number'
},
address: {
type: 'string'
},
unknown: {
type: 'null'
}
},
patternProperties: {
'^S_': {
type: 'string'
},
'^I_': {
type: 'integer'
}
}
}
Defines that an object should have a minimum number of properties.
var schema = sugar.object().keys({
foo: sugar.boolean(),
value: sugar.number(),
address: sugar.string(),
unknown: sugar.nullable()
}).minProperties(2);
schema.generate();
Output:
{
type: 'object',
properties: {
foo: {
type: 'boolean'
},
value: {
type: 'number'
},
address: {
type: 'string'
},
unknown: {
type: 'null'
}
},
minProperties: 2
}
Defines that an object should have a maximum number of properties.
var schema = sugar.object().keys({
foo: sugar.boolean(),
value: sugar.number(),
address: sugar.string(),
unknown: sugar.nullable()
}).maxProperties(3);
schema.generate();
Output:
{
type: 'object',
properties: {
foo: {
type: 'boolean'
},
value: {
type: 'number'
},
address: {
type: 'string'
},
unknown: {
type: 'null'
}
},
maxProperties: 3
}
Creates a schema that matches a array
type. Supports all the same methods as mixed
.
var schema = sugar.array().items(sugar.number());
schema.generate();
// => { type: 'array', items: { type: 'number' } }
When items
is an object
or Schema
specifies that all items in an array must be valid against the given schema.
When items
is an array
specifies that items in an array must be valid and appear in the same order of the given schemas (tuple validation).
var schema = sugar.array().items({
name: sugar.string(),
email: sugar.string()
});
schema.generate();
Output:
{
type: 'array',
items: {
type: 'object',
properties: {
name: {
type: 'string'
},
email: {
type: 'string'
}
}
}
}
Tuple example:
var schema = sugar.array().items([
sugar.number(),
sugar.string()
]);
schema.generate();
Output:
{
type: 'array',
items: [{
type: 'number'
}, {
type: 'string'
}]
}
Defines if an array can have additional items or not.
var schema = sugar.array().items([
sugar.string(),
sugar.number()
]).additionalItems(false);
schema.generate();
Output:
{
type: 'array',
items: [{
type: 'string'
}, {
type: 'number'
}],
additionalItems: false
}
Defines that an array should have a minimum number of items.
var schema = sugar.array().items({
value: sugar.number()
}).minItems(2);
schema.generate();
Output:
{
type: 'array',
items: {
type: 'object',
properties: {
value: {
type: 'number'
}
}
},
minItems: 2
}
Defines that an array should have a maximum number of items.
var schema = sugar.array().items({
value: sugar.number()
}).maxItems(2);
schema.generate();
Output:
{
type: 'array',
items: {
type: 'object',
properties: {
value: {
type: 'number'
}
}
},
maxItems: 2
}
Defines that items in an array should be unique.
var schema = sugar.array().items({
value: sugar.number()
}).uniqueItems(true);
schema.generate();
Output:
{
type: 'array',
items: {
type: 'object',
properties: {
value: {
type: 'number'
}
}
},
uniqueItems: true
}