@ls-stack/utils 3.45.0 → 3.47.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.
@@ -5,11 +5,13 @@ import {
5
5
  // src/partialEqual.ts
6
6
  var has = Object.prototype.hasOwnProperty;
7
7
  function createComparison(type) {
8
- return {
9
- "~sc": type
10
- };
8
+ return { "~sc": type };
11
9
  }
12
10
  var match = {
11
+ noExtraKeys: (partialShape) => createComparison(["withNoExtraKeys", partialShape]),
12
+ deepNoExtraKeys: (partialShape) => createComparison(["withDeepNoExtraKeys", partialShape]),
13
+ noExtraDefinedKeys: (partialShape) => createComparison(["noExtraDefinedKeys", partialShape]),
14
+ deepNoExtraDefinedKeys: (partialShape) => createComparison(["deepNoExtraDefinedKeys", partialShape]),
13
15
  hasType: {
14
16
  string: createComparison(["hasType", "string"]),
15
17
  number: createComparison(["hasType", "number"]),
@@ -50,6 +52,7 @@ var match = {
50
52
  array: createComparison(["not", ["hasType", "array"]]),
51
53
  function: createComparison(["not", ["hasType", "function"]])
52
54
  },
55
+ keyNotBePresent: createComparison(["not", ["keyNotBePresent", null]]),
53
56
  isInstanceOf: (constructor) => createComparison(["not", ["isInstanceOf", constructor]]),
54
57
  str: {
55
58
  contains: (substring) => createComparison(["not", ["strContains", substring]]),
@@ -71,7 +74,11 @@ var match = {
71
74
  partialEqual: (value) => createComparison(["not", ["partialEqual", value]]),
72
75
  custom: (value) => createComparison(["not", ["custom", value]]),
73
76
  any: (...comparisons) => createComparison(["not", ["any", comparisons.map((c) => c["~sc"])]]),
74
- all: (...comparisons) => createComparison(["not", ["all", comparisons.map((c) => c["~sc"])]])
77
+ all: (...comparisons) => createComparison(["not", ["all", comparisons.map((c) => c["~sc"])]]),
78
+ noExtraKeys: (partialShape) => createComparison(["not", ["withNoExtraKeys", partialShape]]),
79
+ deepNoExtraKeys: (partialShape) => createComparison(["not", ["withDeepNoExtraKeys", partialShape]]),
80
+ noExtraDefinedKeys: (partialShape) => createComparison(["not", ["noExtraDefinedKeys", partialShape]]),
81
+ deepNoExtraDefinedKeys: (partialShape) => createComparison(["not", ["deepNoExtraDefinedKeys", partialShape]])
75
82
  }
76
83
  };
77
84
  function find(iter, tar) {
@@ -169,6 +176,128 @@ function executeComparison(target, comparison) {
169
176
  return true;
170
177
  case "not":
171
178
  return !executeComparison(target, value);
179
+ case "withNoExtraKeys":
180
+ if (typeof target !== "object" || target === null || Array.isArray(target)) {
181
+ return false;
182
+ }
183
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
184
+ return false;
185
+ }
186
+ for (const key in target) {
187
+ if (has.call(target, key) && !has.call(value, key)) {
188
+ return false;
189
+ }
190
+ }
191
+ for (const key in value) {
192
+ if (has.call(value, key)) {
193
+ if (!has.call(target, key)) {
194
+ return false;
195
+ }
196
+ if (!partialEqual(target[key], value[key])) {
197
+ return false;
198
+ }
199
+ }
200
+ }
201
+ return true;
202
+ case "withDeepNoExtraKeys":
203
+ if (typeof target !== "object" || target === null || Array.isArray(target)) {
204
+ return false;
205
+ }
206
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
207
+ return false;
208
+ }
209
+ for (const key in target) {
210
+ if (has.call(target, key) && !has.call(value, key)) {
211
+ return false;
212
+ }
213
+ }
214
+ for (const key in value) {
215
+ if (has.call(value, key)) {
216
+ if (!has.call(target, key)) {
217
+ return false;
218
+ }
219
+ const targetValue = target[key];
220
+ const partialValue = value[key];
221
+ if (partialValue && typeof partialValue === "object" && "~sc" in partialValue && partialValue["~sc"][0] === "withDeepNoExtraKeys") {
222
+ if (!executeComparison(targetValue, partialValue["~sc"])) {
223
+ return false;
224
+ }
225
+ } else if (partialValue && typeof partialValue === "object" && !Array.isArray(partialValue) && partialValue.constructor === Object && targetValue && typeof targetValue === "object" && !Array.isArray(targetValue) && targetValue.constructor === Object) {
226
+ if (!executeComparison(targetValue, [
227
+ "withDeepNoExtraKeys",
228
+ partialValue
229
+ ])) {
230
+ return false;
231
+ }
232
+ } else {
233
+ if (!partialEqual(targetValue, partialValue)) {
234
+ return false;
235
+ }
236
+ }
237
+ }
238
+ }
239
+ return true;
240
+ case "noExtraDefinedKeys":
241
+ if (typeof target !== "object" || target === null || Array.isArray(target)) {
242
+ return false;
243
+ }
244
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
245
+ return false;
246
+ }
247
+ for (const key in target) {
248
+ if (has.call(target, key) && target[key] !== void 0 && !has.call(value, key)) {
249
+ return false;
250
+ }
251
+ }
252
+ for (const key in value) {
253
+ if (has.call(value, key)) {
254
+ if (!has.call(target, key)) {
255
+ return false;
256
+ }
257
+ if (!partialEqual(target[key], value[key])) {
258
+ return false;
259
+ }
260
+ }
261
+ }
262
+ return true;
263
+ case "deepNoExtraDefinedKeys":
264
+ if (typeof target !== "object" || target === null || Array.isArray(target)) {
265
+ return false;
266
+ }
267
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
268
+ return false;
269
+ }
270
+ for (const key in target) {
271
+ if (has.call(target, key) && target[key] !== void 0 && !has.call(value, key)) {
272
+ return false;
273
+ }
274
+ }
275
+ for (const key in value) {
276
+ if (has.call(value, key)) {
277
+ if (!has.call(target, key)) {
278
+ return false;
279
+ }
280
+ const targetValue = target[key];
281
+ const partialValue = value[key];
282
+ if (partialValue && typeof partialValue === "object" && "~sc" in partialValue && partialValue["~sc"][0] === "deepNoExtraDefinedKeys") {
283
+ if (!executeComparison(targetValue, partialValue["~sc"])) {
284
+ return false;
285
+ }
286
+ } else if (partialValue && typeof partialValue === "object" && !Array.isArray(partialValue) && partialValue.constructor === Object && targetValue && typeof targetValue === "object" && !Array.isArray(targetValue) && targetValue.constructor === Object) {
287
+ if (!executeComparison(targetValue, [
288
+ "deepNoExtraDefinedKeys",
289
+ partialValue
290
+ ])) {
291
+ return false;
292
+ }
293
+ } else {
294
+ if (!partialEqual(targetValue, partialValue)) {
295
+ return false;
296
+ }
297
+ }
298
+ }
299
+ }
300
+ return true;
172
301
  default:
173
302
  return false;
174
303
  }
