@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.
Files changed (56) hide show
  1. package/docs/_media/modules.md +1 -0
  2. package/docs/arrayUtils/-internal-.md +1 -1
  3. package/docs/arrayUtils/README.md +12 -12
  4. package/docs/consoleFmt.md +2 -2
  5. package/docs/exhaustiveMatch/-internal-.md +1 -1
  6. package/docs/exhaustiveMatch/README.md +1 -1
  7. package/docs/filterObjectOrArrayKeys.md +80 -0
  8. package/docs/modules.md +1 -0
  9. package/docs/objUtils.md +7 -7
  10. package/docs/parallelAsyncCalls/-internal-.md +3 -3
  11. package/docs/parallelAsyncCalls/README.md +1 -1
  12. package/docs/retryOnError/README.md +1 -1
  13. package/docs/runShellCmd/README.md +9 -9
  14. package/docs/safeJson.md +2 -2
  15. package/docs/saferTyping.md +7 -7
  16. package/docs/stringUtils/README.md +6 -6
  17. package/docs/testUtils.md +40 -6
  18. package/docs/time.md +1 -1
  19. package/docs/tsResult/README.md +17 -11
  20. package/docs/typingFnUtils/-internal-.md +1 -1
  21. package/docs/typingFnUtils/README.md +8 -10
  22. package/lib/arrayUtils.d.cts +6 -1
  23. package/lib/arrayUtils.d.ts +6 -1
  24. package/lib/{chunk-JAPKLFIK.js → chunk-QLD7KG5I.js} +34 -20
  25. package/lib/chunk-XXYTMSFH.js +240 -0
  26. package/lib/filterObjectOrArrayKeys.cjs +275 -0
  27. package/lib/filterObjectOrArrayKeys.d.cts +42 -0
  28. package/lib/filterObjectOrArrayKeys.d.ts +42 -0
  29. package/lib/filterObjectOrArrayKeys.js +7 -0
  30. package/lib/objUtils.d.cts +4 -1
  31. package/lib/objUtils.d.ts +4 -1
  32. package/lib/parallelAsyncCalls.cjs +4 -1
  33. package/lib/parallelAsyncCalls.d.cts +4 -1
  34. package/lib/parallelAsyncCalls.d.ts +4 -1
  35. package/lib/parallelAsyncCalls.js +4 -1
  36. package/lib/retryOnError.d.cts +2 -0
  37. package/lib/retryOnError.d.ts +2 -0
  38. package/lib/runShellCmd.d.cts +17 -0
  39. package/lib/runShellCmd.d.ts +17 -0
  40. package/lib/safeJson.d.cts +8 -2
  41. package/lib/safeJson.d.ts +8 -2
  42. package/lib/saferTyping.d.cts +3 -0
  43. package/lib/saferTyping.d.ts +3 -0
  44. package/lib/stringUtils.d.cts +1 -0
  45. package/lib/stringUtils.d.ts +1 -0
  46. package/lib/testUtils.cjs +273 -106
  47. package/lib/testUtils.d.cts +81 -2
  48. package/lib/testUtils.d.ts +81 -2
  49. package/lib/testUtils.js +10 -87
  50. package/lib/tsResult.d.cts +31 -7
  51. package/lib/tsResult.d.ts +31 -7
  52. package/lib/typingFnUtils.d.cts +20 -6
  53. package/lib/typingFnUtils.d.ts +20 -6
  54. package/lib/yamlStringify.cjs +34 -20
  55. package/lib/yamlStringify.js +1 -1
  56. package/package.json +5 -1
@@ -41,6 +41,46 @@ declare function waitController(): {
41
41
  stopWaiting: () => void;
42
42
  stopWaitingAfter: (ms: number) => void;
43
43
  };
