-
Notifications
You must be signed in to change notification settings - Fork 7
/
paths.ts
68 lines (56 loc) · 1.98 KB
/
paths.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// Copyright (c) 2020 Jozty. All rights reserved. MIT license.
import type { ObjRec, PH } from './utils/types.ts';
import {
isArrayLike,
isInteger,
isString,
isUndefinedOrNull,
} from './utils/is.ts';
import { nth } from './nth.ts';
import curryN from './utils/curry_n.ts';
import { trim } from './trim.ts';
export type Path = string | Array<string | number>;
// @types
type Paths_2 = <T, R>(obj: ObjRec<T> | null) => R[];
type Paths_1<T, R> = (pathsArr: Path[]) => R[];
type Paths =
& ((pathsArr: Path[]) => Paths_2)
& (<T, R>(pathsArr: PH, obj: ObjRec<T> | null) => Paths_1<T, R>)
& (<T, R>(pathsArr: Path[], obj: ObjRec<T> | null) => R[]);
export function getPath(path: Path): Array<string | number> {
if (isString(path)) {
if (path.includes('/')) return trim(path, '/').split('/');
if (path.includes('.')) return trim(path, '.').split('.');
return path ? [path] : [];
}
return path;
}
function _paths<T, R>(
pathsArr: Path[],
obj: ObjRec<T> | null,
): (R | undefined)[] {
return pathsArr.map<R | undefined>((p) => {
const path = getPath(p);
let val: unknown = obj;
for (let i = 0; i < path.length; i++) {
if (isUndefinedOrNull(val)) return undefined;
const p = path[i];
const pInt = parseInt(p as string, 10);
val = isInteger(pInt) && isArrayLike(val)
? nth(pInt, val)
: (val as ObjRec)[p];
}
return val as R;
});
}
/**
* Retrieves the values at given paths `pathsArr` of `obj`.
* Each path in the `pathsArr` may be any array of keys or
* string of keys separated by `/` or `.` .
*
* Fae.paths([['a', 'b'], ['p', 0, 'q']], {a: {b: 2}, p: [{q: 3}]}); // [2, 3]
* Fae.paths([['a', 'b'], ['p', 'r']], {a: {b: 2}, p: [{q: 3}]}); // [2, undefined]
* Fae.paths([[], ['p', 0, 'q']], {a: {b: 2}, p: [{q: 3}]}); // [ { a: { b: 2 }, p: [ { q: 3 } ] }, 3 ]
* Fae.paths([['a', ''], ['p', 0, 'q']], {a: {b: 2}, p: [{q: 3}]}); // [ undefined, 3 ]
*/
export const paths = curryN(2, _paths) as Paths;