@@ -231,7 +360,11 @@ function partialEqual(target, sub) {
231
360
  } else if (subValue && typeof subValue === "object" && "~sc" in subValue && subValue["~sc"][0] === "any") {
232
361
  const targetHasKey = has.call(target, key);
233
362
  const targetValue = targetHasKey ? target[key] : void 0;
234
- if (!executeComparisonWithKeyContext(targetValue, subValue["~sc"], targetHasKey)) {
363
+ if (!executeComparisonWithKeyContext(
364
+ targetValue,
365
+ subValue["~sc"],
366
+ targetHasKey
367
+ )) {
235
368
  return false;
236
369
  }
237
370
  } else {
@@ -155,6 +155,51 @@ function deepEqual(foo, bar, maxDepth = 20) {
155
155
  return foo !== foo && bar !== bar;
156
156
  }
157
157
 
158
+ // src/deepReplaceValues.ts
159
+ function applyValueReplacements(value, replaceValues, visited, currentPath) {
160
+ function processValue(val, path) {
161
+ const replacement = replaceValues(val, path);
162
+ if (replacement !== false) {
163
+ return replacement.newValue;
164
+ }
165
+ if (Array.isArray(val)) {
166
+ if (visited.has(val)) {
167
+ throw new Error("Circular reference detected in array");
168
+ }
169
+ visited.add(val);
170
+ try {
171
+ return val.map((item, index) => {
172
+ const itemPath = path ? `${path}[${index}]` : `[${index}]`;
173
+ return processValue(item, itemPath);
174
+ });
175
+ } finally {
176
+ visited.delete(val);
177
+ }
178
+ }
179
+ if (isPlainObject(val)) {
180
+ if (visited.has(val)) {
181
+ throw new Error("Circular reference detected in object");
182
+ }
183
+ visited.add(val);
184
+ try {
185
+ const result = {};
186
+ for (const [key, itemValue] of Object.entries(val)) {
187
+ const itemPath = path ? `${path}.${key}` : key;
188
+ result[key] = processValue(itemValue, itemPath);
189
+ }
190
+ return result;
191
+ } finally {
192
+ visited.delete(val);
193
+ }
194
+ }
195
+ return val;
196
+ }
197
+ return processValue(value, currentPath);
198
+ }
199
+ function deepReplaceValues(value, replaceValues) {
200
+ return applyValueReplacements(value, replaceValues, /* @__PURE__ */ new Set(), "");
201
+ }
202
+
158
203
  // src/filterObjectOrArrayKeys.ts
159
204
  var ID_PROP_REGEXP = /^(id_|key_|id-|key-)|(_id|_key|-id|-key)$/i;
160
205
  function filterObjectOrArrayKeys(objOrArray, {
@@ -1368,7 +1413,7 @@ function compactSnapshot(value, {
1368
1413
  }
1369
1414
  }
1370
1415
  if (replaceValues) {
1371
- processedValue = applyValueReplacements(processedValue, replaceValues);
1416
+ processedValue = deepReplaceValues(processedValue, replaceValues);
1372
1417
  }
1373
1418
  processedValue = showBooleansAs ? replaceBooleansWithEmoji(processedValue, showBooleansAs) : processedValue;
1374
1419
  return `
@@ -1379,46 +1424,6 @@ ${yamlStringify(processedValue, {
1379
1424
  ...options
1380
1425
  })}`;
1381
1426
  }
1382
- function applyValueReplacements(value, replaceValues, visited = /* @__PURE__ */ new Set(), currentPath = "") {
1383
- function processValue(val, path) {
1384
- const replacement = replaceValues(val, path);
1385
- if (replacement !== false) {
1386
- return replacement.newValue;
1387
- }
1388
- if (Array.isArray(val)) {
1389
- if (visited.has(val)) {
1390
- throw new Error("Circular reference detected in array");
1391
- }
1392
- visited.add(val);
1393
- try {
1394
- return val.map((item, index) => {
1395
- const itemPath = path ? `${path}[${index}]` : `[${index}]`;
1396
- return processValue(item, itemPath);
1397
- });
1398
- } finally {
1399
- visited.delete(val);
1400
- }
1401
- }
1402
- if (isPlainObject(val)) {
1403
- if (visited.has(val)) {
1404
- throw new Error("Circular reference detected in object");
1405
- }
1406
- visited.add(val);
1407
- try {
1408
- const result = {};
1409
- for (const [key, itemValue] of Object.entries(val)) {
1410
- const itemPath = path ? `${path}.${key}` : key;
1411
- result[key] = processValue(itemValue, itemPath);
1412
- }
1413
- return result;
1414
- } finally {
1415
- visited.delete(val);
1416
- }
1417
- }
1418
- return val;
1419
- }
1420
- return processValue(value, currentPath);
1421
- }
1422
1427
  function replaceBooleansWithEmoji(value, showBooleansAs, visited = /* @__PURE__ */ new Set()) {
1423
1428
  if (showBooleansAs === false) {
1424
1429
  return value;
package/dist/testUtils.js CHANGED
@@ -6,13 +6,16 @@ import {
6
6
  pick
7
7
  } from "./chunk-Y45CE75W.js";
8
8
  import "./chunk-GMJTLFM6.js";
9
+ import {
10
+ filterObjectOrArrayKeys
11
+ } from "./chunk-6CG6JZKB.js";
9
12
  import "./chunk-IATIXMCE.js";
10
13
  import {
11
14
  deepEqual
12
15
  } from "./chunk-JQFUKJU5.js";
13
16
  import {
14
- filterObjectOrArrayKeys
15
- } from "./chunk-6CG6JZKB.js";
17
+ deepReplaceValues
18
+ } from "./chunk-PUKVXYYL.js";
16
19
  import {
17
20
  defer
18
21
  } from "./chunk-DFXNVEH6.js";
@@ -281,7 +284,7 @@ function compactSnapshot(value, {
281
284
  }
282
285
  }
283
286
  if (replaceValues) {
284
- processedValue = applyValueReplacements(processedValue, replaceValues);
287
+ processedValue = deepReplaceValues(processedValue, replaceValues);
285
288
  }
286
289
  processedValue = showBooleansAs ? replaceBooleansWithEmoji(processedValue, showBooleansAs) : processedValue;
287
290
  return `
@@ -292,46 +295,6 @@ ${yamlStringify(processedValue, {
292
295
  ...options
293
296
  })}`;
294
297
  }
295
- function applyValueReplacements(value, replaceValues, visited = /* @__PURE__ */ new Set(), currentPath = "") {
296
- function processValue(val, path) {
297
- const replacement = replaceValues(val, path);
298
- if (replacement !== false) {
299
- return replacement.newValue;
300
- }
301
- if (Array.isArray(val)) {
302
- if (visited.has(val)) {
303
- throw new Error("Circular reference detected in array");
304
- }
305
- visited.add(val);
306
- try {
307
- return val.map((item, index) => {
308
- const itemPath = path ? `${path}[${index}]` : `[${index}]`;
309
- return processValue(item, itemPath);
310
- });
311
- } finally {
312
- visited.delete(val);
313
- }
314
- }
315
- if (isPlainObject(val)) {
316
- if (visited.has(val)) {
317
- throw new Error("Circular reference detected in object");
318
- }
319
- visited.add(val);
320
- try {
321
- const result = {};
322
- for (const [key, itemValue] of Object.entries(val)) {
323
- const itemPath = path ? `${path}.${key}` : key;
324
- result[key] = processValue(itemValue, itemPath);
325
- }
326
- return result;
327
- } finally {
328
- visited.delete(val);
329
- }
330
- }
331
- return val;
332
- }
333
- return processValue(value, currentPath);
334
- }
335
298
  function replaceBooleansWithEmoji(value, showBooleansAs, visited = /* @__PURE__ */ new Set()) {
336
299
  if (showBooleansAs === false) {
337
300
  return value;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ls-stack/utils",
3
3
  "description": "Universal TypeScript utilities for browser and Node.js",
4
- "version": "3.45.0",
4
+ "version": "3.47.0",
5
5
  "license": "MIT",
6
6
  "files": [
7
7
  "dist",
@@ -76,6 +76,10 @@
76
76
  "import": "./dist/deepEqual.js",
77
77
  "require": "./dist/deepEqual.cjs"
78
78
  },
79
+ "./deepReplaceValues": {
80
+ "import": "./dist/deepReplaceValues.js",
81
+ "require": "./dist/deepReplaceValues.cjs"
82
+ },
79
83
  "./enhancedMap": {
80
84
  "import": "./dist/enhancedMap.js",
81
85
  "require": "./dist/enhancedMap.cjs"