44
+ /**
45
+ * Produces a more compact and readable snapshot of a value using yaml.
46
+ * By default booleans are shown as `✅` and `❌`, use `showBooleansAs` to disable/configure this.
47
+ *
48
+ * Filtering patterns in `rejectKeys` and `filterKeys`:
49
+ * - `'prop'` - Only root-level properties named 'prop'
50
+ * - `'**prop'` - Any property named exactly 'prop' at any level (root or nested)
51
+ * - `'*.prop'` - Any nested property named 'prop' at second level (excludes root-level matches)
52
+ * - `'test.*.prop'` - Any property named 'prop' at second level of 'test'
53
+ * - `'test.*.test.**prop'` - Any property named 'prop' inside of 'test.*.test'
54
+ * - `'prop.nested'` - Exact nested property paths like `obj.prop.nested`
55
+ * - `'prop.**nested'` - All nested properties inside root `prop` with name `nested`
56
+ * - `'prop[0]'` - The first item of the `prop` array
57
+ * - `'prop[*]'` - All items of the `prop` array
58
+ * - `'prop[0].nested'` - `nested` prop of the first item of the `prop` array
59
+ * - `'prop[*].nested'` - `nested` prop of all items of the `prop` array
60
+ * - `'prop[*]**nested'` - all `nested` props of all items of the `prop` array
61
+ * - `'prop[0-2]'` - The first three items of the `prop` array
62
+ * - `'prop[4-*]'` - All items of the `prop` array from the fourth index to the end
63
+ * - `'prop[0-2].nested.**prop'` - Combining multiple nested patterns is supported
64
+ * - Root array:
65
+ * - `'[0]'` - The first item of the root array
66
+ * - `'[*]'` - All items of the array
67
+ * - `'[0].nested'` - `nested` prop of the first item of the array
68
+ * - `'[*].nested'` - `nested` prop of all items of the array
69
+ * - `'[*]**nested'` - all `nested` props of all items of the array
70
+ * - `'[0-2]'` - The first three items of the array
71
+ * - `'[4-*]'` - All items of the array from the fourth index to the end
72
+ *
73
+ * @param value - The value to snapshot.
74
+ * @param options - The options for the snapshot.
75
+ * @param options.collapseObjects - Whether to collapse objects into a single line.
76
+ * @param options.maxLineLength - The maximum length of a line.
77
+ * @param options.showUndefined - Whether to show undefined values.
78
+ * @param options.showBooleansAs - Whether to show booleans as text, by default true is `✅` and false is `❌`
79
+ * @param options.rejectKeys - The keys to reject.
80
+ * @param options.filterKeys - The keys to filter.
81
+ * @param options.ignoreProps - The props to ignore.
82
+ * @returns The compact snapshot of the value.
83
+ */
44
84
  declare function compactSnapshot(value: unknown, { collapseObjects, maxLineLength, showUndefined, showBooleansAs, rejectKeys, filterKeys, ...options }?: YamlStringifyOptions & {
45
85
  showBooleansAs?: boolean | {
46
86
  props?: Record<string, {
@@ -51,8 +91,47 @@ declare function compactSnapshot(value: unknown, { collapseObjects, maxLineLengt
51
91
  trueText?: string;
52
92
  falseText?: string;
53
93
  };
54
- rejectKeys?: string[];
55
- filterKeys?: string[];
94
+ /**
95
+ * Reject (exclude) keys from the snapshot using pattern matching.
96
+ *
97
+ * **Examples:**
98
+ * ```typescript
99
+ * // Reject root-level 'secret' only
100
+ * rejectKeys: ['secret']
101
+ *
102
+ * // Reject nested 'password' properties only
103
+ * rejectKeys: ['*.password']
104
+ *
105
+ * // Reject any 'apiKey' property at any level
106
+ * rejectKeys: ['*apiKey']
107
+ *
108
+ * // Reject specific nested path
109
+ * rejectKeys: ['user.settings.theme']
110
+ * ```
111
+ */
112
+ rejectKeys?: string[] | string;
113
+ /**
114
+ * Filter (include only) keys that match the specified patterns.
115
+ *
116
+ * **Examples:**
117
+ * ```typescript
118
+ * // Include only root-level 'user'
119
+ * filterKeys: ['user']
120
+ *
121
+ * // Include all 'name' properties at any level
122
+ * filterKeys: ['*name']
123
+ *
124
+ * // Include only nested 'id' properties
125
+ * filterKeys: ['*.id']
126
+ *
127
+ * // Include specific nested paths
128
+ * filterKeys: ['user.profile.email', 'settings.theme']
129
+ * ```
130
+ *
131
+ * **Note:** When filtering, parent paths are automatically included if needed
132
+ * to preserve the structure for nested matches.
133
+ */
134
+ filterKeys?: string[] | string;
56
135
  }): string;
57
136
 
58
137
  export { compactSnapshot, createLoggerStore, getResultFn, waitController };
@@ -41,6 +41,46 @@ declare function waitController(): {
41
41
  stopWaiting: () => void;
42
42
  stopWaitingAfter: (ms: number) => void;
43
43
  };
44
+ /**
45
+ * Produces a more compact and readable snapshot of a value using yaml.
46
+ * By default booleans are shown as `✅` and `❌`, use `showBooleansAs` to disable/configure this.
47
+ *
48
+ * Filtering patterns in `rejectKeys` and `filterKeys`:
49
+ * - `'prop'` - Only root-level properties named 'prop'
50
+ * - `'**prop'` - Any property named exactly 'prop' at any level (root or nested)
51
+ * - `'*.prop'` - Any nested property named 'prop' at second level (excludes root-level matches)
52
+ * - `'test.*.prop'` - Any property named 'prop' at second level of 'test'
53
+ * - `'test.*.test.**prop'` - Any property named 'prop' inside of 'test.*.test'
54
+ * - `'prop.nested'` - Exact nested property paths like `obj.prop.nested`
55
+ * - `'prop.**nested'` - All nested properties inside root `prop` with name `nested`
56
+ * - `'prop[0]'` - The first item of the `prop` array
57
+ * - `'prop[*]'` - All items of the `prop` array
58
+ * - `'prop[0].nested'` - `nested` prop of the first item of the `prop` array
59
+ * - `'prop[*].nested'` - `nested` prop of all items of the `prop` array
60
+ * - `'prop[*]**nested'` - all `nested` props of all items of the `prop` array
61
+ * - `'prop[0-2]'` - The first three items of the `prop` array
62
+ * - `'prop[4-*]'` - All items of the `prop` array from the fourth index to the end
63
+ * - `'prop[0-2].nested.**prop'` - Combining multiple nested patterns is supported
64
+ * - Root array:
65
+ * - `'[0]'` - The first item of the root array
66
+ * - `'[*]'` - All items of the array
67
+ * - `'[0].nested'` - `nested` prop of the first item of the array
68
+ * - `'[*].nested'` - `nested` prop of all items of the array
69
+ * - `'[*]**nested'` - all `nested` props of all items of the array
70
+ * - `'[0-2]'` - The first three items of the array
71
+ * - `'[4-*]'` - All items of the array from the fourth index to the end
72
+ *
73
+ * @param value - The value to snapshot.
74
+ * @param options - The options for the snapshot.
75
+ * @param options.collapseObjects - Whether to collapse objects into a single line.
76
+ * @param options.maxLineLength - The maximum length of a line.
77
+ * @param options.showUndefined - Whether to show undefined values.
78
+ * @param options.showBooleansAs - Whether to show booleans as text, by default true is `✅` and false is `❌`
79
+ * @param options.rejectKeys - The keys to reject.
80
+ * @param options.filterKeys - The keys to filter.
81
+ * @param options.ignoreProps - The props to ignore.
82
+ * @returns The compact snapshot of the value.
83
+ */
44
84
  declare function compactSnapshot(value: unknown, { collapseObjects, maxLineLength, showUndefined, showBooleansAs, rejectKeys, filterKeys, ...options }?: YamlStringifyOptions & {
45
85
  showBooleansAs?: boolean | {
46
86
  props?: Record<string, {
@@ -51,8 +91,47 @@ declare function compactSnapshot(value: unknown, { collapseObjects, maxLineLengt
51
91
  trueText?: string;
52
92
  falseText?: string;
53
93
  };
54
- rejectKeys?: string[];
55
- filterKeys?: string[];
94
+ /**
95
+ * Reject (exclude) keys from the snapshot using pattern matching.
96
+ *
97
+ * **Examples:**
98
+ * ```typescript
99
+ * // Reject root-level 'secret' only
100
+ * rejectKeys: ['secret']
101
+ *
102
+ * // Reject nested 'password' properties only
103
+ * rejectKeys: ['*.password']
104
+ *
105
+ * // Reject any 'apiKey' property at any level
106
+ * rejectKeys: ['*apiKey']
107
+ *
108
+ * // Reject specific nested path
109
+ * rejectKeys: ['user.settings.theme']
110
+ * ```
111
+ */
112
+ rejectKeys?: string[] | string;
113
+ /**
114
+ * Filter (include only) keys that match the specified patterns.
115
+ *
116
+ * **Examples:**
117
+ * ```typescript
118
+ * // Include only root-level 'user'
119
+ * filterKeys: ['user']
120
+ *
121
+ * // Include all 'name' properties at any level
122
+ * filterKeys: ['*name']
123
+ *
124
+ * // Include only nested 'id' properties
125
+ * filterKeys: ['*.id']
126
+ *
127
+ * // Include specific nested paths
128
+ * filterKeys: ['user.profile.email', 'settings.theme']
129
+ * ```
130
+ *
131
+ * **Note:** When filtering, parent paths are automatically included if needed
132
+ * to preserve the structure for nested matches.
133
+ */
134
+ filterKeys?: string[] | string;
56
135
  }): string;
57
136
 
58
137
  export { compactSnapshot, createLoggerStore, getResultFn, waitController };
package/lib/testUtils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  yamlStringify
3
- } from "./chunk-JAPKLFIK.js";
3
+ } from "./chunk-QLD7KG5I.js";
4
4
  import {
5
5
  omit,
6
6
  pick
@@ -9,6 +9,9 @@ import "./chunk-IATIXMCE.js";
9
9
  import {
10
10
  deepEqual
11
11
  } from "./chunk-JQFUKJU5.js";
12
+ import {
13
+ filterObjectOrArrayKeys
14
+ } from "./chunk-XXYTMSFH.js";
12
15
  import {
13
16
  defer
14
17
  } from "./chunk-DFXNVEH6.js";
@@ -253,91 +256,6 @@ function waitController() {
253
256
  }
254
257
  };
255
258
  }
256
- function matchesKeyPattern(path, pattern) {
257
- if (path === pattern) {
258
- return true;
259
- }
260
- if (pattern.includes("*")) {
261
- const regexPattern = pattern.replace(/\./g, "\\.").replace(/\*/g, "[^.]*");
262
- const regex = new RegExp(`^${regexPattern}$`);
263
- return regex.test(path);
264
- }
265
- return false;
266
- }
267
- function isParentOfPattern(path, pattern) {
268
- if (pattern.includes("*")) {
269
- const patternParts = pattern.split(".");
270
- const pathParts = path.split(".");
271
- if (pathParts.length >= patternParts.length) {
272
- return false;
273
- }
274
- for (let i = 0; i < pathParts.length; i++) {
275
- const pathPart = pathParts[i];
276
- const patternPart = patternParts[i];
277
- if (patternPart === "*") {
278
- continue;
279
- }
280
- if (pathPart !== patternPart) {
281
- return false;
282
- }
283
- }
284
- return true;
285
- } else {
286
- return pattern.startsWith(`${path}.`);
287
- }
288
- }
289
- function applyKeyFiltering(value, { rejectKeys, filterKeys }, currentPath = "", visited = /* @__PURE__ */ new Set()) {
290
- if (!isPlainObject(value) && !Array.isArray(value)) {
291
- return value;
292
- }
293
- if (Array.isArray(value)) {
294
- if (visited.has(value)) {
295
- throw new Error("Circular reference detected in array during key filtering");
296
- }
297
- visited.add(value);
298
- try {
299
- return value.map(
300
- (item, index) => applyKeyFiltering(item, { rejectKeys, filterKeys }, currentPath ? `${currentPath}[${index}]` : `[${index}]`, visited)
301
- );
302
- } finally {
303
- visited.delete(value);
304
- }
305
- }
306
- if (isPlainObject(value)) {
307
- if (visited.has(value)) {
308
- throw new Error("Circular reference detected in object during key filtering");
309
- }
310
- visited.add(value);
311
- try {
312
- const result = {};
313
- for (const [key, itemValue] of Object.entries(value)) {
314
- const fullPath = currentPath ? `${currentPath}.${key}` : key;
315
- if (rejectKeys?.some(
316
- (rejectPath) => matchesKeyPattern(fullPath, rejectPath) || matchesKeyPattern(key, rejectPath)
317
- )) {
318
- continue;
319
- }
320
- if (filterKeys) {
321
- const shouldInclude = filterKeys.some(
322
- (filterPath) => (
323
- // Exact match
324
- matchesKeyPattern(fullPath, filterPath) || matchesKeyPattern(key, filterPath) || // This path is a parent of a filter pattern (so we include it to allow children)
325
- isParentOfPattern(fullPath, filterPath)
326
- )
327
- );
328
- if (!shouldInclude) {
329
- continue;
330
- }
331
- }
332
- result[key] = applyKeyFiltering(itemValue, { rejectKeys, filterKeys }, fullPath, visited);
333
- }
334
- return result;
335
- } finally {
336
- visited.delete(value);
337
- }
338
- }
339
- return value;
340
- }
341
259
  function compactSnapshot(value, {
342
260
  collapseObjects = true,
343
261
  maxLineLength = 100,
@@ -349,7 +267,12 @@ function compactSnapshot(value, {
349
267
  } = {}) {
350
268
  let processedValue = value;
351
269
  if (rejectKeys || filterKeys) {
352
- processedValue = applyKeyFiltering(processedValue, { rejectKeys, filterKeys });
270
+ if (isPlainObject(processedValue) || Array.isArray(processedValue)) {
271
+ processedValue = filterObjectOrArrayKeys(processedValue, {
272
+ rejectKeys,
273
+ filterKeys
274
+ });
275
+ }
353
276
  }
354
277
  processedValue = showBooleansAs ? replaceBooleansWithEmoji(processedValue, showBooleansAs) : processedValue;
355
278
  return `
@@ -36,12 +36,21 @@ type ResultMethods<T, E extends ResultValidErrors> = {
36
36
  type ResultMethodsKeys = keyof ResultMethods<any, any>;
37
37
  /** @deprecated Use `t-result` library instead. */
38
38
  declare function ok(): Ok<void>;
39
- /** @deprecated Use `t-result` library instead. */
39
+ /**
40
+ * @param value
41
+ * @deprecated Use `t-result` library instead.
42
+ */
40
43
  declare function ok<T>(value: T): Ok<T>;
41
- /** @deprecated Use `t-result` library instead. */
44
+ /**
45
+ * @param error
46
+ * @deprecated Use `t-result` library instead.
47
+ */
42
48
  declare function err<E extends ResultValidErrors>(error: E): Err<E>;
43
49
  declare function unknownToResultError(error: unknown): Err<Error>;
44
- /** Unwraps a promise result */
50
+ /**
51
+ * Unwraps a promise result
52
+ * @param result
53
+ */
45
54
  declare function asyncUnwrap<T>(result: Promise<Result<T, ResultValidErrors>>): Promise<T>;
46
55
  declare function asyncMap<T, E extends ResultValidErrors>(resultPromise: Promise<Result<T, E>>): {
47
56
  err: <NewError extends ResultValidErrors>(mapFn: (error: E) => NewError) => Promise<Result<T, NewError>>;
@@ -62,13 +71,28 @@ declare const Result: {
62
71
  asyncMap: typeof asyncMap;
63
72
  getOkErr: typeof getOkErr;
64
73
  };
65
- /** @deprecated Use `t-result` library instead. */
74
+ /**
75
+ * @param fn
76
+ * @param errorNormalizer
77
+ * @deprecated Use `t-result` library instead.
78
+ */
66
79
  declare function resultify<T, E extends ResultValidErrors = Error>(fn: () => T extends Promise<any> ? never : T, errorNormalizer?: (err: unknown) => E): Result<T, E>;
67
- /** @deprecated Use `t-result` library instead. */
80
+ /**
81
+ * @param fn
82
+ * @param errorNormalizer
83
+ * @deprecated Use `t-result` library instead.
84
+ */
68
85
  declare function resultify<T, E extends ResultValidErrors = Error>(fn: () => Promise<T>, errorNormalizer?: (err: unknown) => E): Promise<Result<Awaited<T>, E>>;
69
- /** @deprecated Use `t-result` library instead. */
86
+ /**
87
+ * @param fn
88
+ * @param errorNormalizer
89
+ * @deprecated Use `t-result` library instead.
90
+ */
70
91
  declare function resultify<T, E extends ResultValidErrors = Error>(fn: Promise<T>, errorNormalizer?: (err: unknown) => E): Promise<Result<T, E>>;
71
- /** @deprecated Use `t-result` library instead. */
92
+ /**
93
+ * @param error
94
+ * @deprecated Use `t-result` library instead.
95
+ */
72
96
  declare function unknownToError(error: unknown): Error;
73
97
  /** @deprecated Use `t-result` library instead. */
74
98
  type TypedResult<T, E extends ResultValidErrors = Error> = {
package/lib/tsResult.d.ts CHANGED
@@ -36,12 +36,21 @@ type ResultMethods<T, E extends ResultValidErrors> = {
36
36
  type ResultMethodsKeys = keyof ResultMethods<any, any>;
37
37
  /** @deprecated Use `t-result` library instead. */
38
38
  declare function ok(): Ok<void>;
39
- /** @deprecated Use `t-result` library instead. */
39
+ /**
40
+ * @param value
41
+ * @deprecated Use `t-result` library instead.
42
+ */
40
43
  declare function ok<T>(value: T): Ok<T>;
41
- /** @deprecated Use `t-result` library instead. */
44
+ /**
45
+ * @param error
46
+ * @deprecated Use `t-result` library instead.
47
+ */
42
48
  declare function err<E extends ResultValidErrors>(error: E): Err<E>;
43
49
  declare function unknownToResultError(error: unknown): Err<Error>;
44
- /** Unwraps a promise result */
50
+ /**
51
+ * Unwraps a promise result
52
+ * @param result
53
+ */
45
54
  declare function asyncUnwrap<T>(result: Promise<Result<T, ResultValidErrors>>): Promise<T>;
46
55
  declare function asyncMap<T, E extends ResultValidErrors>(resultPromise: Promise<Result<T, E>>): {
47
56
  err: <NewError extends ResultValidErrors>(mapFn: (error: E) => NewError) => Promise<Result<T, NewError>>;
@@ -62,13 +71,28 @@ declare const Result: {
62
71
  asyncMap: typeof asyncMap;
63
72
  getOkErr: typeof getOkErr;
64
73
  };
65
- /** @deprecated Use `t-result` library instead. */
74
+ /**
75
+ * @param fn
76
+ * @param errorNormalizer
77
+ * @deprecated Use `t-result` library instead.
78
+ */
66
79
  declare function resultify<T, E extends ResultValidErrors = Error>(fn: () => T extends Promise<any> ? never : T, errorNormalizer?: (err: unknown) => E): Result<T, E>;
67
- /** @deprecated Use `t-result` library instead. */
80
+ /**
81
+ * @param fn
82
+ * @param errorNormalizer
83
+ * @deprecated Use `t-result` library instead.
84
+ */
68
85
  declare function resultify<T, E extends ResultValidErrors = Error>(fn: () => Promise<T>, errorNormalizer?: (err: unknown) => E): Promise<Result<Awaited<T>, E>>;
69
- /** @deprecated Use `t-result` library instead. */
86
+ /**
87
+ * @param fn
88
+ * @param errorNormalizer
89
+ * @deprecated Use `t-result` library instead.
90
+ */
70
91
  declare function resultify<T, E extends ResultValidErrors = Error>(fn: Promise<T>, errorNormalizer?: (err: unknown) => E): Promise<Result<T, E>>;
71
- /** @deprecated Use `t-result` library instead. */
92
+ /**
93
+ * @param error
94
+ * @deprecated Use `t-result` library instead.
95
+ */
72
96
  declare function unknownToError(error: unknown): Error;
73
97
  /** @deprecated Use `t-result` library instead. */
74
98
  type TypedResult<T, E extends ResultValidErrors = Error> = {
@@ -1,28 +1,43 @@
1
1
  import { NonPartial } from './typingUtils.cjs';
2
2
 
3
3
  declare function asNonPartial<T extends Record<string, unknown>>(obj: T): NonPartial<T>;
4
- /** a wrapper to Object.entries with a better typing inference */
4
+ /**
5
+ * a wrapper to Object.entries with a better typing inference
6
+ * @param obj
7
+ */
5
8
  declare function typedObjectEntries<T extends Record<string, unknown>>(obj: T): NonNullable<{
6
9
  [K in keyof T]: [K, T[K]];
7
10
  }[keyof T]>[];
8
- /** a wrapper to Object.keys with a better typing inference */
11
+ /**
12
+ * a wrapper to Object.keys with a better typing inference
13
+ * @param obj
14
+ */
9
15
  declare function typedObjectKeys<T extends Record<string, unknown>>(obj: T): (keyof T)[];
10
- /** a safe way to cast types, use to substitute the `as Type` */
16
+ /**
17
+ * a safe way to cast types, use to substitute the `as Type`
18
+ * @param value
19
+ */
11
20
  declare function asType<T = unknown>(value: T): T;
12
- /** narrow a string to a union of strings */
21
+ /**
22
+ * narrow a string to a union of strings
23
+ * @param key
24
+ * @param union
25
+ */
13
26
  declare function narrowStringToUnion<const T extends string>(key: string | undefined | null, union: T[] | readonly T[] | Set<T>): T | undefined;
14
27
  /**
15
28
  * Type helper to check if a type is a subtype of another type.
16
29
  *
17
30
  * @template BaseType - The base type to check against
18
31
  * @template SubType - The type that should extend BaseType
19
- * @returns {unknown} Returns undefined, only used for type checking
32
+ * @returns Returns undefined, only used for type checking
20
33
  */
21
34
  declare function typeOnRightExtendsLeftType<BaseType, SubType extends BaseType>(): unknown;
22
35
  /** @deprecated use typeOnRightExtendsLeftType instead */
23
36
  declare const isSubTypeOf: typeof typeOnRightExtendsLeftType;
24
37
  /**
25
38
  * Type helper to narrow a string to a key of an object.
39
+ * @param key
40
+ * @param obj
26
41
  */
27
42
  declare function isObjKey<T extends Record<string, unknown>>(key: unknown, obj: T): key is keyof T;
28
43
  type UnionDiff<T, U> = [
@@ -43,7 +58,6 @@ type UnionDiff<T, U> = [
43
58
  * @template T - The first union type (left side)
44
59
  * @template U - The second union type (right side)
45
60
  * @param _diff - null if unions are identical, or an object describing the errors
46
- * @returns void - This function is only used for type checking
47
61
  */
48
62
  declare function unionsAreTheSame<T, U>(_diff: UnionDiff<T, U>): void;
49
63
 
@@ -1,28 +1,43 @@
1
1
  import { NonPartial } from './typingUtils.js';
2
2
 
3
3
  declare function asNonPartial<T extends Record<string, unknown>>(obj: T): NonPartial<T>;
4
- /** a wrapper to Object.entries with a better typing inference */
4
+ /**
5
+ * a wrapper to Object.entries with a better typing inference
6
+ * @param obj
7
+ */
5
8
  declare function typedObjectEntries<T extends Record<string, unknown>>(obj: T): NonNullable<{
6
9
  [K in keyof T]: [K, T[K]];
7
10
  }[keyof T]>[];
8
- /** a wrapper to Object.keys with a better typing inference */
11
+ /**
12
+ * a wrapper to Object.keys with a better typing inference
13
+ * @param obj
14
+ */
9
15
  declare function typedObjectKeys<T extends Record<string, unknown>>(obj: T): (keyof T)[];
10
- /** a safe way to cast types, use to substitute the `as Type` */
16
+ /**
17
+ * a safe way to cast types, use to substitute the `as Type`
18
+ * @param value
19
+ */
11
20
  declare function asType<T = unknown>(value: T): T;
12
- /** narrow a string to a union of strings */
21
+ /**
22
+ * narrow a string to a union of strings
23
+ * @param key
24
+ * @param union
25
+ */
13
26
  declare function narrowStringToUnion<const T extends string>(key: string | undefined | null, union: T[] | readonly T[] | Set<T>): T | undefined;
14
27
  /**
15
28
  * Type helper to check if a type is a subtype of another type.
16
29
  *
17
30
  * @template BaseType - The base type to check against
18
31
  * @template SubType - The type that should extend BaseType
19
- * @returns {unknown} Returns undefined, only used for type checking
32
+ * @returns Returns undefined, only used for type checking
20
33
  */
21
34
  declare function typeOnRightExtendsLeftType<BaseType, SubType extends BaseType>(): unknown;
22
35
  /** @deprecated use typeOnRightExtendsLeftType instead */
23
36
  declare const isSubTypeOf: typeof typeOnRightExtendsLeftType;
24
37
  /**
25
38
  * Type helper to narrow a string to a key of an object.
39
+ * @param key
40
+ * @param obj
26
41
  */
27
42
  declare function isObjKey<T extends Record<string, unknown>>(key: unknown, obj: T): key is keyof T;
28
43
  type UnionDiff<T, U> = [
@@ -43,7 +58,6 @@ type UnionDiff<T, U> = [
43
58
  * @template T - The first union type (left side)
44
59
  * @template U - The second union type (right side)
45
60
  * @param _diff - null if unions are identical, or an object describing the errors
46
- * @returns void - This function is only used for type checking
47
61
  */
48
62
  declare function unionsAreTheSame<T, U>(_diff: UnionDiff<T, U>): void;
49
63
 
@@ -72,12 +72,12 @@ function yamlStringify(obj, {
72
72
  addRootObjSpaces = "beforeAndAfter"
73
73
  } = {}) {
74
74
  if (isObject(obj) || Array.isArray(obj) || typeof obj === "function") {
75
- return `${stringifyValue(obj, "", maxLineLength, !!showUndefined, maxDepth, 0, collapseObjects, addRootObjSpaces)}
75
+ return `${stringifyValue(obj, "", maxLineLength, !!showUndefined, maxDepth, 0, collapseObjects, addRootObjSpaces, false)}
76
76
  `;
77
77
  }
78
78
  return JSON.stringify(obj) || "undefined";
79
79
  }
80
- function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, depth, collapseObjects, addObjSpaces) {
80
+ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, depth, collapseObjects, addObjSpaces, isArrayItem) {
81
81
  let result = "";
82
82
  const childIndent = `${indent} `;
83
83
  if (isPlainObject(value)) {
@@ -96,7 +96,8 @@ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, d
96
96
  return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
97
97
  }
98
98
  );
99
- if (isSimpleObject && entries.length > 0) {
99
+ const shouldCollapse = isArrayItem ? entries.length > 1 : entries.length > 0;
100
+ if (isSimpleObject && shouldCollapse) {
100
101
  let line = "{ ";
101
102
  line += entries.map(([key, val]) => {
102
103
  let valueStr;
@@ -143,20 +144,29 @@ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, d
143
144
  maxDepth,
144
145
  depth + 1,
145
146
  collapseObjects,
146
- addObjSpaces
147
+ addObjSpaces,
148
+ false
147
149
  );
148
- const willBeCollapsed = isObject(objVal) && (Object.keys(objVal).length === 0 || collapseObjects && depth + 1 > 0 && Object.entries(objVal).filter(([, val]) => val !== void 0 || showUndefined).every(([, val]) => {
149
- if (typeof val === "string") {
150
- return !val.includes("'") && !val.includes('"') && !val.includes("\\");
151
- }
152
- return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
153
- }));
154
- const prevWasCollapsed = prevValue && isObject(prevValue) && (Object.keys(prevValue).length === 0 || collapseObjects && depth + 1 > 0 && Object.entries(prevValue).filter(([, val]) => val !== void 0 || showUndefined).every(([, val]) => {
155
- if (typeof val === "string") {
156
- return !val.includes("'") && !val.includes('"') && !val.includes("\\");
157
- }
158
- return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
159
- }));
150
+ const willBeCollapsed = isObject(objVal) && (Object.keys(objVal).length === 0 || collapseObjects && depth + 1 > 0 && (() => {
151
+ const filteredEntries = Object.entries(objVal).filter(([, val]) => val !== void 0 || showUndefined);
152
+ const shouldCollapseThis = isArrayItem ? filteredEntries.length > 1 : filteredEntries.length > 0;
153
+ return shouldCollapseThis && filteredEntries.every(([, val]) => {
154
+ if (typeof val === "string") {
155
+ return !val.includes("'") && !val.includes('"') && !val.includes("\\");
156
+ }
157
+ return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
158
+ });
159
+ })());
160
+ const prevWasCollapsed = prevValue && isObject(prevValue) && (Object.keys(prevValue).length === 0 || collapseObjects && depth + 1 > 0 && (() => {
161
+ const filteredEntries = Object.entries(prevValue).filter(([, val]) => val !== void 0 || showUndefined);
162
+ const shouldCollapseThis = isArrayItem ? filteredEntries.length > 1 : filteredEntries.length > 0;
163
+ return shouldCollapseThis && filteredEntries.every(([, val]) => {
164
+ if (typeof val === "string") {
165
+ return !val.includes("'") && !val.includes('"') && !val.includes("\\");
166
+ }
167
+ return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
168
+ });
169
+ })());
160
170
  if (!afterSpaceWasAdded && indent === "" && isObject(objVal) && !willBeCollapsed && prevValue && !prevWasCollapsed && (addObjSpaces === "before" || addObjSpaces === "beforeAndAfter")) {
161
171
  result += "\n";
162
172
  }
@@ -219,7 +229,8 @@ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, d
219
229
  maxDepth,
220
230
  depth + 1,
221
231
  collapseObjects,
222
- addObjSpaces
232
+ addObjSpaces,
233
+ true
223
234
  );
224
235
  }).join(", ");
225
236
  line += "]";
@@ -243,7 +254,8 @@ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, d
243
254
  maxDepth,
244
255
  depth + 1,
245
256
  collapseObjects,
246
- addObjSpaces
257
+ addObjSpaces,
258
+ true
247
259
  );
248
260
  arrayString = arrayString.trimStart();
249
261
  result += arrayString;
@@ -256,7 +268,8 @@ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, d
256
268
  maxDepth,
257
269
  depth + 1,
258
270
  collapseObjects,
259
- addObjSpaces
271
+ addObjSpaces,
272
+ true
260
273
  );
261
274
  }
262
275
  result += "\n";
@@ -310,7 +323,8 @@ ${indent}${line}
310
323
  maxDepth,
311
324
  depth + 1,
312
325
  collapseObjects,
313
- addObjSpaces
326
+ addObjSpaces,
327
+ false
314
328
  );
315
329
  }
316
330
  return JSON.stringify(value);
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  yamlStringify
3
- } from "./chunk-JAPKLFIK.js";
3
+ } from "./chunk-QLD7KG5I.js";
4
4
  import "./chunk-IATIXMCE.js";
5
5
  import "./chunk-4REIIZQY.js";
6
6
  import "./chunk-JF2MDHOJ.js";