conformist
A flatland-inspired schema definition and validation library for javascript.
Types
conformist ships with the following built-in type hierarchy:
Type
|
+-----------+
| |
Scalar Container
| |
| +------+
| | |
| List Map
|
+-----+------+------+
| | | |
Num Str Bool Enum
|
+
|
Int (TODO: Float)
Only the leaf nodes are concrete.
Scalars
Scalars are single-valued types.
Str is a string.
Bool is a boolean.
Int is an integer.
Enum is an enumerated set of Scalars: Enum.of(Str).valued(['a', 'b', 'c'])
.
Containers
Containers have multiple children.
List represents an array.
Map represents an object.
Schema
You compose types into schema. For example, if you want a number and a checkbox to enforce that the number is odd:
let NumberOddity = Map
Class cloning
Each Schema
type has several class-cloning static methods on it. Ultimately, each of these calls Schema.clone
in order to return a new, composed class with a modified prototype. These are:
Schema.named(name)
This assigns a name to the element
Schema.validatedBy(...validators)
This assigns 1 or more validators to the element.
Schema.using(overrides)
This assigns any number of overrides to the new prototype.
Schema.using({name})
is equivalent to Schema.named(name)
.
Elements
Elements are just instances of Schema types. let element = new Schema()
. Elements have a few useful properties. Consider:
let element = ;elementvalue// undefinedelement// trueelementvalue// '3'elementraw// 3
Validators
Validators are functions. The idiomatic definition of a validator is a function that takes a validation message and returns a validation function from (element, context) to success. If the validation fails, the error message should be added to the element's errors.
{ return { if elementmembersmustBeOddvalue if !elementmembersnumbervalue % 2 element; return false; return true; }} let NumberOddity = Map; let no = ;no;// trueno;// falsenoerrors// ['You should enter an odd number']noallErrors// {self: ['You should enter an odd number'], children: [number: [], mustBeOdd: []]}
Each element in a schema contains a list of errors
, which starts out as undefined
, but after validation is an array. Elements also have an allErrors
property, which for Scalar
elements is identical to the errors
, but for Container
s it will include errors for all children as well. For a List
, allErrors
returns a list of lists. For a Map
, the errors are returned in the format:
self: thiserrors children: child1: thismemberschild1allErrors child2: thismemberschild2allErrors ...
TODO
- drastically improve the quality of this README.
- organize code into separate files
- organize tests into suites
- make a decision about how to integrate with immutable
- should
optional
be a thing, or should there be a Required Validator? -- how to get useful "this element is required" messages, essentially.
Contributing
Please fork and send pull requests. If you add a feature, add a test. If you fix a bug, add a test. Thanks!
Authors
- Eric O'Connell eric@compassing.net
License
See LICENSE.