Skip to content

Commit

Permalink
[added] refs!
Browse files Browse the repository at this point in the history
  • Loading branch information
jquense committed Mar 29, 2016
1 parent 78f84c3 commit 9eb42c6
Show file tree
Hide file tree
Showing 16 changed files with 330 additions and 132 deletions.
78 changes: 65 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,25 @@ Thrown on failed validations, with the following properties
validation chain. When the `abortEarly` option is `false` this is where you can inspect each error thrown,
alternatively `errors` will have all the of the messages from each inner error.

#### `ref(String path, Object options)`

Creates a reference to another sibling or sibling descendant field. Ref's are resolved
at _run time_ and supported where specified. Ref's are evaluated in in the proper order so that
the ref value is resolved before the field using the ref (be careful of circular dependencies!).

```js
var schema = object({
baz: ref('foo.bar'),
foo: object({
bar: string()
})
x: ref('$x')
})

inst.cast({ foo: { bar: 'boom' } }, { context: { x: 5 } })
// { baz: 'boom', x: 5, { foo: { bar: 'boom' } }, }
```


### mixed

Expand Down Expand Up @@ -365,7 +384,7 @@ schema.isValid(42) //=> false
schema.isValid(new Date) //=> true
```

#### `mixed.when(String key, Object options | Function func)`
#### `mixed.when(String|Array<String> keys, Object options | Function func)`

Adjust the schema based on a sibling or sibling children fields. You can provide an object
literal where the key `is` is value or a matcher function, `then` provides the true schema and/or
Expand All @@ -374,11 +393,8 @@ literal where the key `is` is value or a matcher function, `then` provides the t
`is` conditions are strictly compared (`===`) if you want to use a different form of equality you
can provide a function like: `is: (value) => value == true`.

Alternatively you can provide a function the returns a schema (called with the value of the key
and the current schema). `when` conditions are additive.

Like joi you can also prefix properties with `$` to specify a property that is dependent
on `context` passed in by `validate()` or `isValid`.
on `context` passed in by `validate()` or `isValid`. `when` conditions are additive.

```javascript
var inst = yup.object({
Expand All @@ -397,6 +413,42 @@ var inst = yup.object({
inst.validate(value, { context: { other: 4 }})
```

You can also specify more than one dependent key, in which case each value will be spread as an argument.

```javascript
var inst = yup.object({
isSpecial: yup.bool()
isBig: yup.bool(),
count: yup.number()
.when(['isBig', 'isSpecial'], {
is: true, // alternatively: (isBig, isSpecial) => isBig && isSpecial
then: yup.number().min(5),
otherwise: yup.number().min(0)
})
})

inst.validate({
isBig: true,
isSpecial: true,
count: 10
})
```

Alternatively you can provide a function the returns a schema
(called with the value of the key and the current schema).

```js
var inst = yup.object({
isBig: yup.boolean(),
count: yup.number()
.when('isBig', (isBig, schema) => {
return isBig ? schema.min(5) : schema.min(0)
})
})

inst.validate({ isBig: false, count: 4 })
```


#### `mixed.test(String name, String message, Function fn, [Bool callbackStyleAsync])`

Expand Down Expand Up @@ -539,11 +591,11 @@ schema.isValid('hello') //=> true
The same as the `mixed()` schema required, except that empty strings are also considered 'missing' values.
To allow empty strings but fail on `undefined` values use: `string().required().min(0)`

#### `string.min(Number limit, [String message])`
#### `string.min(Number|Ref limit, [String message])`

Set an minimum length limit for the string value. The `${min}` interpolation can be used in the `message` argument

#### `string.max(Number limit, [String message])`
#### `string.max(Number|Ref limit, [String message])`

Set an maximum length limit for the string value. The `${max}` interpolation can be used in the `message` argument

Expand Down Expand Up @@ -588,12 +640,12 @@ var schema = yup.number();
schema.isValid(10) //=> true
```

#### `number.min(Number limit, [String message])`
#### `number.min(Number|Ref limit, [String message])`

Set the minimum value allowed. The `${min}` interpolation can be used in the
`message` argument.

#### `number.max(Number limit, [String message])`
#### `number.max(Number|Ref limit, [String message])`

Set the maximum value allowed. The `${max}` interpolation can be used in the
`message` argument.
Expand Down Expand Up @@ -636,11 +688,11 @@ var schema = yup.date();
schema.isValid(new Date) //=> true
```

#### `date.min(Date|String limit, [String message])`
#### `date.min(Date|String|Ref limit, [String message])`

Set the minimum date allowed.

#### `date.max(Date|String limit, [String message])`
#### `date.max(Date|String|Ref limit, [String message])`

Set the maximum date allowed.

Expand Down Expand Up @@ -668,11 +720,11 @@ not validate its contents.
The same as the `mixed()` schema required, except that empty arrays are also considered 'missing' values.
To allow empty arrays but fail on `undefined` values use: `array().required().min(0)`

#### `array.min(Number limit, [String message])`
#### `array.min(Number|Ref limit, [String message])`

Set an minimum length limit for the array. The `${min}` interpolation can be used in the `message` argument.

#### `array.max(Number limit, [String message])`
#### `array.max(Number|Ref limit, [String message])`

Set an maximum length limit for the array. The `${max}` interpolation can be used in the `message` argument.

Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
"karma-jsdom-launcher": "^1.0.0",
"karma-mocha": "^0.2.0",
"karma-mocha-reporter": "^1.0.2",
"karma-phantomjs-launcher": "^0.2.0",
"karma-sourcemap-loader": "^0.3.5",
"karma-webpack": "^1.7.0",
"mocha": "^1.21.4",
Expand Down
8 changes: 6 additions & 2 deletions src/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ inherits(ArraySchema, MixedSchema, {
name: 'min',
exclusive: true,
params: { min },
test: value => isAbsent(value) || value.length >= min
test(value) {
return isAbsent(value) || value.length >= this.resolve(min)
}
})
},

Expand All @@ -120,7 +122,9 @@ inherits(ArraySchema, MixedSchema, {
name: 'max',
exclusive: true,
params: { max },
test: value => isAbsent(value) || value.length <= max
test(value) {
return isAbsent(value) || value.length <= this.resolve(max)
}
})
},

Expand Down
8 changes: 6 additions & 2 deletions src/date.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ inherits(DateSchema, MixedSchema, {
exclusive: true,
message: msg || locale.min,
params: { min: min },
test: value => isAbsent(value) || (value >= limit)
test(value) {
return isAbsent(value) || value >= this.resolve(limit)
}
})
},

Expand All @@ -57,7 +59,9 @@ inherits(DateSchema, MixedSchema, {
exclusive: true,
message: msg || locale.max,
params: { max: max },
test: value => isAbsent(value) || (value <= limit)
test(value) {
return isAbsent(value) || value <= this.resolve(limit)
}
})
}

Expand Down
4 changes: 3 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';
var mixed = require('./mixed')
, bool = require('./boolean');
, bool = require('./boolean')
, Ref = require('./util/reference');

var isSchema = schema => schema && !!schema.__isYupSchema__;

Expand All @@ -17,6 +18,7 @@ module.exports = {
reach: require('./util/reach'),

ValidationError: require('./util/validation-error'),
ref: (key, options) => new Ref(key, options),

isSchema,

Expand Down
46 changes: 31 additions & 15 deletions src/mixed.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

var Promise = require('promise/lib/es6-extensions')
, Condition = require('./util/condition')
, ValidationError = require('./util/validation-error')
, locale = require('./locale.js').mixed
, _ = require('./util/_')
, isAbsent = require('./util/isAbsent')
, cloneDeep = require('./util/clone')
, createValidation = require('./util/createValidation')
, BadSet = require('./util/set');
, BadSet = require('./util/set')
, Ref = require('./util/reference');

let notEmpty = value => !isAbsent(value);

Expand All @@ -25,6 +25,7 @@ function SchemaType(options = {}){
return new SchemaType()

this._deps = []
this._conditions = []
this._options = { abortEarly: true, recursive: true }
this._exclusive = Object.create(null)
this._whitelist = new BadSet()
Expand Down Expand Up @@ -100,9 +101,9 @@ SchemaType.prototype = {
return !this._typeCheck || this._typeCheck(v)
},

cast(_value, _opts) {
var schema = this._resolve((_opts || {}).context)
return schema._cast(_value, _opts)
cast(value, opts = {}) {
var schema = this._resolve(opts.context, opts.parent)
return schema._cast(value, opts)
},

_cast(_value) {
Expand All @@ -116,9 +117,9 @@ SchemaType.prototype = {
return value
},

_resolve(context, parent){
if (this._deps.length) {
return this._deps.reduce((schema, match) =>
_resolve(context, parent) {
if (this._conditions.length) {
return this._conditions.reduce((schema, match) =>
match.resolve(schema, match.getValue(parent, context)), this)
}

Expand Down Expand Up @@ -186,7 +187,7 @@ SchemaType.prototype = {
},

default(def) {
if( arguments.length === 0){
if (arguments.length === 0) {
var dflt = _.has(this, '_default') ? this._default : this._defaultDefault
return typeof dflt === 'function'
? dflt.call(this) : cloneDeep(dflt)
Expand Down Expand Up @@ -277,11 +278,16 @@ SchemaType.prototype = {
return next
},

when(key, options){
when(keys, options) {
var next = this.clone()
, dep = new Condition(key, next._type, options);
, deps = [].concat(keys).map(key => new Ref(key));

next._deps.push(dep)
deps.forEach(dep => {
if (!dep.isContext)
next._deps.push(dep.key)
})

next._conditions.push(new Condition(deps, options))

return next
},
Expand All @@ -295,7 +301,9 @@ SchemaType.prototype = {
test(value) {
if (value !== undefined && !this.schema.isType(value))
return this.createError({
params: { type: this.schema._type }
params: {
type: this.schema._type
}
})
return true
}
Expand All @@ -320,7 +328,11 @@ SchemaType.prototype = {
test(value) {
let valids = this.schema._whitelist
if (valids.length && !(valids.has(value) || isAbsent(value)))
return this.createError({ params: { values: valids.values().join(', ') }})
return this.createError({
params: {
values: valids.values().join(', ')
}
})
return true
}
})
Expand All @@ -342,7 +354,11 @@ SchemaType.prototype = {
test(value) {
let invalids = this.schema._blacklist
if (invalids.length && invalids.has(value))
return this.createError({ params: { values: invalids.values().join(', ') }})
return this.createError({
params: {
values: invalids.values().join(', ')
}
})
return true
}
})
Expand Down
8 changes: 6 additions & 2 deletions src/number.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ inherits(NumberSchema, SchemaObject, {
exclusive: true,
params: { min },
message: msg || locale.min,
test: value => isAbsent(value) || value >= min
test(value) {
return isAbsent(value) || value >= this.resolve(min)
}
})
},

Expand All @@ -49,7 +51,9 @@ inherits(NumberSchema, SchemaObject, {
exclusive: true,
params: { max },
message: msg || locale.max,
test: value => isAbsent(value) || value <= max
test(value) {
return isAbsent(value) || value <= this.resolve(max)
}
})
},

Expand Down
Loading

0 comments on commit 9eb42c6

Please sign in to comment.