Type Driven Schema Validator.
- Lightweight. Much smaller than other validation libraries.
- Easy to use. You can use any schema as a function or constructor directly.
- Powerful. Schemastery supports some advanced types such as
union
,intersect
andtransform
. - Extensible. You can create your own schema types via
Schema.extend()
. - Serializable. Schema objects can be serialized into JSON and then be hydrated in another environment.
const Schema = require('schemastery')
const validate = Schema.number().default(10)
validate(0) // 0
validate(null) // 10
validate('') // TypeError
import Schema from 'schemastery'
interface Config {
foo: Record<string, string>
bar: string[]
}
const Config = Schema.object({
foo: Schema.dict(Schema.string()).default({}),
bar: Schema.array(Schema.string()).default([]),
})
// config is an instance of Config
// in this case, that is { foo: {}, bar: [] }
const config = new Config()
Assert that the value is of any type.
const validate = Schema.any()
validate() // undefined
validate(0) // 0
validate({}) // {}
Assert that the value is nullable.
const validate = Schema.never()
validate() // undefined
validate(0) // TypeError
validate({}) // TypeError
Assert that the value is equal to the given constant.
const validate = Schema.const(10)
validate(10) // 10
validate(0) // TypeError
Assert that the value is a number.
const validate = Schema.number()
validate() // undefined
validate(1) // 1
validate('') // TypeError
Assert that the value is a string.
const validate = Schema.string()
validate() // undefined
validate(0) // TypeError
validate('foo') // 'foo'
Assert that the value is a boolean.
const validate = Schema.boolean()
validate() // undefined
validate(0) // TypeError
validate(true) // true
Assert that the value is an instance of the given constructor.
const validate = Schema.is(RegExp)
validate() // undefined
validate(/foo/) // /foo/
validate('foo') // TypeError
Assert that the value is an array of inner
. The default value will be []
if not specified.
const validate = Schema.array(Schema.number())
validate() // []
validate(0) // TypeError
validate([0, 1]) // [0, 1]
validate([0, '1']) // TypeError
Assert that the value is a dictionary of inner
. The default value will be {}
if not specified.
const validate = Schema.dict(Schema.number())
validate() // {}
validate(0) // TypeError
validate({ a: 0, b: 1 }) // { a: 0, b: 1 }
validate({ a: 0, b: '1' }) // TypeError
Assert that the value is a tuple whose each element is of corresponding subtype. The default value will be []
if not specified.
const validate = Schema.tuple([
Schema.number(),
Schema.string(),
])
validate() // []
validate([0]) // { a: 0 }
validate([0, 1]) // TypeError
validate([0, '1']) // [0, '1']
Assert that the value is an object whose each property is of corresponding subtype. The default value will be {}
if not specified.
const validate = Schema.object({
a: Schema.number(),
b: Schema.string(),
})
validate() // {}
validate({ a: 0 }) // { a: 0 }
validate({ a: 0, b: 1 }) // TypeError
validate({ a: 0, b: '1' }) // { a: 0, b: '1' }
Assert that the value is one of the specified types.
const validate = Schema.union([
Schema.number(),
Schema.string(),
])
validate() // undefined
validate(0) // 0
validate('1') // '1'
validate(true) // TypeError
Assert that the value should match each specified type.
const validate = Schema.intersect([
Schema.object({ a: Schema.string().required() }),
Schema.object({ b: Schema.number().default(0) }),
])
validate() // TypeError
validate({ a: '' }) // { a: '', b: 0 }
validate({ a: '', b: 1 }) // { a: '', b: 1 }
validate({ a: '', b: '2' }) // TypeError
Assert that the value is of the specified subtype and then transformed by callback
.
const validate = Schema.transform(Schema.number().default(0), n => n + 1)
validate() // 1
validate('0') // TypeError
validate(10) // 11
Assert that the value is not nullable.
Set the fallback value when nullable.
Set the description of the schema.
Some shorthand syntax is available for inner types.
undefined
->Schema.any()
String
->Schema.string()
Number
->Schema.number()
Boolean
->Schema.boolean()
1
->Schema.const(1)
(only for primitive types)Date
->Schema.is(Date)
Schema.array(String) // Schema.array(Schema.string())
Schema.dict(RegExp) // Schema.dict(Schema.is(RegExp))
Schema.union([1, 2]) // Schema.union([Schema.const(1), Schema.const(2)])
You can also use Schema.from()
to get the inferred schema from a shorthand value.
Schema.from() // Schema.any()
Schema.from(Date) // Schema.is(Date)
Schema.from('foo') // Schema.const('foo')
Here are some examples which demonstrate how to define advanced types.
const Enum = Schema.union(['red', 'blue'])
Enum('red') // 'red'
Enum('blue') // 'blue'
Enum('green') // TypeError
const ToString = Schema.transform(Schema.any(), v => String(v))
ToString('') // ''
ToString(0) // '0'
ToString({}) // '{}'
const Listable = Schema.union([
Schema.array(Number),
Schema.transform(Number, n => [n]),
]).default([])
Listable() // []
Listable(0) // [0]
Listable([1, 2]) // [1, 2]
const Config = Schema.dict(Number, Schema.union([
'foo',
Schema.transform('bar', () => 'foo'),
]))
Config({ foo: 1 }) // { foo: 1 }
Config({ bar: 2 }) // { foo: 2 }
Config({ bar: '3' }) // TypeError
const schema1 = Schema.object({
foo: Schema.string(),
bar: Schema.number(),
})
// should have the same effect as schema1
const schema2 = new Schema(JSON.parse(JSON.stringify(schema1)))