@ls-stack/utils 3.24.1 → 3.26.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 +82 -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-FXRZ4RQU.js +257 -0
- package/lib/{chunk-JAPKLFIK.js → chunk-QLD7KG5I.js} +34 -20
- package/lib/filterObjectOrArrayKeys.cjs +292 -0
- package/lib/filterObjectOrArrayKeys.d.cts +44 -0
- package/lib/filterObjectOrArrayKeys.d.ts +44 -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 +290 -144
- package/lib/testUtils.d.cts +40 -12
- package/lib/testUtils.d.ts +40 -12
- package/lib/testUtils.js +10 -125
- 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/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,256 @@ 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
|
+
const filterPatterns = filterPatternsRaw.map(parsePattern);
|
|
146
|
+
const rejectPatterns = rejectPatternsRaw.map(parsePattern);
|
|
147
|
+
function matchPath(path, pattern) {
|
|
148
|
+
function rec(pi, pti) {
|
|
149
|
+
if (pti >= pattern.length) return pi === path.length;
|
|
150
|
+
const pt = pattern[pti];
|
|
151
|
+
if (pt.type === "WILDCARD_ANY") {
|
|
152
|
+
if (rec(pi, pti + 1)) return true;
|
|
153
|
+
if (pi < path.length) return rec(pi + 1, pti);
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
if (pt.type === "WILDCARD_ONE") {
|
|
157
|
+
let j = pi;
|
|
158
|
+
let sawKey = false;
|
|
159
|
+
while (j < path.length) {
|
|
160
|
+
if (path[j].type === "KEY") sawKey = true;
|
|
161
|
+
if (sawKey && rec(j, pti + 1)) return true;
|
|
162
|
+
j += 1;
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
if (pi >= path.length) return false;
|
|
167
|
+
const ct = path[pi];
|
|
168
|
+
switch (pt.type) {
|
|
169
|
+
case "KEY":
|
|
170
|
+
if (ct.type === "KEY" && ct.name === pt.name)
|
|
171
|
+
return rec(pi + 1, pti + 1);
|
|
172
|
+
if (ct.type === "INDEX") return rec(pi + 1, pti);
|
|
173
|
+
return false;
|
|
174
|
+
case "MULTI_KEY":
|
|
175
|
+
if (ct.type === "KEY" && pt.names.includes(ct.name))
|
|
176
|
+
return rec(pi + 1, pti + 1);
|
|
177
|
+
if (ct.type === "INDEX") return rec(pi + 1, pti);
|
|
178
|
+
return false;
|
|
179
|
+
case "INDEX":
|
|
180
|
+
if (ct.type === "INDEX" && ct.index === pt.index)
|
|
181
|
+
return rec(pi + 1, pti + 1);
|
|
182
|
+
return false;
|
|
183
|
+
case "INDEX_ANY":
|
|
184
|
+
if (ct.type === "INDEX") return rec(pi + 1, pti + 1);
|
|
185
|
+
return false;
|
|
186
|
+
case "INDEX_RANGE":
|
|
187
|
+
if (ct.type === "INDEX") {
|
|
188
|
+
const okLower = ct.index >= pt.start;
|
|
189
|
+
const okUpper = pt.end === null ? true : ct.index <= pt.end;
|
|
190
|
+
if (okLower && okUpper) return rec(pi + 1, pti + 1);
|
|
191
|
+
}
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return rec(0, 0);
|
|
196
|
+
}
|
|
197
|
+
const matchesAnyFilter = (path) => filterPatterns.some((p) => matchPath(path, p));
|
|
198
|
+
const matchesAnyReject = (path) => rejectPatterns.some((p) => matchPath(path, p));
|
|
199
|
+
const build = (value, path, allowedByFilter, stack2, isRoot, parentIsArray) => {
|
|
200
|
+
if (Array.isArray(value)) {
|
|
201
|
+
if (stack2.has(value)) {
|
|
202
|
+
throw new TypeError("Circular references are not supported");
|
|
203
|
+
}
|
|
204
|
+
stack2.add(value);
|
|
205
|
+
const out = [];
|
|
206
|
+
const includeAllChildren = allowedByFilter || !hasFilters;
|
|
207
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
208
|
+
const childPath = path.concat({ type: "INDEX", index });
|
|
209
|
+
if (hasRejects && matchesAnyReject(childPath)) continue;
|
|
210
|
+
const child = value[index];
|
|
211
|
+
const directInclude = hasFilters ? matchesAnyFilter(childPath) : true;
|
|
212
|
+
const childAllowed = includeAllChildren || directInclude;
|
|
213
|
+
if (isPlainObject(child) || Array.isArray(child)) {
|
|
214
|
+
const builtChild = build(
|
|
215
|
+
child,
|
|
216
|
+
childPath,
|
|
217
|
+
childAllowed,
|
|
218
|
+
stack2,
|
|
219
|
+
false,
|
|
220
|
+
true
|
|
221
|
+
);
|
|
222
|
+
if (builtChild !== void 0) {
|
|
223
|
+
out.push(builtChild);
|
|
224
|
+
}
|
|
225
|
+
} else {
|
|
226
|
+
if (childAllowed) {
|
|
227
|
+
out.push(child);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
stack2.delete(value);
|
|
232
|
+
const filteredOut = rejectEmptyObjectsInArray ? out.filter(
|
|
233
|
+
(item) => !(isPlainObject(item) && Object.keys(item).length === 0)
|
|
234
|
+
) : out;
|
|
235
|
+
if (filteredOut.length === 0 && !allowedByFilter && !isRoot)
|
|
236
|
+
return void 0;
|
|
237
|
+
return filteredOut;
|
|
238
|
+
}
|
|
239
|
+
if (isPlainObject(value)) {
|
|
240
|
+
if (stack2.has(value)) {
|
|
241
|
+
throw new TypeError("Circular references are not supported");
|
|
242
|
+
}
|
|
243
|
+
stack2.add(value);
|
|
244
|
+
const result = {};
|
|
245
|
+
const includeAllChildren = allowedByFilter || !hasFilters;
|
|
246
|
+
for (const key of Object.keys(value)) {
|
|
247
|
+
const childPath = path.concat({ type: "KEY", name: key });
|
|
248
|
+
if (hasRejects && matchesAnyReject(childPath)) continue;
|
|
249
|
+
const val = value[key];
|
|
250
|
+
const directInclude = hasFilters ? matchesAnyFilter(childPath) : true;
|
|
251
|
+
const childAllowed = includeAllChildren || directInclude;
|
|
252
|
+
if (isPlainObject(val) || Array.isArray(val)) {
|
|
253
|
+
const builtChild = build(
|
|
254
|
+
val,
|
|
255
|
+
childPath,
|
|
256
|
+
childAllowed,
|
|
257
|
+
stack2,
|
|
258
|
+
false,
|
|
259
|
+
false
|
|
260
|
+
);
|
|
261
|
+
if (builtChild === void 0) {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
if (Array.isArray(builtChild) && builtChild.length === 0 && !childAllowed) {
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
if (isPlainObject(builtChild) && Object.keys(builtChild).length === 0 && !childAllowed) {
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
result[key] = builtChild;
|
|
271
|
+
} else {
|
|
272
|
+
if (childAllowed) {
|
|
273
|
+
result[key] = val;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
stack2.delete(value);
|
|
278
|
+
if (Object.keys(result).length === 0 && !allowedByFilter && !isRoot) {
|
|
279
|
+
if (parentIsArray && !rejectEmptyObjectsInArray) {
|
|
280
|
+
return {};
|
|
281
|
+
}
|
|
282
|
+
return void 0;
|
|
283
|
+
}
|
|
284
|
+
return result;
|
|
285
|
+
}
|
|
286
|
+
return allowedByFilter || !hasFilters ? value : void 0;
|
|
287
|
+
};
|
|
288
|
+
const startPath = [];
|
|
289
|
+
const initialAllowed = !hasFilters;
|
|
290
|
+
const stack = /* @__PURE__ */ new WeakSet();
|
|
291
|
+
const built = build(
|
|
292
|
+
objOrArray,
|
|
293
|
+
startPath,
|
|
294
|
+
initialAllowed,
|
|
295
|
+
stack,
|
|
296
|
+
true,
|
|
297
|
+
false
|
|
298
|
+
);
|
|
299
|
+
if (built === void 0) return Array.isArray(objOrArray) ? [] : {};
|
|
300
|
+
return built;
|
|
301
|
+
}
|
|
302
|
+
function parsePattern(pattern) {
|
|
303
|
+
const tokens = [];
|
|
304
|
+
let i = 0;
|
|
305
|
+
const n = pattern.length;
|
|
306
|
+
const pushKey = (name) => {
|
|
307
|
+
if (name.length === 0) return;
|
|
308
|
+
tokens.push({ type: "KEY", name });
|
|
309
|
+
};
|
|
310
|
+
while (i < n) {
|
|
311
|
+
const ch = pattern[i];
|
|
312
|
+
if (ch === ".") {
|
|
313
|
+
i += 1;
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
if (ch === "[") {
|
|
317
|
+
const end = pattern.indexOf("]", i + 1);
|
|
318
|
+
const inside = end === -1 ? pattern.slice(i + 1) : pattern.slice(i + 1, end);
|
|
319
|
+
if (inside === "*") {
|
|
320
|
+
tokens.push({ type: "INDEX_ANY" });
|
|
321
|
+
} else if (inside.includes("-")) {
|
|
322
|
+
const parts = inside.split("-");
|
|
323
|
+
const startStr = parts[0] ?? "";
|
|
324
|
+
const endStr = parts[1] ?? "";
|
|
325
|
+
const start = parseInt(startStr, 10);
|
|
326
|
+
const endNum = endStr === "*" ? null : parseInt(endStr, 10);
|
|
327
|
+
tokens.push({
|
|
328
|
+
type: "INDEX_RANGE",
|
|
329
|
+
start,
|
|
330
|
+
end: endNum === null || Number.isFinite(endNum) ? endNum : null
|
|
331
|
+
});
|
|
332
|
+
} else if (inside.length > 0) {
|
|
333
|
+
const idx = parseInt(inside, 10);
|
|
334
|
+
tokens.push({ type: "INDEX", index: idx });
|
|
335
|
+
}
|
|
336
|
+
i = end === -1 ? n : end + 1;
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
if (ch === "(") {
|
|
340
|
+
const end = pattern.indexOf(")", i + 1);
|
|
341
|
+
const inside = end === -1 ? pattern.slice(i + 1) : pattern.slice(i + 1, end);
|
|
342
|
+
if (inside.includes("|") && inside.trim().length > 0) {
|
|
343
|
+
const names = inside.split("|").filter((name) => name.length > 0);
|
|
344
|
+
if (names.length > 0) {
|
|
345
|
+
tokens.push({ type: "MULTI_KEY", names });
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
i = end === -1 ? n : end + 1;
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
if (ch === "*") {
|
|
352
|
+
if (pattern[i + 1] === "*") {
|
|
353
|
+
tokens.push({ type: "WILDCARD_ANY" });
|
|
354
|
+
i += 2;
|
|
355
|
+
let j2 = i;
|
|
356
|
+
while (j2 < n) {
|
|
357
|
+
const c = pattern[j2];
|
|
358
|
+
if (c === "." || c === "[") break;
|
|
359
|
+
j2 += 1;
|
|
360
|
+
}
|
|
361
|
+
if (j2 > i) {
|
|
362
|
+
pushKey(pattern.slice(i, j2));
|
|
363
|
+
i = j2;
|
|
364
|
+
}
|
|
365
|
+
continue;
|
|
366
|
+
} else {
|
|
367
|
+
tokens.push({ type: "WILDCARD_ONE" });
|
|
368
|
+
i += 1;
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
let j = i;
|
|
373
|
+
while (j < n) {
|
|
374
|
+
const c = pattern[j];
|
|
375
|
+
if (c === "." || c === "[") break;
|
|
376
|
+
j += 1;
|
|
377
|
+
}
|
|
378
|
+
pushKey(pattern.slice(i, j));
|
|
379
|
+
i = j;
|
|
380
|
+
}
|
|
381
|
+
return tokens;
|
|
382
|
+
}
|
|
383
|
+
|
|
134
384
|
// src/mathUtils.ts
|
|
135
385
|
function clampMin(value, min) {
|
|
136
386
|
return value < min ? min : value;
|
|
@@ -197,12 +447,12 @@ function yamlStringify(obj, {
|
|
|
197
447
|
addRootObjSpaces = "beforeAndAfter"
|
|
198
448
|
} = {}) {
|
|
199
449
|
if (isObject(obj) || Array.isArray(obj) || typeof obj === "function") {
|
|
200
|
-
return `${stringifyValue(obj, "", maxLineLength, !!showUndefined, maxDepth, 0, collapseObjects, addRootObjSpaces)}
|
|
450
|
+
return `${stringifyValue(obj, "", maxLineLength, !!showUndefined, maxDepth, 0, collapseObjects, addRootObjSpaces, false)}
|
|
201
451
|
`;
|
|
202
452
|
}
|
|
203
453
|
return JSON.stringify(obj) || "undefined";
|
|
204
454
|
}
|
|
205
|
-
function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, depth, collapseObjects, addObjSpaces) {
|
|
455
|
+
function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, depth, collapseObjects, addObjSpaces, isArrayItem) {
|
|
206
456
|
let result = "";
|
|
207
457
|
const childIndent = `${indent} `;
|
|
208
458
|
if (isPlainObject(value)) {
|
|
@@ -221,7 +471,8 @@ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, d
|
|
|
221
471
|
return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
|
|
222
472
|
}
|
|
223
473
|
);
|
|
224
|
-
|
|
474
|
+
const shouldCollapse = isArrayItem ? entries.length > 1 : entries.length > 0;
|
|
475
|
+
if (isSimpleObject && shouldCollapse) {
|
|
225
476
|
let line = "{ ";
|
|
226
477
|
line += entries.map(([key, val]) => {
|
|
227
478
|
let valueStr;
|
|
@@ -268,20 +519,29 @@ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, d
|
|
|
268
519
|
maxDepth,
|
|
269
520
|
depth + 1,
|
|
270
521
|
collapseObjects,
|
|
271
|
-
addObjSpaces
|
|
522
|
+
addObjSpaces,
|
|
523
|
+
false
|
|
272
524
|
);
|
|
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
|
-
|
|
525
|
+
const willBeCollapsed = isObject(objVal) && (Object.keys(objVal).length === 0 || collapseObjects && depth + 1 > 0 && (() => {
|
|
526
|
+
const filteredEntries = Object.entries(objVal).filter(([, val]) => val !== void 0 || showUndefined);
|
|
527
|
+
const shouldCollapseThis = isArrayItem ? filteredEntries.length > 1 : filteredEntries.length > 0;
|
|
528
|
+
return shouldCollapseThis && filteredEntries.every(([, val]) => {
|
|
529
|
+
if (typeof val === "string") {
|
|
530
|
+
return !val.includes("'") && !val.includes('"') && !val.includes("\\");
|
|
531
|
+
}
|
|
532
|
+
return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
|
|
533
|
+
});
|
|
534
|
+
})());
|
|
535
|
+
const prevWasCollapsed = prevValue && isObject(prevValue) && (Object.keys(prevValue).length === 0 || collapseObjects && depth + 1 > 0 && (() => {
|
|
536
|
+
const filteredEntries = Object.entries(prevValue).filter(([, val]) => val !== void 0 || showUndefined);
|
|
537
|
+
const shouldCollapseThis = isArrayItem ? filteredEntries.length > 1 : filteredEntries.length > 0;
|
|
538
|
+
return shouldCollapseThis && filteredEntries.every(([, val]) => {
|
|
539
|
+
if (typeof val === "string") {
|
|
540
|
+
return !val.includes("'") && !val.includes('"') && !val.includes("\\");
|
|
541
|
+
}
|
|
542
|
+
return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
|
|
543
|
+
});
|
|
544
|
+
})());
|
|
285
545
|
if (!afterSpaceWasAdded && indent === "" && isObject(objVal) && !willBeCollapsed && prevValue && !prevWasCollapsed && (addObjSpaces === "before" || addObjSpaces === "beforeAndAfter")) {
|
|
286
546
|
result += "\n";
|
|
287
547
|
}
|
|
@@ -344,7 +604,8 @@ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, d
|
|
|
344
604
|
maxDepth,
|
|
345
605
|
depth + 1,
|
|
346
606
|
collapseObjects,
|
|
347
|
-
addObjSpaces
|
|
607
|
+
addObjSpaces,
|
|
608
|
+
true
|
|
348
609
|
);
|
|
349
610
|
}).join(", ");
|
|
350
611
|
line += "]";
|
|
@@ -368,7 +629,8 @@ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, d
|
|
|
368
629
|
maxDepth,
|
|
369
630
|
depth + 1,
|
|
370
631
|
collapseObjects,
|
|
371
|
-
addObjSpaces
|
|
632
|
+
addObjSpaces,
|
|
633
|
+
true
|
|
372
634
|
);
|
|
373
635
|
arrayString = arrayString.trimStart();
|
|
374
636
|
result += arrayString;
|
|
@@ -381,7 +643,8 @@ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, d
|
|
|
381
643
|
maxDepth,
|
|
382
644
|
depth + 1,
|
|
383
645
|
collapseObjects,
|
|
384
|
-
addObjSpaces
|
|
646
|
+
addObjSpaces,
|
|
647
|
+
true
|
|
385
648
|
);
|
|
386
649
|
}
|
|
387
650
|
result += "\n";
|
|
@@ -435,7 +698,8 @@ ${indent}${line}
|
|
|
435
698
|
maxDepth,
|
|
436
699
|
depth + 1,
|
|
437
700
|
collapseObjects,
|
|
438
|
-
addObjSpaces
|
|
701
|
+
addObjSpaces,
|
|
702
|
+
false
|
|
439
703
|
);
|
|
440
704
|
}
|
|
441
705
|
return JSON.stringify(value);
|
|
@@ -753,126 +1017,6 @@ function waitController() {
|
|
|
753
1017
|
}
|
|
754
1018
|
};
|
|
755
1019
|
}
|
|
756
|
-
function matchesKeyPattern(fullPath, key, pattern, currentPath) {
|
|
757
|
-
if (fullPath === pattern) {
|
|
758
|
-
return true;
|
|
759
|
-
}
|
|
760
|
-
if (pattern.startsWith("*.")) {
|
|
761
|
-
const propName = pattern.slice(2);
|
|
762
|
-
return currentPath !== "" && key === propName;
|
|
763
|
-
}
|
|
764
|
-
if (pattern.startsWith("*") && !pattern.startsWith("*.")) {
|
|
765
|
-
const propName = pattern.slice(1);
|
|
766
|
-
return key === propName;
|
|
767
|
-
}
|
|
768
|
-
if (!pattern.includes("*")) {
|
|
769
|
-
return currentPath === "" && key === pattern;
|
|
770
|
-
}
|
|
771
|
-
return false;
|
|
772
|
-
}
|
|
773
|
-
function isParentOfPattern(path, pattern) {
|
|
774
|
-
if (pattern.includes("*")) {
|
|
775
|
-
const patternParts = pattern.split(".");
|
|
776
|
-
const pathParts = path.split(".");
|
|
777
|
-
if (pathParts.length >= patternParts.length) {
|
|
778
|
-
return false;
|
|
779
|
-
}
|
|
780
|
-
for (let i = 0; i < pathParts.length; i++) {
|
|
781
|
-
const pathPart = pathParts[i];
|
|
782
|
-
const patternPart = patternParts[i];
|
|
783
|
-
if (patternPart === "*") {
|
|
784
|
-
continue;
|
|
785
|
-
}
|
|
786
|
-
if (pathPart !== patternPart) {
|
|
787
|
-
return false;
|
|
788
|
-
}
|
|
789
|
-
}
|
|
790
|
-
return true;
|
|
791
|
-
} else {
|
|
792
|
-
return pattern.startsWith(`${path}.`);
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
function applyKeyFiltering(value, { rejectKeys, filterKeys }, currentPath = "", visited = /* @__PURE__ */ new Set()) {
|
|
796
|
-
if (!isPlainObject(value) && !Array.isArray(value)) {
|
|
797
|
-
return value;
|
|
798
|
-
}
|
|
799
|
-
if (Array.isArray(value)) {
|
|
800
|
-
if (visited.has(value)) {
|
|
801
|
-
throw new Error(
|
|
802
|
-
"Circular reference detected in array during key filtering"
|
|
803
|
-
);
|
|
804
|
-
}
|
|
805
|
-
visited.add(value);
|
|
806
|
-
try {
|
|
807
|
-
return value.map(
|
|
808
|
-
(item, index) => applyKeyFiltering(
|
|
809
|
-
item,
|
|
810
|
-
{ rejectKeys, filterKeys },
|
|
811
|
-
currentPath ? `${currentPath}[${index}]` : `[${index}]`,
|
|
812
|
-
visited
|
|
813
|
-
)
|
|
814
|
-
);
|
|
815
|
-
} finally {
|
|
816
|
-
visited.delete(value);
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
if (isPlainObject(value)) {
|
|
820
|
-
if (visited.has(value)) {
|
|
821
|
-
throw new Error(
|
|
822
|
-
"Circular reference detected in object during key filtering"
|
|
823
|
-
);
|
|
824
|
-
}
|
|
825
|
-
visited.add(value);
|
|
826
|
-
try {
|
|
827
|
-
const result = {};
|
|
828
|
-
for (const [key, itemValue] of Object.entries(value)) {
|
|
829
|
-
const fullPath = currentPath ? `${currentPath}.${key}` : key;
|
|
830
|
-
if (rejectKeys?.some(
|
|
831
|
-
(rejectPath) => matchesKeyPattern(fullPath, key, rejectPath, currentPath)
|
|
832
|
-
)) {
|
|
833
|
-
continue;
|
|
834
|
-
}
|
|
835
|
-
if (filterKeys) {
|
|
836
|
-
const exactMatch = filterKeys.some(
|
|
837
|
-
(filterPath) => matchesKeyPattern(fullPath, key, filterPath, currentPath)
|
|
838
|
-
);
|
|
839
|
-
const isParent = filterKeys.some(
|
|
840
|
-
(filterPath) => isParentOfPattern(fullPath, filterPath)
|
|
841
|
-
);
|
|
842
|
-
if (!exactMatch && !isParent) {
|
|
843
|
-
continue;
|
|
844
|
-
}
|
|
845
|
-
if (exactMatch) {
|
|
846
|
-
result[key] = applyKeyFiltering(
|
|
847
|
-
itemValue,
|
|
848
|
-
{ rejectKeys },
|
|
849
|
-
fullPath,
|
|
850
|
-
visited
|
|
851
|
-
);
|
|
852
|
-
} else {
|
|
853
|
-
result[key] = applyKeyFiltering(
|
|
854
|
-
itemValue,
|
|
855
|
-
{ rejectKeys, filterKeys },
|
|
856
|
-
fullPath,
|
|
857
|
-
visited
|
|
858
|
-
);
|
|
859
|
-
}
|
|
860
|
-
} else {
|
|
861
|
-
result[key] = applyKeyFiltering(
|
|
862
|
-
itemValue,
|
|
863
|
-
{ rejectKeys, filterKeys },
|
|
864
|
-
fullPath,
|
|
865
|
-
visited
|
|
866
|
-
);
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
return result;
|
|
870
|
-
} finally {
|
|
871
|
-
visited.delete(value);
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
return value;
|
|
875
|
-
}
|
|
876
1020
|
function compactSnapshot(value, {
|
|
877
1021
|
collapseObjects = true,
|
|
878
1022
|
maxLineLength = 100,
|
|
@@ -884,10 +1028,12 @@ function compactSnapshot(value, {
|
|
|
884
1028
|
} = {}) {
|
|
885
1029
|
let processedValue = value;
|
|
886
1030
|
if (rejectKeys || filterKeys) {
|
|
887
|
-
processedValue
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
1031
|
+
if (isPlainObject(processedValue) || Array.isArray(processedValue)) {
|
|
1032
|
+
processedValue = filterObjectOrArrayKeys(processedValue, {
|
|
1033
|
+
rejectKeys,
|
|
1034
|
+
filterKeys
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
891
1037
|
}
|
|
892
1038
|
processedValue = showBooleansAs ? replaceBooleansWithEmoji(processedValue, showBooleansAs) : processedValue;
|
|
893
1039
|
return `
|