Skip to content

Commit

Permalink
feat: rewrite reference
Browse files Browse the repository at this point in the history
  • Loading branch information
vonagam committed Feb 5, 2019
1 parent 0f9df92 commit 7311c87
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 43 deletions.
8 changes: 2 additions & 6 deletions src/Condition.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,9 @@ class Conditional {
}
}

getValue(value, parent, context) {
let values = this.refs.map(r => r.getValue(value, parent, context));
resolve(ctx, options) {
let values = this.refs.map(ref => ref.getValue(options));

return values;
}

resolve(ctx, values) {
let schema = this.fn.apply(ctx, values.concat(ctx));

if (schema !== undefined && !isSchema(schema))
Expand Down
85 changes: 54 additions & 31 deletions src/Reference.js
Original file line number Diff line number Diff line change
@@ -1,54 +1,77 @@
import { getter } from 'property-expr';

let validateName = d => {
if (typeof d !== 'string')
throw new TypeError("ref's must be strings, got: " + d);
const prefixes = {
context: '$',
value: '.',
};

export default class Reference {
static isRef(value) {
return !!(value && (value.__isYupRef || value instanceof Reference));
}
constructor(key, options = {}) {
if (typeof key !== 'string')
throw new TypeError("ref's must be strings, got: " + key);

toString() {
return `Ref(${this.key})`;
this.key = key.trim();

this.isContext = this.key[0] === prefixes.context;
this.isValue = this.key[0] === prefixes.value;
this.isParent = this.key === '';
this.isSibling = !this.isContext && !this.isValue && !this.isParent;

let prefix = this.isContext
? prefixes.context
: this.isValue
? prefixes.value
: '';

this.path = this.key.slice(prefix.length);
this.getter = this.path && getter(this.path, true);
this.map = options.map;
}

constructor(key, mapFn, options = {}) {
validateName(key);
let prefix = options.contextPrefix || '$';
getValue(options) {
let result = this.isContext
? options.context
: this.isValue
? options.value
: options.parent;

this.key = key.trim();
this.prefix = prefix;
if (result === null) result = undefined;

this.isContext = this.key.indexOf(prefix) === 0;
this.isParent = this.key === '';
this.isSelf = this.key === '.';
this.isSibling = !this.isContext && !this.isParent && !this.isSelf;
if (this.getter && result !== undefined) result = this.getter(result);

if (!this.isSelf) {
this.path = this.isContext
? this.key.slice(this.prefix.length)
: this.key;
this._get = getter(this.path, true);
}
if (this.map) result = this.map(result);

this.map = mapFn || (value => value);
return result;
}

cast(value, options) {
return this.getValue({ ...options, value });
}

resolve() {
return this;
}

cast(value, { parent, context }) {
return this.getValue(value, parent, context);
describe() {
return {
type: 'ref',
isRef: true,
key: this.key,
isContext: this.isContext,
isValue: this.isValue,
isParent: this.isParent,
isSibling: this.isSibling,
path: this.path,
hasMap: Boolean(this.map),
};
}

getValue(value, parent, context) {
if (!this.isSelf) {
value = this._get(this.isContext ? context : parent || context || {});
}
toString() {
return `Ref(${this.key})`;
}

return this.map(value);
static isRef(value) {
return value && value.__isYupRef;
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/mixed.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,10 @@ const proto = (SchemaType.prototype = {
return !this._typeCheck || this._typeCheck(v);
},

resolve({ value, parent, context }) {
resolve(options) {
if (this._conditions.length) {
return this._conditions.reduce(
(schema, match) =>
match.resolve(schema, match.getValue(value, parent, context)),
(schema, condition) => condition.resolve(schema, options),
this,
);
}
Expand Down
4 changes: 3 additions & 1 deletion src/util/createValidation.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ export default function createValidation(options) {
}) {
let parent = options.parent;
let resolve = item =>
Ref.isRef(item) ? item.getValue(value, parent, options.context) : item;
Ref.isRef(item)
? item.getValue({ value, parent, context: options.context })
: item;

let createError = createErrorFactory({
message,
Expand Down
4 changes: 2 additions & 2 deletions test/mixed.js
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ describe('Mixed Types ', () => {

it('should handle multiple conditionals', function() {
let called = false;
let inst = mixed().when(['prop', 'other'], function(prop, other) {
let inst = mixed().when(['$prop', '$other'], function(prop, other) {
other.should.equal(true);
prop.should.equal(1);
called = true;
Expand All @@ -657,7 +657,7 @@ describe('Mixed Types ', () => {
inst.cast({}, { context: { prop: 1, other: true } });
called.should.equal(true);

inst = mixed().when(['prop', 'other'], {
inst = mixed().when(['$prop', '$other'], {
is: 5,
then: mixed().required(),
});
Expand Down

0 comments on commit 7311c87

Please sign in to comment.