@ls-stack/utils 3.23.0 → 3.24.1

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/testUtils.md CHANGED
@@ -8,13 +8,37 @@
8
8
 
9
9
  ## Functions
10
10
 
11
+ ### compactSnapshot()
12
+
13
+ ```ts
14
+ function compactSnapshot(value, __namedParameters): string;
15
+ ```
16
+
17
+ Defined in: [packages/utils/src/testUtils.ts:487](https://github.com/lucasols/utils/blob/main/packages/utils/src/testUtils.ts#L487)
18
+
19
+ #### Parameters
20
+
21
+ ##### value
22
+
23
+ `unknown`
24
+
25
+ ##### \_\_namedParameters
26
+
27
+ [`YamlStringifyOptions`](yamlStringify.md#yamlstringifyoptions) & `object` = `{}`
28
+
29
+ #### Returns
30
+
31
+ `string`
32
+
33
+ ***
34
+
11
35
  ### createLoggerStore()
12
36
 
13
37
  ```ts
14
38
  function createLoggerStore(__namedParameters): object;
15
39
  ```
16
40
 
17
- Defined in: [packages/utils/src/testUtils.ts:8](https://github.com/lucasols/utils/blob/main/packages/utils/src/testUtils.ts#L8)
41
+ Defined in: [packages/utils/src/testUtils.ts:10](https://github.com/lucasols/utils/blob/main/packages/utils/src/testUtils.ts#L10)
18
42
 
19
43
  #### Parameters
20
44
 
@@ -246,7 +270,7 @@ get snapshotFromLast(): string;
246
270
  function getResultFn<T>(fnGetter, wrapper?): T;
247
271
  ```
248
272
 
249
- Defined in: [packages/utils/src/testUtils.ts:274](https://github.com/lucasols/utils/blob/main/packages/utils/src/testUtils.ts#L274)
273
+ Defined in: [packages/utils/src/testUtils.ts:276](https://github.com/lucasols/utils/blob/main/packages/utils/src/testUtils.ts#L276)
250
274
 
251
275
  #### Type Parameters
252
276
 
@@ -276,7 +300,7 @@ Defined in: [packages/utils/src/testUtils.ts:274](https://github.com/lucasols/ut
276
300
  function waitController(): object;
277
301
  ```
278
302
 
279
- Defined in: [packages/utils/src/testUtils.ts:289](https://github.com/lucasols/utils/blob/main/packages/utils/src/testUtils.ts#L289)
303
+ Defined in: [packages/utils/src/testUtils.ts:291](https://github.com/lucasols/utils/blob/main/packages/utils/src/testUtils.ts#L291)
280
304
 
281
305
  #### Returns
282
306
 
@@ -6,39 +6,77 @@
6
6
 
7
7
  # yamlStringify
8
8
 
9
- ## Functions
9
+ ## Type Aliases
10
10
 
11
- ### yamlStringify()
11
+ ### YamlStringifyOptions
12
12
 
13
13
  ```ts
14
- function yamlStringify(obj, __namedParameters): string;
14
+ type YamlStringifyOptions = object;
15
15
  ```
16
16
 
17
17
  Defined in: [packages/utils/src/yamlStringify.ts:5](https://github.com/lucasols/utils/blob/main/packages/utils/src/yamlStringify.ts#L5)
18
18
 
19
- #### Parameters
19
+ #### Properties
20
20
 
21
- ##### obj
21
+ ##### addRootObjSpaces?
22
22
 
23
- `unknown`
23
+ ```ts
24
+ optional addRootObjSpaces: "before" | "after" | "beforeAndAfter" | false;
25
+ ```
24
26
 
25
- ##### \_\_namedParameters
27
+ Defined in: [packages/utils/src/yamlStringify.ts:15](https://github.com/lucasols/utils/blob/main/packages/utils/src/yamlStringify.ts#L15)
28
+
29
+ ##### collapseObjects?
26
30
 
27
- ###### addRootObjSpaces?
31
+ ```ts
32
+ optional collapseObjects: boolean;
33
+ ```
34
+
35
+ Defined in: [packages/utils/src/yamlStringify.ts:13](https://github.com/lucasols/utils/blob/main/packages/utils/src/yamlStringify.ts#L13)
36
+
37
+ ##### maxDepth?
38
+
39
+ ```ts
40
+ optional maxDepth: number;
41
+ ```
28
42
 
29
- `false` \| `"beforeAndAfter"` \| `"before"` \| `"after"` = `'beforeAndAfter'`
43
+ Defined in: [packages/utils/src/yamlStringify.ts:11](https://github.com/lucasols/utils/blob/main/packages/utils/src/yamlStringify.ts#L11)
30
44
 
31
- ###### maxDepth?
45
+ ##### maxLineLength?
32
46
 
33
- `number` = `50`
47
+ ```ts
48
+ optional maxLineLength: number;
49
+ ```
34
50
 
35
- ###### maxLineLength?
51
+ Defined in: [packages/utils/src/yamlStringify.ts:7](https://github.com/lucasols/utils/blob/main/packages/utils/src/yamlStringify.ts#L7)
36
52
 
37
- `number` = `100`
53
+ ##### showUndefined?
38
54
 
39
- ###### showUndefined?
55
+ ```ts
56
+ optional showUndefined: boolean;
57
+ ```
58
+
59
+ Defined in: [packages/utils/src/yamlStringify.ts:9](https://github.com/lucasols/utils/blob/main/packages/utils/src/yamlStringify.ts#L9)
60
+
61
+ ## Functions
62
+
63
+ ### yamlStringify()
64
+
65
+ ```ts
66
+ function yamlStringify(obj, __namedParameters): string;
67
+ ```
68
+
69
+ Defined in: [packages/utils/src/yamlStringify.ts:18](https://github.com/lucasols/utils/blob/main/packages/utils/src/yamlStringify.ts#L18)
70
+
71
+ #### Parameters
72
+
73
+ ##### obj
74
+
75
+ `unknown`
76
+
77
+ ##### \_\_namedParameters
40
78
 
41
- `boolean`
79
+ [`YamlStringifyOptions`](#yamlstringifyoptions) = `{}`
42
80
 
43
81
  #### Returns
44
82
 
@@ -0,0 +1,353 @@
1
+ import {
2
+ bytesToHumanReadable
3
+ } from "./chunk-IATIXMCE.js";
4
+ import {
5
+ truncateString
6
+ } from "./chunk-4REIIZQY.js";
7
+ import {
8
+ isObject,
9
+ isPlainObject
10
+ } from "./chunk-JF2MDHOJ.js";
11
+
12
+ // src/yamlStringify.ts
13
+ function yamlStringify(obj, {
14
+ maxLineLength = 100,
15
+ showUndefined,
16
+ maxDepth = 50,
17
+ collapseObjects = false,
18
+ addRootObjSpaces = "beforeAndAfter"
19
+ } = {}) {
20
+ if (isObject(obj) || Array.isArray(obj) || typeof obj === "function") {
21
+ return `${stringifyValue(obj, "", maxLineLength, !!showUndefined, maxDepth, 0, collapseObjects, addRootObjSpaces)}
22
+ `;
23
+ }
24
+ return JSON.stringify(obj) || "undefined";
25
+ }
26
+ function stringifyValue(value, indent, maxLineLength, showUndefined, maxDepth, depth, collapseObjects, addObjSpaces) {
27
+ let result = "";
28
+ const childIndent = `${indent} `;
29
+ if (isPlainObject(value)) {
30
+ if (Object.keys(value).length === 0) {
31
+ return "{}";
32
+ }
33
+ if (collapseObjects && depth > 0) {
34
+ const entries = Object.entries(value).filter(
35
+ ([, val]) => val !== void 0 || showUndefined
36
+ );
37
+ const isSimpleObject = entries.every(
38
+ ([, val]) => {
39
+ if (typeof val === "string") {
40
+ return !val.includes("'") && !val.includes('"') && !val.includes("\\");
41
+ }
42
+ return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
43
+ }
44
+ );
45
+ if (isSimpleObject && entries.length > 0) {
46
+ let line = "{ ";
47
+ line += entries.map(([key, val]) => {
48
+ let valueStr;
49
+ if (typeof val === "string") {
50
+ if (val.includes("'") && !val.includes('"')) {
51
+ valueStr = `"${val}"`;
52
+ } else if (val.includes('"') && !val.includes("'")) {
53
+ valueStr = `'${val}'`;
54
+ } else if (val.includes("'") && val.includes('"')) {
55
+ valueStr = `"${val.replace(/"/g, '\\"')}"`;
56
+ } else {
57
+ valueStr = `'${val}'`;
58
+ }
59
+ } else {
60
+ valueStr = String(val);
61
+ }
62
+ return `${key}: ${valueStr}`;
63
+ }).join(", ");
64
+ line += " }";
65
+ if (line.length <= maxLineLength) {
66
+ return line;
67
+ }
68
+ }
69
+ }
70
+ let prevValue;
71
+ let afterSpaceWasAdded = false;
72
+ for (let [key, objVal] of Object.entries(value)) {
73
+ if (objVal === void 0 && !showUndefined) {
74
+ continue;
75
+ }
76
+ if (depth > maxDepth) {
77
+ objVal = `{max depth reached}`;
78
+ }
79
+ const normalizedValue2 = normalizeValue(objVal);
80
+ if (normalizedValue2 !== null) {
81
+ objVal = normalizedValue2[1];
82
+ key = `${key}{${normalizedValue2[0]}}`;
83
+ }
84
+ const valueString = stringifyValue(
85
+ objVal,
86
+ childIndent,
87
+ maxLineLength,
88
+ showUndefined,
89
+ maxDepth,
90
+ depth + 1,
91
+ collapseObjects,
92
+ addObjSpaces
93
+ );
94
+ const willBeCollapsed = isObject(objVal) && (Object.keys(objVal).length === 0 || collapseObjects && depth + 1 > 0 && Object.entries(objVal).filter(([, val]) => val !== void 0 || showUndefined).every(([, val]) => {
95
+ if (typeof val === "string") {
96
+ return !val.includes("'") && !val.includes('"') && !val.includes("\\");
97
+ }
98
+ return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
99
+ }));
100
+ 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]) => {
101
+ if (typeof val === "string") {
102
+ return !val.includes("'") && !val.includes('"') && !val.includes("\\");
103
+ }
104
+ return typeof val === "number" || typeof val === "boolean" || val === null || val === void 0;
105
+ }));
106
+ if (!afterSpaceWasAdded && indent === "" && isObject(objVal) && !willBeCollapsed && prevValue && !prevWasCollapsed && (addObjSpaces === "before" || addObjSpaces === "beforeAndAfter")) {
107
+ result += "\n";
108
+ }
109
+ if (Array.isArray(objVal)) {
110
+ const arrayIsSingleLine = valueString.split("\n").length === 1;
111
+ if (arrayIsSingleLine && !valueString.trim().startsWith("-")) {
112
+ result += `${indent}${key}: `;
113
+ } else {
114
+ result += `${indent}${key}:
115
+ `;
116
+ }
117
+ } else if (isObject(objVal)) {
118
+ const isCollapsedObject = valueString.startsWith("{") && !valueString.includes("\n");
119
+ if (Object.keys(objVal).length === 0 || isCollapsedObject) {
120
+ result += `${indent}${key}: `;
121
+ } else {
122
+ result += `${indent}${key}:
123
+ `;
124
+ }
125
+ } else {
126
+ result += `${indent}${key}: `;
127
+ }
128
+ result += valueString;
129
+ result += "\n";
130
+ if (indent === "") {
131
+ const isCollapsedObject = valueString.startsWith("{") && !valueString.includes("\n") && valueString.length > 2;
132
+ if (isObject(objVal) && !isCollapsedObject) {
133
+ if (addObjSpaces === "after" || addObjSpaces === "beforeAndAfter") {
134
+ result += "\n";
135
+ afterSpaceWasAdded = true;
136
+ } else {
137
+ afterSpaceWasAdded = false;
138
+ }
139
+ }
140
+ }
141
+ prevValue = objVal;
142
+ }
143
+ return result.trimEnd();
144
+ }
145
+ if (Array.isArray(value)) {
146
+ let arrayWasAdded = false;
147
+ if (value.length === 0 || value.every(
148
+ (item) => typeof item === "string" || typeof item === "number" || typeof item === "boolean" || item === null || item === void 0
149
+ )) {
150
+ let line = "";
151
+ line += `[`;
152
+ line += value.map((item) => {
153
+ let valueToUse = item;
154
+ if (depth > maxDepth) {
155
+ valueToUse = `{max depth reached}`;
156
+ }
157
+ if (typeof valueToUse === "string" && valueToUse.includes("\n")) {
158
+ valueToUse = valueToUse.replace(/\n/g, "\\n");
159
+ }
160
+ return stringifyValue(
161
+ valueToUse,
162
+ "",
163
+ maxLineLength,
164
+ showUndefined,
165
+ maxDepth,
166
+ depth + 1,
167
+ collapseObjects,
168
+ addObjSpaces
169
+ );
170
+ }).join(", ");
171
+ line += "]";
172
+ if (line.length <= maxLineLength) {
173
+ result += line;
174
+ arrayWasAdded = true;
175
+ }
176
+ }
177
+ if (!arrayWasAdded) {
178
+ for (let item of value) {
179
+ if (depth > maxDepth) {
180
+ item = `{max depth reached}`;
181
+ }
182
+ result += `${indent}- `;
183
+ if (Array.isArray(item) || isObject(item)) {
184
+ let arrayString = stringifyValue(
185
+ item,
186
+ childIndent,
187
+ maxLineLength,
188
+ showUndefined,
189
+ maxDepth,
190
+ depth + 1,
191
+ collapseObjects,
192
+ addObjSpaces
193
+ );
194
+ arrayString = arrayString.trimStart();
195
+ result += arrayString;
196
+ } else {
197
+ result += stringifyValue(
198
+ item,
199
+ childIndent,
200
+ maxLineLength,
201
+ showUndefined,
202
+ maxDepth,
203
+ depth + 1,
204
+ collapseObjects,
205
+ addObjSpaces
206
+ );
207
+ }
208
+ result += "\n";
209
+ }
210
+ }
211
+ return result.trimEnd();
212
+ }
213
+ if (typeof value === "string") {
214
+ if (value.includes("\n")) {
215
+ const lines = value.split("\n");
216
+ for (const [i, line] of lines.entries()) {
217
+ if (i === 0) {
218
+ if (value.endsWith("\n")) {
219
+ result += `|`;
220
+ } else {
221
+ result += `|-`;
222
+ }
223
+ result += `
224
+ ${indent}${line}
225
+ `;
226
+ } else {
227
+ result += `${indent}${line}
228
+ `;
229
+ }
230
+ }
231
+ } else {
232
+ if (value.includes("'") && !value.includes('"')) {
233
+ result += `"${value}"`;
234
+ } else if (value.includes('"') && !value.includes("'")) {
235
+ result += `'${value}'`;
236
+ } else if (value.includes("'") && value.includes('"')) {
237
+ result += `"${value.replace(/"/g, '\\"')}"`;
238
+ } else {
239
+ result += `'${value}'`;
240
+ }
241
+ }
242
+ return result.trimEnd();
243
+ }
244
+ if (typeof value === "number" || typeof value === "boolean" || value === null || value === void 0) {
245
+ return String(value).trimEnd();
246
+ }
247
+ const normalizedValue = normalizeValue(value);
248
+ if (normalizedValue !== null) {
249
+ return stringifyValue(
250
+ {
251
+ [`${normalizedValue[0]}#`]: normalizedValue[1]
252
+ },
253
+ indent,
254
+ maxLineLength,
255
+ showUndefined,
256
+ maxDepth,
257
+ depth + 1,
258
+ collapseObjects,
259
+ addObjSpaces
260
+ );
261
+ }
262
+ return JSON.stringify(value);
263
+ }
264
+ function normalizeValue(value) {
265
+ if (value === null || isPlainObject(value) || Array.isArray(value)) {
266
+ return null;
267
+ }
268
+ if (value instanceof Map) {
269
+ const mapEntries = Array.from(value.entries());
270
+ let mapValue;
271
+ if (mapEntries.every(([key]) => typeof key === "string")) {
272
+ const mapObjValue = {};
273
+ for (const [key, val] of mapEntries) {
274
+ mapObjValue[key] = val;
275
+ }
276
+ mapValue = mapObjValue;
277
+ } else {
278
+ mapValue = mapEntries.map(([key, val]) => ({
279
+ key,
280
+ value: val
281
+ }));
282
+ }
283
+ return ["Map", mapValue];
284
+ }
285
+ if (value instanceof Set) {
286
+ const setValue = Array.from(value);
287
+ return ["Set", setValue];
288
+ }
289
+ if (value instanceof Date) {
290
+ return ["Date", value.toISOString()];
291
+ }
292
+ if (value instanceof RegExp) {
293
+ return ["RegExp", value.toString()];
294
+ }
295
+ if (value instanceof Error) {
296
+ return [
297
+ "Error",
298
+ {
299
+ message: value.message,
300
+ name: value.name,
301
+ stack: value.stack
302
+ }
303
+ ];
304
+ }
305
+ if (value instanceof File) {
306
+ return [
307
+ "File",
308
+ {
309
+ name: value.name,
310
+ type: value.type,
311
+ lastModified: new Date(value.lastModified).toISOString(),
312
+ size: bytesToHumanReadable(value.size)
313
+ }
314
+ ];
315
+ }
316
+ if (typeof value === "object") {
317
+ if ("toJSON" in value && typeof value.toJSON === "function") {
318
+ return [value.constructor.name, value.toJSON()];
319
+ }
320
+ if ("toString" in value && typeof value.toString === "function") {
321
+ const stringValue = value.toString();
322
+ if (stringValue.toString() !== "[object Object]") {
323
+ return [value.constructor.name, stringValue];
324
+ }
325
+ }
326
+ const objectValue = { ...value };
327
+ const displayValue = {};
328
+ let addedKeys = 0;
329
+ for (const [key, item] of Object.entries(objectValue)) {
330
+ if (addedKeys > 4) {
331
+ displayValue["...and more properties"] = Object.keys(objectValue).length - 4;
332
+ break;
333
+ }
334
+ if (typeof item === "string" || typeof item === "number" || typeof item === "boolean" || item === null || item === void 0) {
335
+ displayValue[key] = item;
336
+ addedKeys++;
337
+ }
338
+ }
339
+ return [String(value.constructor.name), displayValue];
340
+ }
341
+ if (typeof value === "function") {
342
+ const functionString = value.toString();
343
+ return [
344
+ `Function`,
345
+ functionString.includes("\n") ? truncateString(functionString.split("\n").join(""), 40) : functionString
346
+ ];
347
+ }
348
+ return null;
349
+ }
350
+
351
+ export {
352
+ yamlStringify
353
+ };