|
1 | 1 | import { forEach } from 'property-expr';
|
2 |
| -import has from 'lodash/has'; |
3 | 2 |
|
4 | 3 | let trim = part => part.substr(0, part.length - 1).substr(1);
|
5 | 4 |
|
6 |
| -export function getIn(schema, path, value, context) { |
| 5 | +export function getIn(schema, path, value, context = value) { |
7 | 6 | let parent, lastPart, lastPartDebug;
|
8 | 7 |
|
9 |
| - // if only one "value" arg then use it for both |
10 |
| - context = context || value; |
| 8 | + // root path: '' |
| 9 | + if (!path) return { parent, parentPath: path, schema }; |
11 | 10 |
|
12 |
| - if (!path) |
13 |
| - return { |
14 |
| - parent, |
15 |
| - parentPath: path, |
16 |
| - schema, |
17 |
| - }; |
18 |
| - |
19 |
| - // I no longer remember why this is so complicated |
20 |
| - forEach(path, (_part, isBracket, isArray, partIdx, parts) => { |
21 |
| - let isLast = partIdx === parts.length - 1; |
| 11 | + forEach(path, (_part, isBracket, isArray) => { |
22 | 12 | let part = isBracket ? trim(_part) : _part;
|
23 | 13 |
|
24 |
| - if (isArray || has(schema, '_subType')) { |
25 |
| - // we skipped an array: foo[].bar |
26 |
| - let idx = isArray ? parseInt(part, 10) : 0; |
27 |
| - |
28 |
| - schema = schema.resolve({ context, parent, value })._subType; |
| 14 | + schema = schema.resolve({ context, parent, value }); |
29 | 15 |
|
30 |
| - if (value) { |
31 |
| - if (isArray && idx >= value.length) { |
32 |
| - throw new Error( |
33 |
| - `Yup.reach cannot resolve an array item at index: ${_part}, in the path: ${path}. ` + |
34 |
| - `because there is no value at that index. `, |
35 |
| - ); |
36 |
| - } |
| 16 | + if (schema.innerType) { |
| 17 | + let idx = isArray ? parseInt(part, 10) : 0; |
37 | 18 |
|
38 |
| - if (isLast) { |
39 |
| - parent = value; |
40 |
| - lastPart = part; |
41 |
| - lastPartDebug = isBracket ? '[' + _part + ']' : '.' + _part; |
42 |
| - } |
43 |
| - value = value[idx]; |
| 19 | + if (value && idx >= value.length) { |
| 20 | + throw new Error( |
| 21 | + `Yup.reach cannot resolve an array item at index: ${_part}, in the path: ${path}. ` + |
| 22 | + `because there is no value at that index. `, |
| 23 | + ); |
44 | 24 | }
|
| 25 | + parent = value; |
| 26 | + value = value && value[idx]; |
| 27 | + schema = schema.innerType; |
45 | 28 | }
|
46 | 29 |
|
| 30 | + // sometimes the array index part of a path doesn't exist: "nested.arr.child" |
| 31 | + // in these cases the current part is the next schema and should be processed |
| 32 | + // in this iteration. For cases where the index signature is included this |
| 33 | + // check will fail and we'll handle the `child` part on the next iteration like normal |
47 | 34 | if (!isArray) {
|
48 |
| - schema = schema.resolve({ context, parent, value }); |
49 |
| - |
50 |
| - if (!has(schema, 'fields') || !has(schema.fields, part)) |
| 35 | + if (!schema.fields || !schema.fields[part]) |
51 | 36 | throw new Error(
|
52 | 37 | `The schema does not contain the path: ${path}. ` +
|
53 | 38 | `(failed at: ${lastPartDebug} which is a type: "${schema._type}")`,
|
54 | 39 | );
|
55 | 40 |
|
56 |
| - schema = schema.fields[part]; |
57 |
| - |
58 | 41 | parent = value;
|
59 | 42 | value = value && value[part];
|
60 |
| - lastPart = part; |
61 |
| - lastPartDebug = isBracket ? '[' + _part + ']' : '.' + _part; |
| 43 | + schema = schema.fields[part]; |
62 | 44 | }
|
| 45 | + |
| 46 | + lastPart = part; |
| 47 | + lastPartDebug = isBracket ? '[' + _part + ']' : '.' + _part; |
63 | 48 | });
|
64 | 49 |
|
65 | 50 | return { schema, parent, parentPath: lastPart };
|
|
0 commit comments