-
Notifications
You must be signed in to change notification settings - Fork 8
/
getRoutes.ts
52 lines (40 loc) · 1.71 KB
/
getRoutes.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
import { getRouteFromPaths } from './getRoutes.utils';
import { EMPTY_PATH } from '../generation/constants';
export const getRoutes = <T>(): T => {
const proxy = new Proxy(['/'], {
get(target: string[], path): string[] {
const targetArray = Array.from(target);
switch (true) {
// TODO: add warning about potential mistake when some route "length" path
case path === 'length':
return targetArray.length as any;
case path === 'toString':
case path === Symbol.toPrimitive:
return (() => getRouteFromPaths(targetArray)) as any;
case path === 'asString':
return getRouteFromPaths(targetArray) as any;
case path === 'asArray': {
return Array.from(targetArray);
}
case path === Symbol.iterator:
return Array.prototype[Symbol.iterator].bind(targetArray);
case path in Array.prototype: {
const updatedTargetPath = Array.prototype[path as any].bind(targetArray);
Object.defineProperty(updatedTargetPath, 'length', { get: () => targetArray.length + 1 });
const nextTuple = [...targetArray, path];
updatedTargetPath[Symbol.iterator] = Array.prototype[Symbol.iterator].bind(nextTuple);
for (let i = 0; i < nextTuple.length; i += 1) {
updatedTargetPath[i] = nextTuple[i];
}
return new Proxy(updatedTargetPath, this);
}
default: {
const nextTuple = path === EMPTY_PATH ? targetArray : [...targetArray, path];
return new Proxy(nextTuple, this) as string[];
}
}
}
});
return (proxy as unknown) as T;
};
export const getPaths = (paths: string[]): string[] => Array.from(paths);