Skip to content

Commit

Permalink
feat: add resolved to params (#1437)
Browse files Browse the repository at this point in the history
  • Loading branch information
akmjenkins committed Aug 9, 2021
1 parent 7842afb commit 03584f6
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 17 deletions.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ schema.validate({ name: 'jimmy', age: 11 }).catch(function (err) {
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->


- [`yup`](#yup)
- [`yup.reach(schema: Schema, path: string, value?: object, context?: object): Schema`](#yupreachschema-schema-path-string-value-object-context-object-schema)
- [`yup.addMethod(schemaType: Schema, name: string, method: ()=> Schema): void`](#yupaddmethodschematype-schema-name-string-method--schema-void)
Expand Down Expand Up @@ -606,7 +605,9 @@ be used in the `message` argument.
#### `mixed.oneOf(arrayOfValues: Array<any>, message?: string | function): Schema` Alias: `equals`

Whitelist a set of values. Values added are automatically removed from any blacklist if they are in it.
The `${values}` interpolation can be used in the `message` argument.
The `${values}` interpolation can be used in the `message` argument. If a ref or refs are provided,
the `${resolved}` interpolation can be used in the message argument to get the resolved values that were checked
at validation time.

Note that `undefined` does not fail this validator, even when `undefined` is not included in `arrayOfValues`.
If you don't want `undefined` to be a valid value, you can use `mixed.required`.
Expand All @@ -622,7 +623,9 @@ await schema.isValid(new Date()); // => false
#### `mixed.notOneOf(arrayOfValues: Array<any>, message?: string | function)`

Blacklist a set of values. Values added are automatically removed from any whitelist if they are in it.
The `${values}` interpolation can be used in the `message` argument.
The `${values}` interpolation can be used in the `message` argument. If a ref or refs are provided,
the `${resolved}` interpolation can be used in the message argument to get the resolved values that were checked
at validation time.

```js
let schema = yup.mixed().notOneOf(['jimmy', 42]);
Expand Down Expand Up @@ -729,7 +732,7 @@ await schema.isValid('john'); // => false
```

Test functions are called with a special context value, as the second argument, that exposes some useful metadata
and functions. For non arrow functions, the test context is also set as the function `this`. Watch out, if you access
and functions. For non arrow functions, the test context is also set as the function `this`. Watch out, if you access
it via `this` it won't work in an arrow function.

- `testContext.path`: the string path of the current validation
Expand Down
10 changes: 7 additions & 3 deletions src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import createValidation, {
import printValue from './util/printValue';
import Ref from './Reference';
import { getIn } from './util/reach';
import toArray from './util/toArray';
import {
ValidateOptions,
TransformFunction,
Expand All @@ -28,6 +27,7 @@ import ValidationError from './ValidationError';
import type { Asserts, Thunk } from './util/types';
import ReferenceSet from './util/ReferenceSet';
import Reference from './Reference';
import toArray from './util/toArray';

// const UNSET = 'unset' as const;

Expand Down Expand Up @@ -684,12 +684,14 @@ export default abstract class BaseSchema<
test(value) {
if (value === undefined) return true;
let valids = this.schema._whitelist;
let resolved = valids.resolveAll(this.resolve);

return valids.has(value, this.resolve)
return resolved.includes(value)
? true
: this.createError({
params: {
values: valids.toArray().join(', '),
resolved
},
});
},
Expand All @@ -713,10 +715,12 @@ export default abstract class BaseSchema<
name: 'notOneOf',
test(value) {
let invalids = this.schema._blacklist;
if (invalids.has(value, this.resolve))
let resolved = invalids.resolveAll(this.resolve);
if (resolved.includes(value))
return this.createError({
params: {
values: invalids.toArray().join(', '),
resolved
},
});
return true;
Expand Down
14 changes: 4 additions & 10 deletions src/util/ReferenceSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ export default class ReferenceSet {
return Array.from(this.list).concat(Array.from(this.refs.values()));
}

resolveAll(resolve: (v: unknown) => unknown) {
return this.toArray().reduce((acc: unknown[],e) => acc.concat(Reference.isRef(e) ? resolve(e) : e),[]);
}

add(value: unknown) {
Reference.isRef(value)
? this.refs.set(value.key, value)
Expand All @@ -36,16 +40,6 @@ export default class ReferenceSet {
? this.refs.delete(value.key)
: this.list.delete(value);
}
has(value: unknown, resolve: (v: unknown) => unknown) {
if (this.list.has(value)) return true;

let item,
values = this.refs.values();
while (((item = values.next()), !item.done))
if (resolve(item.value) === value) return true;

return false;
}

clone() {
const next = new ReferenceSet();
Expand Down
11 changes: 11 additions & 0 deletions test/mixed.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,17 @@ describe('Mixed Types ', () => {
);
});

it('should limit values with a ref', async () => {
let someValues = [1,2,3] ;
let context = { someValues };
let inst = mixed().oneOf([ref('$someValues[0]'),ref('$someValues[1]'),ref('$someValues[2]')]);
await inst.validate(1,{context}).should.eventually.equal(1);
await inst.validate(4,{context}).should.be.rejected().then(err => {
err.type.should.equal('oneOf')
expect(err.params.resolved).to.deep.equal(someValues)
})
})

it('should not require field when notRequired was set', async () => {
let inst = mixed().required();

Expand Down

0 comments on commit 03584f6

Please sign in to comment.