@ls-stack/utils 3.24.0 → 3.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/_media/modules.md +1 -0
- package/docs/arrayUtils/-internal-.md +1 -1
- package/docs/arrayUtils/README.md +12 -12
- package/docs/consoleFmt.md +2 -2
- package/docs/exhaustiveMatch/-internal-.md +1 -1
- package/docs/exhaustiveMatch/README.md +1 -1
- package/docs/filterObjectOrArrayKeys.md +80 -0
- package/docs/modules.md +1 -0
- package/docs/objUtils.md +7 -7
- package/docs/parallelAsyncCalls/-internal-.md +3 -3
- package/docs/parallelAsyncCalls/README.md +1 -1
- package/docs/retryOnError/README.md +1 -1
- package/docs/runShellCmd/README.md +9 -9
- package/docs/safeJson.md +2 -2
- package/docs/saferTyping.md +7 -7
- package/docs/stringUtils/README.md +6 -6
- package/docs/testUtils.md +40 -6
- package/docs/time.md +1 -1
- package/docs/tsResult/README.md +17 -11
- package/docs/typingFnUtils/-internal-.md +1 -1
- package/docs/typingFnUtils/README.md +8 -10
- package/lib/arrayUtils.d.cts +6 -1
- package/lib/arrayUtils.d.ts +6 -1
- package/lib/{chunk-JAPKLFIK.js → chunk-QLD7KG5I.js} +34 -20
- package/lib/chunk-XXYTMSFH.js +240 -0
- package/lib/filterObjectOrArrayKeys.cjs +275 -0
- package/lib/filterObjectOrArrayKeys.d.cts +42 -0
- package/lib/filterObjectOrArrayKeys.d.ts +42 -0
- package/lib/filterObjectOrArrayKeys.js +7 -0
- package/lib/objUtils.d.cts +4 -1
- package/lib/objUtils.d.ts +4 -1
- package/lib/parallelAsyncCalls.cjs +4 -1
- package/lib/parallelAsyncCalls.d.cts +4 -1
- package/lib/parallelAsyncCalls.d.ts +4 -1
- package/lib/parallelAsyncCalls.js +4 -1
- package/lib/retryOnError.d.cts +2 -0
- package/lib/retryOnError.d.ts +2 -0
- package/lib/runShellCmd.d.cts +17 -0
- package/lib/runShellCmd.d.ts +17 -0
- package/lib/safeJson.d.cts +8 -2
- package/lib/safeJson.d.ts +8 -2
- package/lib/saferTyping.d.cts +3 -0
- package/lib/saferTyping.d.ts +3 -0
- package/lib/stringUtils.d.cts +1 -0
- package/lib/stringUtils.d.ts +1 -0
- package/lib/testUtils.cjs +273 -106
- package/lib/testUtils.d.cts +81 -2
- package/lib/testUtils.d.ts +81 -2
- package/lib/testUtils.js +10 -87
- package/lib/tsResult.d.cts +31 -7
- package/lib/tsResult.d.ts +31 -7
- package/lib/typingFnUtils.d.cts +20 -6
- package/lib/typingFnUtils.d.ts +20 -6
- package/lib/yamlStringify.cjs +34 -20
- package/lib/yamlStringify.js +1 -1
- package/package.json +5 -1
package/lib/retryOnError.d.ts
CHANGED
|
@@ -18,6 +18,8 @@ type RetryOptions = {
|
|
|
18
18
|
* @param fn - Function to retry that receives context with retry count
|
|
19
19
|
* @param maxRetries - Maximum number of retries
|
|
20
20
|
* @param options - Configuration options
|
|
21
|
+
* @param retry
|
|
22
|
+
* @param originalMaxRetries
|
|
21
23
|
* @returns Promise resolving to the function result or rejecting with the final error
|
|
22
24
|
*
|
|
23
25
|
* @example
|
package/lib/runShellCmd.d.cts
CHANGED
|
@@ -13,6 +13,14 @@ type RunCmdOptions = {
|
|
|
13
13
|
noCiColorForce?: boolean;
|
|
14
14
|
};
|
|
15
15
|
/**
|
|
16
|
+
* @param label
|
|
17
|
+
* @param command
|
|
18
|
+
* @param root0
|
|
19
|
+
* @param root0.mock
|
|
20
|
+
* @param root0.silent
|
|
21
|
+
* @param root0.throwOnError
|
|
22
|
+
* @param root0.cwd
|
|
23
|
+
* @param root0.noCiColorForce
|
|
16
24
|
* @deprecated This utility has been moved to @ls-stack/node-utils. Please update your imports:
|
|
17
25
|
* ```
|
|
18
26
|
* // Old (deprecated)
|
|
@@ -24,6 +32,9 @@ type RunCmdOptions = {
|
|
|
24
32
|
*/
|
|
25
33
|
declare function runCmd(label: string | null, command: string | string[], { mock, silent, throwOnError, cwd, noCiColorForce, }?: RunCmdOptions): Promise<CmdResult>;
|
|
26
34
|
/**
|
|
35
|
+
* @param label
|
|
36
|
+
* @param cmd
|
|
37
|
+
* @param onResult
|
|
27
38
|
* @deprecated This utility has been moved to @ls-stack/node-utils. Please update your imports:
|
|
28
39
|
* ```
|
|
29
40
|
* // Old (deprecated)
|
|
@@ -35,6 +46,10 @@ declare function runCmd(label: string | null, command: string | string[], { mock
|
|
|
35
46
|
*/
|
|
36
47
|
declare function concurrentCmd(label: string, cmd: string | string[], onResult: (result: CmdResult) => void): Promise<() => void>;
|
|
37
48
|
/**
|
|
49
|
+
* @param label
|
|
50
|
+
* @param command
|
|
51
|
+
* @param root0
|
|
52
|
+
* @param root0.silent
|
|
38
53
|
* @deprecated This utility has been moved to @ls-stack/node-utils. Please update your imports:
|
|
39
54
|
* ```
|
|
40
55
|
* // Old (deprecated)
|
|
@@ -48,6 +63,7 @@ declare function runCmdUnwrap(label: string | null, command: string | string[],
|
|
|
48
63
|
silent?: boolean | 'timeOnly';
|
|
49
64
|
}): Promise<string>;
|
|
50
65
|
/**
|
|
66
|
+
* @param command
|
|
51
67
|
* @deprecated This utility has been moved to @ls-stack/node-utils. Please update your imports:
|
|
52
68
|
* ```
|
|
53
69
|
* // Old (deprecated)
|
|
@@ -59,6 +75,7 @@ declare function runCmdUnwrap(label: string | null, command: string | string[],
|
|
|
59
75
|
*/
|
|
60
76
|
declare function runCmdSilent(command: string | string[]): Promise<CmdResult>;
|
|
61
77
|
/**
|
|
78
|
+
* @param command
|
|
62
79
|
* @deprecated This utility has been moved to @ls-stack/node-utils. Please update your imports:
|
|
63
80
|
* ```
|
|
64
81
|
* // Old (deprecated)
|
package/lib/runShellCmd.d.ts
CHANGED
|
@@ -13,6 +13,14 @@ type RunCmdOptions = {
|
|
|
13
13
|
noCiColorForce?: boolean;
|
|
14
14
|
};
|
|
15
15
|
/**
|
|
16
|
+
* @param label
|
|
17
|
+
* @param command
|
|
18
|
+
* @param root0
|
|
19
|
+
* @param root0.mock
|
|
20
|
+
* @param root0.silent
|
|
21
|
+
* @param root0.throwOnError
|
|
22
|
+
* @param root0.cwd
|
|
23
|
+
* @param root0.noCiColorForce
|
|
16
24
|
* @deprecated This utility has been moved to @ls-stack/node-utils. Please update your imports:
|
|
17
25
|
* ```
|
|
18
26
|
* // Old (deprecated)
|
|
@@ -24,6 +32,9 @@ type RunCmdOptions = {
|
|
|
24
32
|
*/
|
|
25
33
|
declare function runCmd(label: string | null, command: string | string[], { mock, silent, throwOnError, cwd, noCiColorForce, }?: RunCmdOptions): Promise<CmdResult>;
|
|
26
34
|
/**
|
|
35
|
+
* @param label
|
|
36
|
+
* @param cmd
|
|
37
|
+
* @param onResult
|
|
27
38
|
* @deprecated This utility has been moved to @ls-stack/node-utils. Please update your imports:
|
|
28
39
|
* ```
|
|
29
40
|
* // Old (deprecated)
|
|
@@ -35,6 +46,10 @@ declare function runCmd(label: string | null, command: string | string[], { mock
|
|
|
35
46
|
*/
|
|
36
47
|
declare function concurrentCmd(label: string, cmd: string | string[], onResult: (result: CmdResult) => void): Promise<() => void>;
|
|
37
48
|
/**
|
|
49
|
+
* @param label
|
|
50
|
+
* @param command
|
|
51
|
+
* @param root0
|
|
52
|
+
* @param root0.silent
|
|
38
53
|
* @deprecated This utility has been moved to @ls-stack/node-utils. Please update your imports:
|
|
39
54
|
* ```
|
|
40
55
|
* // Old (deprecated)
|
|
@@ -48,6 +63,7 @@ declare function runCmdUnwrap(label: string | null, command: string | string[],
|
|
|
48
63
|
silent?: boolean | 'timeOnly';
|
|
49
64
|
}): Promise<string>;
|
|
50
65
|
/**
|
|
66
|
+
* @param command
|
|
51
67
|
* @deprecated This utility has been moved to @ls-stack/node-utils. Please update your imports:
|
|
52
68
|
* ```
|
|
53
69
|
* // Old (deprecated)
|
|
@@ -59,6 +75,7 @@ declare function runCmdUnwrap(label: string | null, command: string | string[],
|
|
|
59
75
|
*/
|
|
60
76
|
declare function runCmdSilent(command: string | string[]): Promise<CmdResult>;
|
|
61
77
|
/**
|
|
78
|
+
* @param command
|
|
62
79
|
* @deprecated This utility has been moved to @ls-stack/node-utils. Please update your imports:
|
|
63
80
|
* ```
|
|
64
81
|
* // Old (deprecated)
|
package/lib/safeJson.d.cts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* JSON.stringify can throw if the value is circular or contains functions, this function catches those errors and returns undefined
|
|
3
|
+
* @param value
|
|
4
|
+
*/
|
|
2
5
|
declare function safeJsonStringify(value: unknown): string | undefined;
|
|
3
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* JSON.parse can throw if the value is not valid JSON, this function catches those errors and returns undefined
|
|
8
|
+
* @param value
|
|
9
|
+
*/
|
|
4
10
|
declare function safeJsonParse(value: string): unknown;
|
|
5
11
|
|
|
6
12
|
export { safeJsonParse, safeJsonStringify };
|
package/lib/safeJson.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* JSON.stringify can throw if the value is circular or contains functions, this function catches those errors and returns undefined
|
|
3
|
+
* @param value
|
|
4
|
+
*/
|
|
2
5
|
declare function safeJsonStringify(value: unknown): string | undefined;
|
|
3
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* JSON.parse can throw if the value is not valid JSON, this function catches those errors and returns undefined
|
|
8
|
+
* @param value
|
|
9
|
+
*/
|
|
4
10
|
declare function safeJsonParse(value: string): unknown;
|
|
5
11
|
|
|
6
12
|
export { safeJsonParse, safeJsonStringify };
|
package/lib/saferTyping.d.cts
CHANGED
|
@@ -8,12 +8,14 @@ type EmptyObject = Record<string, never>;
|
|
|
8
8
|
/**
|
|
9
9
|
* Cast a value to `any` type. Use this when you have legit usage of `any` casting.
|
|
10
10
|
*
|
|
11
|
+
* @param value
|
|
11
12
|
* @template V (optional) - When used enforces that the casted value is assignable to the type V, use it for safer casts
|
|
12
13
|
*/
|
|
13
14
|
declare function __LEGIT_ANY_CAST__<V = unknown>(value: V): __LEGIT_ANY__;
|
|
14
15
|
/**
|
|
15
16
|
* Cast a value to a specific type T. Use this when you have legit usage of type assertion.
|
|
16
17
|
*
|
|
18
|
+
* @param value
|
|
17
19
|
* @template T - The type to cast to
|
|
18
20
|
* @template V (optional) - When used enforces that the casted value is assignable to the type V, use it for safer casts
|
|
19
21
|
*/
|
|
@@ -21,6 +23,7 @@ declare function __LEGIT_CAST__<T, V = unknown>(value: V): T;
|
|
|
21
23
|
/**
|
|
22
24
|
* Refine a value to a specific type T. Use this when you have legit usage of type assertion.
|
|
23
25
|
*
|
|
26
|
+
* @param value
|
|
24
27
|
* @template T - The type to cast to
|
|
25
28
|
* @template V (optional) - When used enforces that the casted value is assignable to the type V, use it for safer casts
|
|
26
29
|
*/
|
package/lib/saferTyping.d.ts
CHANGED
|
@@ -8,12 +8,14 @@ type EmptyObject = Record<string, never>;
|
|
|
8
8
|
/**
|
|
9
9
|
* Cast a value to `any` type. Use this when you have legit usage of `any` casting.
|
|
10
10
|
*
|
|
11
|
+
* @param value
|
|
11
12
|
* @template V (optional) - When used enforces that the casted value is assignable to the type V, use it for safer casts
|
|
12
13
|
*/
|
|
13
14
|
declare function __LEGIT_ANY_CAST__<V = unknown>(value: V): __LEGIT_ANY__;
|
|
14
15
|
/**
|
|
15
16
|
* Cast a value to a specific type T. Use this when you have legit usage of type assertion.
|
|
16
17
|
*
|
|
18
|
+
* @param value
|
|
17
19
|
* @template T - The type to cast to
|
|
18
20
|
* @template V (optional) - When used enforces that the casted value is assignable to the type V, use it for safer casts
|
|
19
21
|
*/
|
|
@@ -21,6 +23,7 @@ declare function __LEGIT_CAST__<T, V = unknown>(value: V): T;
|
|
|
21
23
|
/**
|
|
22
24
|
* Refine a value to a specific type T. Use this when you have legit usage of type assertion.
|
|
23
25
|
*
|
|
26
|
+
* @param value
|
|
24
27
|
* @template T - The type to cast to
|
|
25
28
|
* @template V (optional) - When used enforces that the casted value is assignable to the type V, use it for safer casts
|
|
26
29
|
*/
|
package/lib/stringUtils.d.cts
CHANGED
package/lib/stringUtils.d.ts
CHANGED
package/lib/testUtils.cjs
CHANGED
|
@@ -131,6 +131,239 @@ function deepEqual(foo, bar, maxDepth = 20) {
|
|
|
131
131
|
return foo !== foo && bar !== bar;
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
// src/filterObjectOrArrayKeys.ts
|
|
135
|
+
function filterObjectOrArrayKeys(objOrArray, {
|
|
136
|
+
filterKeys,
|
|
137
|
+
rejectKeys,
|
|
138
|
+
rejectEmptyObjectsInArray = true
|
|
139
|
+
}) {
|
|
140
|
+
const toArray = (v) => v === void 0 ? [] : Array.isArray(v) ? v : [v];
|
|
141
|
+
const filterPatternsRaw = toArray(filterKeys);
|
|
142
|
+
const rejectPatternsRaw = toArray(rejectKeys);
|
|
143
|
+
const hasFilters = filterPatternsRaw.length > 0;
|
|
144
|
+
const hasRejects = rejectPatternsRaw.length > 0;
|
|
145
|
+
function parsePattern(pattern) {
|
|
146
|
+
const tokens = [];
|
|
147
|
+
let i = 0;
|
|
148
|
+
const n = pattern.length;
|
|
149
|
+
const pushKey = (name) => {
|
|
150
|
+
if (name.length === 0) return;
|
|
151
|
+
tokens.push({ type: "KEY", name });
|
|
152
|
+
};
|
|
153
|
+
while (i < n) {
|
|
154
|
+
const ch = pattern[i];
|
|
155
|
+
if (ch === ".") {
|
|
156
|
+
i += 1;
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (ch === "[") {
|
|
160
|
+
const end = pattern.indexOf("]", i + 1);
|
|
161
|
+
const inside = end === -1 ? pattern.slice(i + 1) : pattern.slice(i + 1, end);
|
|
162
|
+
if (inside === "*") {
|
|
163
|
+
tokens.push({ type: "INDEX_ANY" });
|
|
164
|
+
} else if (inside.includes("-")) {
|
|
165
|
+
const parts = inside.split("-");
|
|
166
|
+
const startStr = parts[0] ?? "";
|
|
167
|
+
const endStr = parts[1] ?? "";
|
|
168
|
+
const start = parseInt(startStr, 10);
|
|
169
|
+
const endNum = endStr === "*" ? null : parseInt(endStr, 10);
|
|
170
|
+
tokens.push({
|
|
171
|
+
type: "INDEX_RANGE",
|
|
172
|
+
start,
|
|
173
|
+
end: endNum === null || Number.isFinite(endNum) ? endNum : null
|
|
174
|
+
});
|
|
175
|
+
} else if (inside.length > 0) {
|
|
176
|
+
const idx = parseInt(inside, 10);
|
|
177
|
+
tokens.push({ type: "INDEX", index: idx });
|
|
178
|
+
}
|
|
179
|
+
i = end === -1 ? n : end + 1;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (ch === "*") {
|
|
183
|
+
if (pattern[i + 1] === "*") {
|
|
184
|
+
tokens.push({ type: "WILDCARD_ANY" });
|
|
185
|
+
i += 2;
|
|
186
|
+
let j2 = i;
|
|
187
|
+
while (j2 < n) {
|
|
188
|
+
const c = pattern[j2];
|
|
189
|
+
if (c === "." || c === "[") break;
|
|
190
|
+
j2 += 1;
|
|
191
|
+
}
|
|
192
|
+
if (j2 > i) {
|
|
193
|
+
pushKey(pattern.slice(i, j2));
|
|
194
|
+
i = j2;
|
|
195
|
+
}
|
|
196
|
+
continue;
|
|
197
|
+
} else {
|
|
198
|
+
tokens.push({ type: "WILDCARD_ONE" });
|
|
199
|
+
i += 1;
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
let j = i;
|
|
204
|
+
while (j < n) {
|
|
205
|
+
const c = pattern[j];
|
|
206
|
+
if (c === "." || c === "[") break;
|
|
207
|
+
j += 1;
|
|
208
|
+
}
|
|
209
|
+
pushKey(pattern.slice(i, j));
|
|
210
|
+
i = j;
|
|
211
|
+
}
|
|
212
|
+
return tokens;
|
|
213
|
+
}
|
|
214
|
+
const filterPatterns = filterPatternsRaw.map(parsePattern);
|
|
215
|
+
const rejectPatterns = rejectPatternsRaw.map(parsePattern);
|
|
216
|
+
function matchPath(path, pattern) {
|
|
217
|
+
function rec(pi, pti) {
|
|
218
|
+
if (pti >= pattern.length) return pi === path.length;
|
|
219
|
+
const pt = pattern[pti];
|
|
220
|
+
if (pt.type === "WILDCARD_ANY") {
|
|
221
|
+
if (rec(pi, pti + 1)) return true;
|
|
222
|
+
if (pi < path.length) return rec(pi + 1, pti);
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
if (pt.type === "WILDCARD_ONE") {
|
|
226
|
+
let j = pi;
|
|
227
|
+
let sawKey = false;
|
|
228
|
+
while (j < path.length) {
|
|
229
|
+
if (path[j].type === "KEY") sawKey = true;
|
|
230
|
+
if (sawKey && rec(j, pti + 1)) return true;
|
|
231
|
+
j += 1;
|
|
232
|
+
}
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
if (pi >= path.length) return false;
|
|
236
|
+
const ct = path[pi];
|
|
237
|
+
switch (pt.type) {
|
|
238
|
+
case "KEY":
|
|
239
|
+
if (ct.type === "KEY" && ct.name === pt.name)
|
|
240
|
+
return rec(pi + 1, pti + 1);
|
|
241
|
+
if (ct.type === "INDEX") return rec(pi + 1, pti);
|
|
242
|
+
return false;
|
|
243
|
+
case "INDEX":
|
|
244
|
+
if (ct.type === "INDEX" && ct.index === pt.index)
|
|
245
|
+
return rec(pi + 1, pti + 1);
|
|
246
|
+
return false;
|
|
247
|
+
case "INDEX_ANY":
|
|
248
|
+
if (ct.type === "INDEX") return rec(pi + 1, pti + 1);
|
|
249
|
+
return false;
|
|
250
|
+
case "INDEX_RANGE":
|
|
251
|
+
if (ct.type === "INDEX") {
|
|
252
|
+
const okLower = ct.index >= pt.start;
|
|
253
|
+
const okUpper = pt.end === null ? true : ct.index <= pt.end;
|
|
254
|
+
if (okLower && okUpper) return rec(pi + 1, pti + 1);
|
|
255
|
+
}
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return rec(0, 0);
|
|
260
|
+
}
|
|
261
|
+
const matchesAnyFilter = (path) => filterPatterns.some((p) => matchPath(path, p));
|
|
262
|
+
const matchesAnyReject = (path) => rejectPatterns.some((p) => matchPath(path, p));
|
|
263
|
+
const build = (value, path, allowedByFilter, stack2, isRoot, parentIsArray) => {
|
|
264
|
+
if (Array.isArray(value)) {
|
|
265
|
+
if (stack2.has(value)) {
|
|
266
|
+
throw new TypeError("Circular references are not supported");
|
|
267
|
+
}
|
|
268
|
+
stack2.add(value);
|
|
269
|
+
const out = [];
|
|
270
|
+
const includeAllChildren = allowedByFilter || !hasFilters;
|
|
271
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
272
|
+
const childPath = path.concat({ type: "INDEX", index });
|
|
273
|
+
if (hasRejects && matchesAnyReject(childPath)) continue;
|
|
274
|
+
const child = value[index];
|
|
275
|
+
const directInclude = hasFilters ? matchesAnyFilter(childPath) : true;
|
|
276
|
+
const childAllowed = includeAllChildren || directInclude;
|
|
277
|
+
if (isPlainObject(child) || Array.isArray(child)) {
|
|
278
|
+
const builtChild = build(
|
|
279
|
+
child,
|
|
280
|
+
childPath,
|
|
281
|
+
childAllowed,
|
|
282
|
+
stack2,
|
|
283
|
+
false,
|
|
284
|
+
true
|
|
285
|
+
);
|
|
286
|
+
if (builtChild !== void 0) {
|
|
287
|
+
out.push(builtChild);
|
|
288
|
+
}
|
|
289
|
+
} else {
|
|
290
|
+
if (childAllowed) {
|
|
291
|
+
out.push(child);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
stack2.delete(value);
|
|
296
|
+
const filteredOut = rejectEmptyObjectsInArray ? out.filter(
|
|
297
|
+
(item) => !(isPlainObject(item) && Object.keys(item).length === 0)
|
|
298
|
+
) : out;
|
|
299
|
+
if (filteredOut.length === 0 && !allowedByFilter && !isRoot)
|
|
300
|
+
return void 0;
|
|
301
|
+
return filteredOut;
|
|
302
|
+
}
|
|
303
|
+
if (isPlainObject(value)) {
|
|
304
|
+
if (stack2.has(value)) {
|
|
305
|
+
throw new TypeError("Circular references are not supported");
|
|
306
|
+
}
|
|
307
|
+
stack2.add(value);
|
|
308
|
+
const result = {};
|
|
309
|
+
const includeAllChildren = allowedByFilter || !hasFilters;
|
|
310
|
+
for (const key of Object.keys(value)) {
|
|
311
|
+
const childPath = path.concat({ type: "KEY", name: key });
|
|
312
|
+
if (hasRejects && matchesAnyReject(childPath)) continue;
|
|
313
|
+
const val = value[key];
|
|
314
|
+
const directInclude = hasFilters ? matchesAnyFilter(childPath) : true;
|
|
315
|
+
const childAllowed = includeAllChildren || directInclude;
|
|
316
|
+
if (isPlainObject(val) || Array.isArray(val)) {
|
|
317
|
+
const builtChild = build(
|
|
318
|
+
val,
|
|
319
|
+
childPath,
|
|
320
|
+
childAllowed,
|
|
321
|
+
stack2,
|
|
322
|
+
false,
|
|
323
|
+
false
|
|
324
|
+
);
|
|
325
|
+
if (builtChild === void 0) {
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
if (Array.isArray(builtChild) && builtChild.length === 0 && !childAllowed) {
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
if (isPlainObject(builtChild) && Object.keys(builtChild).length === 0 && !childAllowed) {
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
result[key] = builtChild;
|
|
335
|
+
} else {
|
|
336
|
+
if (childAllowed) {
|
|
337
|
+
result[key] = val;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
stack2.delete(value);
|
|
342
|
+
if (Object.keys(result).length === 0 && !allowedByFilter && !isRoot) {
|
|
343
|
+
if (parentIsArray && !rejectEmptyObjectsInArray) {
|
|
344
|
+
return {};
|
|
345
|
+
}
|
|
346
|
+
return void 0;
|
|
347
|
+
}
|
|
348
|
+
return result;
|
|
349
|
+
}
|
|
350
|
+
return allowedByFilter || !hasFilters ? value : void 0;
|
|
351
|
+
};
|
|
352
|
+
const startPath = [];
|
|
353
|
+
const initialAllowed = !hasFilters;
|
|
354
|
+
const stack = /* @__PURE__ */ new WeakSet();
|
|
355
|
+
const built = build(
|
|
356
|
+
objOrArray,
|
|
357
|
+
startPath,
|
|
358
|
+
initialAllowed,
|
|
359
|
+
stack,
|
|
360
|
+
true,
|
|
361
|
+
false
|
|
362
|
+
);
|
|
363
|
+
if (built === void 0) return Array.isArray(objOrArray) ? [] : {};
|
|
364
|
+
return built;
|
|
365
|
+
}
|
|
366
|
+
|
|
134
367
|
// src/mathUtils.ts
|
|
135
368
|
function clampMin(value, min) {
|
|
136
369
|
return value < min ? min : value;
|
|
@@ -197,12 +430,12 @@ function yamlStringify(obj, {
|
|
|
197
430
|
addRootObjSpaces = "beforeAndAfter"
|
|
198
431
|
} = {}) {
|
|
199
432
|
if (isObject(obj) || Array.isArray(obj) || typeof obj === "function") {
|
|
200
|
-
return `${stringifyValue(obj, "", maxLineLength, !!showUndefined, maxDepth, 0, collapseObjects, addRootObjSpaces)}
|
|
433
|
+
return `${stringifyValue(obj, "", maxLineLength, !!showUndefined, maxDepth, 0, collapseObjects, addRootObjSpaces, false)}
|
|
201
434
|
`;
|
|
202
435
|
}
|
|
203
436
|
return JSON.stringify(obj) || "undefined";
|
|
204
437
|
}
|
|
205
|
-
function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, depth, collapseObjects, addObjSpaces) {
|
|
438
|
+
function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, depth, collapseObjects, addObjSpaces, isArrayItem) {
|
|
206
439
|
let result = "";
|
|
207
440
|
const childIndent = `${indent} `;
|
|
208
441
|
if (isPlainObject(value)) {
|
|
@@ -221,7 +454,8 @@ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, d
|
|
|
221
454
|
return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
|
|
222
455
|
}
|
|
223
456
|
);
|
|
224
|
-
|
|
457
|
+
const shouldCollapse = isArrayItem ? entries.length > 1 : entries.length > 0;
|
|
458
|
+
if (isSimpleObject && shouldCollapse) {
|
|
225
459
|
let line = "{ ";
|
|
226
460
|
line += entries.map(([key, val]) => {
|
|
227
461
|
let valueStr;
|
|
@@ -268,20 +502,29 @@ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, d
|
|
|
268
502
|
maxDepth,
|
|
269
503
|
depth + 1,
|
|
270
504
|
collapseObjects,
|
|
271
|
-
addObjSpaces
|
|
505
|
+
addObjSpaces,
|
|
506
|
+
false
|
|
272
507
|
);
|
|
273
|
-
const willBeCollapsed = isObject(objVal) && (Object.keys(objVal).length === 0 || collapseObjects && depth + 1 > 0 &&
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
508
|
+
const willBeCollapsed = isObject(objVal) && (Object.keys(objVal).length === 0 || collapseObjects && depth + 1 > 0 && (() => {
|
|
509
|
+
const filteredEntries = Object.entries(objVal).filter(([, val]) => val !== void 0 || showUndefined);
|
|
510
|
+
const shouldCollapseThis = isArrayItem ? filteredEntries.length > 1 : filteredEntries.length > 0;
|
|
511
|
+
return shouldCollapseThis && filteredEntries.every(([, val]) => {
|
|
512
|
+
if (typeof val === "string") {
|
|
513
|
+
return !val.includes("'") && !val.includes('"') && !val.includes("\\");
|
|
514
|
+
}
|
|
515
|
+
return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
|
|
516
|
+
});
|
|
517
|
+
})());
|
|
518
|
+
const prevWasCollapsed = prevValue && isObject(prevValue) && (Object.keys(prevValue).length === 0 || collapseObjects && depth + 1 > 0 && (() => {
|
|
519
|
+
const filteredEntries = Object.entries(prevValue).filter(([, val]) => val !== void 0 || showUndefined);
|
|
520
|
+
const shouldCollapseThis = isArrayItem ? filteredEntries.length > 1 : filteredEntries.length > 0;
|
|
521
|
+
return shouldCollapseThis && filteredEntries.every(([, val]) => {
|
|
522
|
+
if (typeof val === "string") {
|
|
523
|
+
return !val.includes("'") && !val.includes('"') && !val.includes("\\");
|
|
524
|
+
}
|
|
525
|
+
return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
|
|
526
|
+
});
|
|
527
|
+
})());
|
|
285
528
|
if (!afterSpaceWasAdded && indent === "" && isObject(objVal) && !willBeCollapsed && prevValue && !prevWasCollapsed && (addObjSpaces === "before" || addObjSpaces === "beforeAndAfter")) {
|
|
286
529
|
result += "\n";
|
|
287
530
|
}
|
|
@@ -344,7 +587,8 @@ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, d
|
|
|
344
587
|
maxDepth,
|
|
345
588
|
depth + 1,
|
|
346
589
|
collapseObjects,
|
|
347
|
-
addObjSpaces
|
|
590
|
+
addObjSpaces,
|
|
591
|
+
true
|
|
348
592
|
);
|
|
349
593
|
}).join(", ");
|
|
350
594
|
line += "]";
|
|
@@ -368,7 +612,8 @@ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, d
|
|
|
368
612
|
maxDepth,
|
|
369
613
|
depth + 1,
|
|
370
614
|
collapseObjects,
|
|
371
|
-
addObjSpaces
|
|
615
|
+
addObjSpaces,
|
|
616
|
+
true
|
|
372
617
|
);
|
|
373
618
|
arrayString = arrayString.trimStart();
|
|
374
619
|
result += arrayString;
|
|
@@ -381,7 +626,8 @@ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, d
|
|
|
381
626
|
maxDepth,
|
|
382
627
|
depth + 1,
|
|
383
628
|
collapseObjects,
|
|
384
|
-
addObjSpaces
|
|
629
|
+
addObjSpaces,
|
|
630
|
+
true
|
|
385
631
|
);
|
|
386
632
|
}
|
|
387
633
|
result += "\n";
|
|
@@ -435,7 +681,8 @@ ${indent}${line}
|
|
|
435
681
|
maxDepth,
|
|
436
682
|
depth + 1,
|
|
437
683
|
collapseObjects,
|
|
438
|
-
addObjSpaces
|
|
684
|
+
addObjSpaces,
|
|
685
|
+
false
|
|
439
686
|
);
|
|
440
687
|
}
|
|
441
688
|
return JSON.stringify(value);
|
|
@@ -753,91 +1000,6 @@ function waitController() {
|
|
|
753
1000
|
}
|
|
754
1001
|
};
|
|
755
1002
|
}
|
|
756
|
-
function matchesKeyPattern(path, pattern) {
|
|
757
|
-
if (path === pattern) {
|
|
758
|
-
return true;
|
|
759
|
-
}
|
|
760
|
-
if (pattern.includes("*")) {
|
|
761
|
-
const regexPattern = pattern.replace(/\./g, "\\.").replace(/\*/g, "[^.]*");
|
|
762
|
-
const regex = new RegExp(`^${regexPattern}$`);
|
|
763
|
-
return regex.test(path);
|
|
764
|
-
}
|
|
765
|
-
return false;
|
|
766
|
-
}
|
|
767
|
-
function isParentOfPattern(path, pattern) {
|
|
768
|
-
if (pattern.includes("*")) {
|
|
769
|
-
const patternParts = pattern.split(".");
|
|
770
|
-
const pathParts = path.split(".");
|
|
771
|
-
if (pathParts.length >= patternParts.length) {
|
|
772
|
-
return false;
|
|
773
|
-
}
|
|
774
|
-
for (let i = 0; i < pathParts.length; i++) {
|
|
775
|
-
const pathPart = pathParts[i];
|
|
776
|
-
const patternPart = patternParts[i];
|
|
777
|
-
if (patternPart === "*") {
|
|
778
|
-
continue;
|
|
779
|
-
}
|
|
780
|
-
if (pathPart !== patternPart) {
|
|
781
|
-
return false;
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
return true;
|
|
785
|
-
} else {
|
|
786
|
-
return pattern.startsWith(`${path}.`);
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
function applyKeyFiltering(value, { rejectKeys, filterKeys }, currentPath = "", visited = /* @__PURE__ */ new Set()) {
|
|
790
|
-
if (!isPlainObject(value) && !Array.isArray(value)) {
|
|
791
|
-
return value;
|
|
792
|
-
}
|
|
793
|
-
if (Array.isArray(value)) {
|
|
794
|
-
if (visited.has(value)) {
|
|
795
|
-
throw new Error("Circular reference detected in array during key filtering");
|
|
796
|
-
}
|
|
797
|
-
visited.add(value);
|
|
798
|
-
try {
|
|
799
|
-
return value.map(
|
|
800
|
-
(item, index) => applyKeyFiltering(item, { rejectKeys, filterKeys }, currentPath ? `${currentPath}[${index}]` : `[${index}]`, visited)
|
|
801
|
-
);
|
|
802
|
-
} finally {
|
|
803
|
-
visited.delete(value);
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
if (isPlainObject(value)) {
|
|
807
|
-
if (visited.has(value)) {
|
|
808
|
-
throw new Error("Circular reference detected in object during key filtering");
|
|
809
|
-
}
|
|
810
|
-
visited.add(value);
|
|
811
|
-
try {
|
|
812
|
-
const result = {};
|
|
813
|
-
for (const [key, itemValue] of Object.entries(value)) {
|
|
814
|
-
const fullPath = currentPath ? `${currentPath}.${key}` : key;
|
|
815
|
-
if (rejectKeys?.some(
|
|
816
|
-
(rejectPath) => matchesKeyPattern(fullPath, rejectPath) || matchesKeyPattern(key, rejectPath)
|
|
817
|
-
)) {
|
|
818
|
-
continue;
|
|
819
|
-
}
|
|
820
|
-
if (filterKeys) {
|
|
821
|
-
const shouldInclude = filterKeys.some(
|
|
822
|
-
(filterPath) => (
|
|
823
|
-
// Exact match
|
|
824
|
-
matchesKeyPattern(fullPath, filterPath) || matchesKeyPattern(key, filterPath) || // This path is a parent of a filter pattern (so we include it to allow children)
|
|
825
|
-
isParentOfPattern(fullPath, filterPath)
|
|
826
|
-
)
|
|
827
|
-
);
|
|
828
|
-
if (!shouldInclude) {
|
|
829
|
-
continue;
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
result[key] = applyKeyFiltering(itemValue, { rejectKeys, filterKeys }, fullPath, visited);
|
|
833
|
-
}
|
|
834
|
-
return result;
|
|
835
|
-
} finally {
|
|
836
|
-
visited.delete(value);
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
return value;
|
|
840
|
-
}
|
|
841
1003
|
function compactSnapshot(value, {
|
|
842
1004
|
collapseObjects = true,
|
|
843
1005
|
maxLineLength = 100,
|
|
@@ -849,7 +1011,12 @@ function compactSnapshot(value, {
|
|
|
849
1011
|
} = {}) {
|
|
850
1012
|
let processedValue = value;
|
|
851
1013
|
if (rejectKeys || filterKeys) {
|
|
852
|
-
processedValue
|
|
1014
|
+
if (isPlainObject(processedValue) || Array.isArray(processedValue)) {
|
|
1015
|
+
processedValue = filterObjectOrArrayKeys(processedValue, {
|
|
1016
|
+
rejectKeys,
|
|
1017
|
+
filterKeys
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
853
1020
|
}
|
|
854
1021
|
processedValue = showBooleansAs ? replaceBooleansWithEmoji(processedValue, showBooleansAs) : processedValue;
|
|
855
1022
|
return `
|