Skip to content

Commit

Permalink
fix(resolve-map): add private _resolveDeep
Browse files Browse the repository at this point in the history
- fixes resolution issue if a function dynamically created deep values
  • Loading branch information
postspectacular committed Jun 6, 2018
1 parent f2e0df2 commit 558f4f8
Showing 1 changed file with 28 additions and 4 deletions.
32 changes: 28 additions & 4 deletions packages/resolve-map/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export const resolveMap = (obj: any, root?: any, path: LookupPath = [], resolved
* @param path
* @param resolved
*/
const resolveArray = (arr: any[], root?: any, path: LookupPath = [], resolved: any = {}) => {
const _resolveArray = (arr: any[], root?: any, path: LookupPath = [], resolved: any = {}) => {
root = root || arr;
for (let k = 0, n = arr.length; k < n; k++) {
_resolve(root, [...path, k], resolved);
Expand All @@ -90,17 +90,18 @@ const resolveArray = (arr: any[], root?: any, path: LookupPath = [], resolved: a
};

const _resolve = (root: any, path: LookupPath, resolved: any) => {
let v = getIn(root, path), rv = SEMAPHORE;
let rv = SEMAPHORE;
let v = getIn(root, path);
const pp = path.join("/");
if (!resolved[pp]) {
if (isString(v) && v.charAt(0) === "@") {
rv = _resolve(root, absPath(path, v), resolved);
} else if (isPlainObject(v)) {
resolveMap(v, root, path, resolved);
} else if (isArray(v)) {
resolveArray(v, root, path, resolved);
_resolveArray(v, root, path, resolved);
} else if (isFunction(v)) {
rv = v((p: string) => _resolve(root, absPath(path, p, 0), resolved));
rv = v((p: string) => _resolveDeep(root, absPath(path, p, 0), resolved));
}
if (rv !== SEMAPHORE) {
mutIn(root, path, rv);
Expand All @@ -111,6 +112,29 @@ const _resolve = (root: any, path: LookupPath, resolved: any) => {
return v;
};

/**
* Repeatedly calls `_resolve` stepwise descending along given path.
* This is to ensure resolution of deep values created by functions at
* parent tree levels. E.g. given:
*
* ```
* {a: () => ({b: {c: 1}}), d: ($) => $("/a/b/c") }
* =>
* { a: { b: { c: 1 } }, d: 1 }
* ```
*
* @param root
* @param path
* @param resolved
*/
const _resolveDeep = (root: any, path: LookupPath, resolved: any) => {
let v;
for (let i = 1, n = path.length; i <= n; i++) {
v = _resolve(root, path.slice(0, i), resolved);
}
return v;
};

/**
* Takes the path for the current key and a lookup path string. Converts
* the possibly relative lookup path into its absolute form.
Expand Down

0 comments on commit 558f4f8

Please sign in to comment.