-
Notifications
You must be signed in to change notification settings - Fork 610
/
Copy pathutils.ts
121 lines (109 loc) · 3.4 KB
/
utils.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import type { marshallOptions, unmarshallOptions } from "@aws-sdk/util-dynamodb";
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";
/**
* @internal
*/
export type KeyNodeSelf = null;
/**
* @internal
*/
export const SELF: KeyNodeSelf = null;
/**
* @internal
*/
export type KeyNodeChildren = Record<string, any>;
/**
* @internal
*/
export const ALL_VALUES: KeyNodeChildren = {};
/**
* @internal
*/
export const ALL_MEMBERS: KeyNodeChildren = [];
/**
* @internal
*/
const NEXT_LEVEL = "*";
/**
* @internal
*/
export type KeyNodes = KeyNodeSelf | KeyNodeChildren;
const processObj = (obj: any, processFunc: Function, keyNodes?: KeyNodes): any => {
if (obj !== undefined) {
if (keyNodes == null) {
// Leaf of KeyNode, process the object.
return processFunc(obj);
} else {
const keys = Object.keys(keyNodes);
const goToNextLevel = keys.length === 1 && keys[0] === NEXT_LEVEL;
const someChildren = keys.length >= 1 && !goToNextLevel;
const allChildren = keys.length === 0;
// Not leaf node, process the children.
if (someChildren) {
return processKeysInObj(obj, processFunc, keyNodes as KeyNodeChildren);
} else if (allChildren) {
return processAllKeysInObj(obj, processFunc, SELF);
} else if (goToNextLevel) {
return Object.entries(obj ?? {}).reduce((acc, [k, v]) => {
if (typeof v !== "function") {
acc[k] = processObj(v, processFunc, keyNodes[NEXT_LEVEL]);
}
return acc;
}, (Array.isArray(obj) ? [] : {}) as any);
}
}
}
return undefined;
};
const processKeysInObj = (obj: any, processFunc: Function, keyNodes: KeyNodeChildren) => {
let accumulator: any;
if (Array.isArray(obj)) {
accumulator = [...obj].filter((item) => typeof item !== "function");
} else {
accumulator = {};
for (const [k, v] of Object.entries(obj)) {
if (typeof v !== "function") {
accumulator[k] = v;
}
}
}
for (const [nodeKey, nodes] of Object.entries(keyNodes)) {
if (typeof obj[nodeKey] === "function") {
continue;
}
const processedValue = processObj(obj[nodeKey], processFunc, nodes);
if (processedValue !== undefined && typeof processedValue !== "function") {
accumulator[nodeKey] = processedValue;
}
}
return accumulator;
};
const processAllKeysInObj = (obj: any, processFunc: Function, keyNodes: KeyNodes): any => {
if (Array.isArray(obj)) {
return obj.filter((item) => typeof item !== "function").map((item) => processObj(item, processFunc, keyNodes));
}
return Object.entries(obj).reduce((acc, [key, value]) => {
if (typeof value === "function") {
return acc;
}
const processedValue = processObj(value, processFunc, keyNodes);
if (processedValue !== undefined && typeof processedValue !== "function") {
acc[key] = processedValue;
}
return acc;
}, {} as any);
};
/**
* @internal
*/
export const marshallInput = (obj: any, keyNodes: KeyNodeChildren, options?: marshallOptions) => {
const marshallFunc = (toMarshall: any) => marshall(toMarshall, options);
return processKeysInObj(obj, marshallFunc, keyNodes);
};
/**
* @internal
*/
export const unmarshallOutput = (obj: any, keyNodes: KeyNodeChildren, options?: unmarshallOptions) => {
const unmarshallFunc = (toMarshall: any) => unmarshall(toMarshall, options);
return processKeysInObj(obj, unmarshallFunc, keyNodes);
};