json-schema-to-yup
Version:
Build a Yup schema from a JSON Schema. Also supports custom/alternative schema models such as GraphQL type defs
156 lines (130 loc) • 3.26 kB
JavaScript
// See:
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.4
import { YupMixed } from './mixed';
import { Base } from './base';
class ArrayHandler extends Base {
constructor(config) {
super(config);
}
isArray(obj) {
if (!this.config.isArray) {
this.error("ArrayHandler: mising isArray in config", this.config);
}
return this.config.isArray(obj);
}
handle(obj) {
return this.isArray(obj) && YupArray.create(obj).createSchemaEntry();
}
}
function toYupArray(obj, config = {}) {
return obj && new ArrayHandler(config).handle(obj);
}
class YupArray extends YupMixed {
constructor(obj) {
super(obj);
this.type = "array";
this.base = this.yup.array();
this.createYupSchemaEntry = this.config.createYupSchemaEntry;
}
static create(obj) {
return new YupArray(obj);
}
convert() {
this.maxItems();
this.minItems();
this.ensureItems();
this.compact();
// this.$uniqueItems()
// .$contains()
// .$additionalItems()
// .$items();
// this.itemsOf()
super.convert();
return this;
}
ensureItems() {
return this.addConstraint("ensure");
}
compact() {
return this.addConstraint("compact");
}
// TODO: not yet implemented
itemsOf() {
return this;
// const { items, itemsOf } = this.constraints;
// const $itemsOfSchema = items || itemsOf || this.constraints.of;
// if (Array.isArray($itemsOfSchema)) {
// this.error("itemsOf", "does not (yet) support an Array of schemas");
// }
// if (!this.createYupSchemaEntry) {
// this.warn(
// "missing createYupSchemaEntry in config, needed for recursive validation"
// );
// return;
// }
// this.createYupSchemaEntry({
// key: this.key,
// value: $itemsOfSchema,
// type: this.type,
// config: this.config
// });
// $of && this.base.of($max);
// return this;
}
maxItems() {
const { maxItems, max } = this.constraints;
const $max = maxItems || max;
if (!this.isNumberType($max)) {
return this;
}
if (!this.isValidSize($max)) {
return this.handleInvalidSize("maxItems", $max);
}
const newBase = $max && this.base.max($max);
this.base = newBase || this.base;
return this;
}
minItems() {
const { minItems, min } = this.constraints;
const $min = minItems || min;
if (!this.isNumberType($min)) {
return this;
}
if (!this.isValidSize($min)) {
return this.handleInvalidSize("minItems", $min);
}
const newBase = $min && this.base.min($min);
this.base = newBase || this.base;
return this;
}
$items() {
return this;
}
$additionalItems() {
return this;
}
$uniqueItems() {
return this;
}
$contains() {
return this;
}
// utility
handleInvalidSize(name, value) {
const msg = `invalid array size constraint for ${name}, was ${value}. Must be a number >= 0`;
if (this.config.warnOnInvalid) {
this.warn(msg);
return this;
}
this.error(msg, value);
return this;
}
isValidSize(num) {
return this.isNumberType(num) && num >= 0;
}
}
export {
toYupArray,
YupArray,
ArrayHandler
};