A utility to generate a Yup Schema from a valid JSON Schema.
Note: This package only supports yup v0.29.3 and below.
json-schema-yup-transform is heavily inspired by schema-to-yup but strictly supports the draft 7 specification
The main objective is to support as many of the features of the draft 7 specification as possible.
The project is written in TypeScript.
$ yarn build
Output goes into the dist/
directory.
Tests and code coverage are run with Jest.
$ yarn test
String, Number, Integer, Array, Object, Boolean and Null types are supported. The tables below outline which keywords each schema type supports.
Keyword | Supported |
---|---|
const | ✔️ |
enum | ✔️ |
minLength | ✔️ |
maxLength | ✔️ |
pattern | ✔️ |
date-time (format) | ✔️ |
time (format) | ✔️ |
date (format) | ✔️ |
email (format) | ✔️ |
idn-email (format) | ✔️ |
hostname (format) | ✔️ |
idn-hostname (format) | ✔️ |
ipv4 (format) | ✔️ |
ipv6 (format) | ✔️ |
uri (format) | ✔️ |
uri-reference (format) | ✔️ |
iri (format) | ✖️ |
iri-reference (format) | ✖️ |
uri-template (format) | ✖️ |
json-pointer | ✖️ |
relative-json-pointer | ✖️ |
regex | ✔️ |
Keyword | Supported |
---|---|
const | ✔️ |
enum | ✔️ |
multipleOf | ✔️ |
minimum | ✔️ |
exclusiveMinimum | ✔️ |
maximum | ✔️ |
exclusiveMaximum | ✔️ |
Keyword | Supported |
---|---|
const | ✔️ |
enum | ✔️ |
items | ✔️ |
contains | ✔️ |
tuple | ✔️ |
additionalItems | ✖️ |
minItems | ✔️ |
maxItems | ✔️ |
uniqueItems | ✔️ |
Keyword | Supported |
---|---|
const | ✔️ |
Keyword | Supported |
---|---|
required | ✔️ |
properties | ✔️ |
additionalProperties | ✖️ |
propertyNames | ✖️ |
size | ✖️ |
dependencies | ✖️ |
patternProperties | ✖️ |
Keyword | Supported |
---|---|
default | ✔️ |
description (used to store node path) | ✔️ |
if | ✔️ |
then | ✔️ |
else | ✔️ |
definitions | ✔️ |
$id | ✔️ |
Keyword | Supported |
---|---|
allOf | ✔️ |
anyOf | ✔️ |
oneOf | ✔️ |
not | ✔️ |
Provide a valid schema and convertToYup
will transform it to a yup schema.
import convertToYup from "json-schema-yup-transformer";
const schema = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "example",
title: "Example",
properties: {
name: {
type: "string"
}
}
};
// the yup equivalent of the above json schema
// const yupschema = Yup.object().shape({
// name: Yup.string()
// })
// check validity
const yupschema = convertToYup(schema);
const isValid = yupschema.isValidsync({
name: "Bruce Tanek"
});
// => true
Applying conditional rules
import convertToYup from "json-schema-yup-transformer";
const schema = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "example-conditional-rules",
title: "Example of conditional rules",
properties: {
country: {
type: "string"
}
},
required: ["country"]
if: {
properties: {
country: {
const: "Australia"
}
}
}
then: {
properties: {
residencyYears: {
type: "number",
minimum: 12
}
},
required: ["residencyYears"]
}
};
// the yup equivalent of the above json schema
// const yupschema = Yup.object().shape({
// country: Yup.string().required(),
// residencyYears: Yup.number().when('country', {
// is: 'true'
// then: Yup.number().required()
// })
// })
// check validity
const yupschema = convertToYup(schema)
const isValid = yupschema.isValidsync({
country: "Australia",
residencyYears: 15
})
// => true
Applying multiple types
import convertToYup from "json-schema-yup-transformer";
const schema = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "example-multiple-types",
title: "Example of multiple types",
properties: {
name: {
type: ["string", "null"]
}
}
};
// the yup equivalent of the above json schema
// const yupschema = Yup.object().shape({
// name: Yup.lazy(value => {
// switch (typeof value) {
// case 'string':
// return Yup.number();
// case 'null':
// return Yup.mixed().notRequired();
// default:
// return Yup.mixed();
// }
// })
// })
// check validity
const yupschema = convertToYup(schema);
const isValid = yupschema.isValidsync({
name: null
});
// => true
Providing custom error messages
The structure of the configuration error messages need to adhere to the path of that field in the schema as well as the associated schema validation keyword.
import convertToYup from "json-schema-yup-transformer";
const schema = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "example-custom-error-messages",
title: "Exampel of custom error messages",
properties: {
team: {
type: "object",
properties: {
name: {
type: "string"
}
}
}
},
required: ["name"]
};
// configuration for custom error messages
const config = {
errors: {
team: {
name: {
required: "Custom error message"
}
}
}
};
// check validity
const yupschema = convertToYup(schema, config);
let errorMessage;
try {
errorMessage = yupschema.validateSync();
} catch (e) {
errorMessage = e.errors[0];
}
// => "Custom error message"
Using error handlers to further customise error messages
import convertToYup from "json-schema-yup-transformer";
const schema = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "example-custom-error-messages",
title: "Exampel of custom error messages",
properties: {
team: {
type: "object",
properties: {
name: {
type: "string"
}
}
}
},
required: ["name"]
};
// configuration for custom error messages
const config = {
errors: {
team: {
name: {
required: ([key, { required }]) =>
`${key} field is invalid. Here is a list of required fields: ${required}`
}
}
}
};
// check validity
const yupschema = convertToYup(schema, config);
let errorMessage;
try {
errorMessage = yupschema.validateSync();
} catch (e) {
errorMessage = e.errors[0];
}
// => "name field is invalid. Here is a list of required fields: name"
Setting default error messages for a type
import convertToYup from "json-schema-yup-transformer";
const schema = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "example-default-error-messages",
title: "Example of default error messages",
properties: {
team: {
type: "object",
properties: {
name: {
type: "string"
}
}
}
}
};
// set default error message for type of string
const config = {
errors: {
defaults: {
string: "Custom error message"
}
}
};
// check validity
const yupschema = convertToYup(schema, config);
let errorMessage;
try {
errorMessage = yupschema.validateSync({
team: {
name: null
}
});
} catch (e) {
errorMessage = e.errors[0];
}
// => "Custom error message"
Applying definitions and $ref
import convertToYup from "json-schema-yup-transformer";
let schema: JSONSchema7 = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "example-definitions",
title: "Example of definitions",
definitions: {
address: {
type: "object",
properties: {
street_address: { type: "string" },
city: { type: "string" },
state: { type: "string" }
},
required: ["street_address", "city", "state"]
}
},
properties: {
mailingAddress: {
$ref: "#/definitions/address"
}
}
};
// check validity
const yupschema = convertToYup(schema);
const isValid = yupschema.isValidsync({
mailingAddress: {
street_address: "18 Rover street",
city: "New York City",
state: "New York"
}
});
// => true
Validate against allof
subschemas
import convertToYup from "json-schema-yup-transformer";
const schema = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "test",
title: "Test",
properties: {
things: {
allOf: [
{ type: "string", minLength: 4 },
{ type: "string", maxLength: 6 }
]
}
}
};
// check validity
let yupschema = convertToYup(schema);
let isValid = yupschema.isValidSync({
things: "12345"
});
// => true
Validate against anyof
subschemas
import convertToYup from "json-schema-yup-transformer";
const schema = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "test",
title: "Test",
properties: {
things: {
anyOf: [
{ type: "string", minLength: 6 },
{ type: "string", const: "test" }
]
}
}
};
// check validity
let yupschema = convertToYup(schema);
let isValid = yupschema.isValidSync({
things: "test"
});
// => true
Validate against not
subschemas
import convertToYup from "json-schema-yup-transformer";
const schema = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "test",
title: "Test",
properties: {
things: {
not: { type: "string", minLength: 6 }
}
}
};
// check validity
let yupschema = convertToYup(schema);
let isValid = yupschema.isValidSync({
things: "1234"
});
// => true
Validate against oneof
subschemas
import convertToYup from "json-schema-yup-transformer";
const schema = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "test",
title: "Test",
properties: {
things: {
oneOf: [
{ type: "string", minLength: 6 },
{ type: "string", minLength: 3 }
]
}
}
};
// check validity
let yupschema = convertToYup(schema);
let isValid = yupschema.isValidSync({
things: "1234"
});
// => true