1+
12Yup
23=======================
34
@@ -11,20 +12,73 @@ It also allows "stacking" conditions via `when` for properties that depend on mo
1112child property. Yup separates the parsing and validating functions into separate steps so it can be used to parse
1213json separate from validating it, via the ` cast ` method.
1314
14- ## Usage
15+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
16+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
17+ ** Table of Contents** * generated with [ DocToc] ( https://github.com/thlorenz/doctoc ) *
18+
19+ - [ Usage] ( #usage )
20+ - [ API] ( #api )
21+ - [ ` yup ` ] ( #yup )
22+ - [ ` .reach(Schema schema, String path, Object options) ` ] ( #reachschema-schema-string-path-object-options )
23+ - [ ` .addMethod(schemaType, name, method) ` ] ( #addmethodschematype-name-method )
24+ - [ ` ValidationError(String|Array<String> errors, Any value, String path) ` ] ( #validationerrorstringarraystring-errors-any-value-string-path )
25+ - [ ` mixed ` ] ( #mixed )
26+ - [ ` mixed.clone() ` ] ( #mixedclone )
27+ - [ ` mixed.concat(Schema schema) ` ] ( #mixedconcatschema-schema )
28+ - [ ` mixed.validate(Any value, [Object options, Function callback]) ` ] ( #mixedvalidateany-value-object-options-function-callback )
29+ - [ ` mixed.isValid(Any value, [Object options, Function callback]) -> Promise ` ] ( #mixedisvalidany-value-object-options-function-callback---promise )
30+ - [ ` mixed.cast(value) -> Any ` ] ( #mixedcastvalue---any )
31+ - [ ` mixed.isType(Any value) -> Boolean ` ] ( #mixedistypeany-value---boolean )
32+ - [ ` mixed.strict() ` (default: ` false ` )] ( #mixedstrict-default-false )
33+ - [ ` mixed.default(Any value) ` ] ( #mixeddefaultany-value )
34+ - [ ` mixed.default() -> Any ` ] ( #mixeddefault---any )
35+ - [ ` mixed.typeError(String message) ` (default: '${path} (value: \` ${value}\` ) must be a \` ${type}\` type')] ( #mixedtypeerrorstring-message-default-path-value-%5Cvalue%5C-must-be-a-%5Ctype%5C-type )
36+ - [ ` mixed.nullable(Bool isNullable) ` (default: ` false ` )] ( #mixednullablebool-isnullable-default-false )
37+ - [ ` mixed.required([String message]) ` ] ( #mixedrequiredstring-message )
38+ - [ ` mixed.oneOf(Array<Any> arrayOfValues, [String message]) ` Alias: ` equals ` ] ( #mixedoneofarrayany-arrayofvalues-string-message-alias-equals )
39+ - [ ` mixed.notOneOf(Array<Any> arrayOfValues, [String message]) ` ] ( #mixednotoneofarrayany-arrayofvalues-string-message )
40+ - [ ` mixed.when(String key, Object options | Function func) ` ] ( #mixedwhenstring-key-object-options--function-func )
41+ - [ ` mixed.test(String name, String message, Function fn, [Bool callbackStyleAsync]) ` ] ( #mixedteststring-name-string-message-function-fn-bool-callbackstyleasync )
42+ - [ ` mixed.test(Object options) ` ] ( #mixedtestobject-options )
43+ - [ ` mixed.transform(Function fn) ` ] ( #mixedtransformfunction-fn )
44+ - [ string] ( #string )
45+ - [ ` string.required([String message]) ` ] ( #stringrequiredstring-message )
46+ - [ ` string.min(Number limit, [String message]) ` ] ( #stringminnumber-limit-string-message )
47+ - [ ` string.max(Number limit, [String message]) ` ] ( #stringmaxnumber-limit-string-message )
48+ - [ ` string.matches(Regex regex, [String message]) ` ] ( #stringmatchesregex-regex-string-message )
49+ - [ ` string.email([String message]) ` ] ( #stringemailstring-message )
50+ - [ ` string.url([String message]) ` ] ( #stringurlstring-message )
51+ - [ ` string.trim([String message]) ` ] ( #stringtrimstring-message )
52+ - [ ` string.lowercase([String message]) ` ] ( #stringlowercasestring-message )
53+ - [ ` string.uppercase([String message]) ` ] ( #stringuppercasestring-message )
54+ - [ number] ( #number )
55+ - [ ` number.min(Number limit, [String message]) ` ] ( #numberminnumber-limit-string-message )
56+ - [ ` number.max(Number limit, [String message]) ` ] ( #numbermaxnumber-limit-string-message )
57+ - [ ` number.positive([String message]) ` ] ( #numberpositivestring-message )
58+ - [ ` number.negative([String message]) ` ] ( #numbernegativestring-message )
59+ - [ ` number.integer([String message]) ` ] ( #numberintegerstring-message )
60+ - [ ` round(String type) ` - 'floor', 'ceil', 'round'] ( #roundstring-type---floor-ceil-round )
61+ - [ boolean] ( #boolean )
62+ - [ date] ( #date )
63+ - [ ` date.min(Date|String limit, [String message]) ` ] ( #datemindatestring-limit-string-message )
64+ - [ ` date.max(Date|String limit, [String message]) ` ] ( #datemaxdatestring-limit-string-message )
65+ - [ array] ( #array )
66+ - [ ` array.of(Schema type) ` ] ( #arrayofschema-type )
67+ - [ ` array.required([String message]) ` ] ( #arrayrequiredstring-message )
68+ - [ ` array.min(Number limit, [String message]) ` ] ( #arrayminnumber-limit-string-message )
69+ - [ ` array.max(Number limit, [String message]) ` ] ( #arraymaxnumber-limit-string-message )
70+ - [ ` array.compact(Function rejector) ` ] ( #arraycompactfunction-rejector )
71+ - [ object] ( #object )
72+ - [ ` object.shape(Object schemaHash, [noSortEdges]) ` ] ( #objectshapeobject-schemahash-nosortedges )
73+ - [ ` object.from(String fromKey, String toKey, Bool alias) ` ] ( #objectfromstring-fromkey-string-tokey-bool-alias )
74+ - [ ` object.noUnknown([Bool onlyKnownKeys, String msg]) ` ] ( #objectnounknownbool-onlyknownkeys-string-msg )
75+ - [ ` object.camelcase() ` ] ( #objectcamelcase )
76+ - [ ` object.constantcase() ` ] ( #objectconstantcase )
77+ - [ Extending Schema Types] ( #extending-schema-types )
78+
79+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
1580
16- - [ Yup] ( #yup-1 )
17- + [ ` mixed ` ] ( #mixed )
18- + [ ` string ` ] ( #string )
19- + [ ` number ` ] ( #number )
20- + [ ` boolean ` ] ( #boolean )
21- + [ ` date ` ] ( #date )
22- + [ ` array ` ] ( #array )
23- + [ ` object ` ] ( #array )
24- - [ ` reach ` ] ( #reachschema-schema-string-path-object-options )
25- - [ ` addMethod ` ] ( #addmethodschematype-name-method )
26- - [ ` ValidationError ` ] ( #validationerrorstringarraystring-errors-string-path-any-value )
27- - [ Extending Schema Types] ( #extending-schema-types )
81+ ## Usage
2882
2983You define and create schema objects. Schema objects are immutable, so each call of a method returns a _ new_ schema object.
3084
@@ -60,6 +114,8 @@ schema.cast({
60114// => { name: 'jimmy', age: 24, createdOn: Date }
61115```
62116
117+ ## API
118+
63119### ` yup `
64120
65121The module export.
@@ -128,7 +184,7 @@ Thrown on failed validations, with the following properties
128184 alternatively ` errors ` will have all the of the messages from each inner error.
129185
130186
131- ### ` mixed `
187+ ### mixed
132188
133189Creates a schema that matches all types. All types inherit from this base type
134190
@@ -219,6 +275,30 @@ You should use `isType` for all Schema type checks.
219275Sets the ` strict ` option to ` true ` . Strict schemas skip coercion and transformation attempts,
220276validating the value "as is".
221277
278+ #### ` mixed.withMutation(Function fn) `
279+
280+ First the legally required Rich Hickey quote:
281+
282+ > If a tree falls in the woods, does it make a sound?
283+ >
284+ > If a pure function mutates some local data in order to produce an immutable return value, is that ok?
285+
286+ ` withMutation ` allows you to mutate the schema in place, instead of the default behavior which clones before each change.
287+ Generally this isn't necessary since the vast majority of schema changes happen during the initial
288+ declaration, and only happen once over the lifetime of the schema, so performance isn't an issue.
289+ However certain mutations _ do_ occur at cast/validation time, (such as conditional schema using ` when() ` ), or
290+ when instantiating a schema object.
291+
292+ ``` js
293+ object ()
294+ .shape ({ key: string () })
295+ .withMutation (schema => {
296+ return arrayOfObjectTests .forEach (test => {
297+ schema .test (test)
298+ })
299+ })
300+ ```
301+
222302#### ` mixed.default(Any value) `
223303
224304Sets a default value to use when the value is ` undefined ` (or ` null ` when the schema is not nullable).
@@ -242,12 +322,7 @@ for objects and arrays. To avoid this overhead you can also pass a function that
242322Calling ` default ` with no arguments will return the current default value
243323
244324
245- #### ` mixed.typeError(String message) ` (default: '${path} (value: \` ${value}\` ) must be a \` ${type}\` type')
246-
247- Define an error message for failed type checks. The ` ${value} ` and ` ${type} ` interpolation can
248- be used in the ` message ` argument.
249-
250- #### ` mixed.nullable(Bool isNullable) ` (default: ` false ` )
325+ #### ` mixed.nullable(Bool isNullable = false) `
251326
252327Indicates that ` null ` is a valid value for the schema. Without ` nullable() `
253328` null ` is treated as a different type and will fail ` isType() ` checks.
@@ -256,6 +331,11 @@ Indicates that `null` is a valid value for the schema. Without `nullable()`
256331
257332Mark the schema as required. All field values apart from ` undefined ` meet this requirement.
258333
334+ #### ` mixed.typeError(String message) `
335+
336+ Define an error message for failed type checks. The ` ${value} ` and ` ${type} ` interpolation can
337+ be used in the ` message ` argument.
338+
259339#### ` mixed.oneOf(Array<Any> arrayOfValues, [String message]) ` Alias: ` equals `
260340
261341Whitelist a set of values. Values added are automatically removed from any blacklist if they are in it.
@@ -692,8 +772,8 @@ var invalidDate = new Date('');
692772function parseDateFromFormats (formats , parseStrict ) {
693773
694774 return this .transform (function (value , originalValue ){
695-
696- if ( this . isType (value) ) return value
775+ if ( this . isType (value))
776+ return value
697777
698778 value = Moment (originalValue, formats, parseStrict)
699779
@@ -707,32 +787,45 @@ yup.addMethod(yup.date, 'format', parseDateFromFormats)
707787```
708788
709789__ Creating new Types__
710- ``` js
711- var inherits = require (' inherits' )
712- var invalidDate = new Date (' ' ); // our failed to coerce value
713790
714- function MomentDateSchemaType (){
715- // so we don't need to use the `new` keyword
716- if ( ! (this instanceof MomentDateSchemaType))
717- return new MomentDateSchemaType ()
791+ Yup schema use the common constructor pattern for modeling inheritance. You can use any
792+ utility or pattern that works with that pattern. The below demonstrates using the es6 class
793+ syntax since its less verbose, but you absolutely aren't required to use it.
718794
719- yup .date .call (this )
795+ ``` js
796+ var DateSchema = yup .date
797+ var invalidDate = new Date (' ' ); // our failed to coerce value
798+
799+ class MomentDateSchemaType extends DateSchema {
800+ constructor () {
801+ super ();
802+ this ._validFormats = [];
803+
804+ this .withMutation (() => {
805+ this .transform (function (value , originalvalue ) {
806+ if (this .isType (value)) // we have a valid value
807+ return value
808+ return Moment (originalValue, this ._validFormats , true )
809+ })
810+ })
720811 }
721812
722- inherits (MomentDateSchemaType, yup . date )
723-
724- MomentDateSchemaType . prototype . format = function ( formats , strict ){
725- if ( ! formats) throw new Error ( ' must enter a valid format ' )
813+ _typeCheck ( value ) {
814+ return super . _typeCheck (value)
815+ || ( moment . isMoment (value) && value . isValid ())
816+ }
726817
727- this .transforms .push (function (value , originalValue ) {
728- if ( this .isType (value) ) // we have a valid value
729- return value
730- value = Moment (originalValue, formats, strict)
731- return value .isValid () ? value .toDate () : invalidDate
732- })
818+ format (formats ) {
819+ if (! formats)
820+ throw new Error (' must enter a valid format' )
821+ let next = this .clone ()
822+ next ._validFormats = {}.concat (formats);
733823 }
824+ }
734825
735- var schema = MomentDateSchemaType (). format ( ' YYYY-MM-DD ' )
826+ var schema = new MomentDateSchemaType ()
736827
737- schema .cast (' It is 2012-05-25' ) // Fri May 25 2012 00:00:00 GMT-0400 (Eastern Daylight Time)
828+ schema
829+ .format (' YYYY-MM-DD' )
830+ .cast (' It is 2012-05-25' ) // Fri May 25 2012 00:00:00 GMT-0400 (Eastern Daylight Time)
738831```
0 commit comments