@ls-stack/utils 3.44.1 → 3.46.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.
@@ -92,11 +92,13 @@ function deepEqual(foo, bar, maxDepth = 20) {
92
92
  // src/partialEqual.ts
93
93
  var has2 = Object.prototype.hasOwnProperty;
94
94
  function createComparison(type) {
95
- return {
96
- "~sc": type
97
- };
95
+ return { "~sc": type };
98
96
  }
99
97
  var match = {
98
+ noExtraKeys: (partialShape) => createComparison(["withNoExtraKeys", partialShape]),
99
+ deepNoExtraKeys: (partialShape) => createComparison(["withDeepNoExtraKeys", partialShape]),
100
+ noExtraDefinedKeys: (partialShape) => createComparison(["noExtraDefinedKeys", partialShape]),
101
+ deepNoExtraDefinedKeys: (partialShape) => createComparison(["deepNoExtraDefinedKeys", partialShape]),
100
102
  hasType: {
101
103
  string: createComparison(["hasType", "string"]),
102
104
  number: createComparison(["hasType", "number"]),
@@ -125,6 +127,9 @@ var match = {
125
127
  equal: (value) => createComparison(["deepEqual", value]),
126
128
  partialEqual: (value) => createComparison(["partialEqual", value]),
127
129
  custom: (isEqual) => createComparison(["custom", isEqual]),
130
+ keyNotBePresent: createComparison(["keyNotBePresent", null]),
131
+ any: (...comparisons) => createComparison(["any", comparisons.map((c) => c["~sc"])]),
132
+ all: (...comparisons) => createComparison(["all", comparisons.map((c) => c["~sc"])]),
128
133
  not: {
129
134
  hasType: {
130
135
  string: createComparison(["not", ["hasType", "string"]]),
@@ -134,6 +139,7 @@ var match = {
134
139
  array: createComparison(["not", ["hasType", "array"]]),
135
140
  function: createComparison(["not", ["hasType", "function"]])
136
141
  },
142
+ keyNotBePresent: createComparison(["not", ["keyNotBePresent", null]]),
137
143
  isInstanceOf: (constructor) => createComparison(["not", ["isInstanceOf", constructor]]),
138
144
  str: {
139
145
  contains: (substring) => createComparison(["not", ["strContains", substring]]),
@@ -153,7 +159,13 @@ var match = {
153
159
  },
154
160
  equal: (value) => createComparison(["not", ["deepEqual", value]]),
155
161
  partialEqual: (value) => createComparison(["not", ["partialEqual", value]]),
156
- custom: (value) => createComparison(["not", ["custom", value]])
162
+ custom: (value) => createComparison(["not", ["custom", value]]),
163
+ any: (...comparisons) => createComparison(["not", ["any", comparisons.map((c) => c["~sc"])]]),
164
+ all: (...comparisons) => createComparison(["not", ["all", comparisons.map((c) => c["~sc"])]]),
165
+ noExtraKeys: (partialShape) => createComparison(["not", ["withNoExtraKeys", partialShape]]),
166
+ deepNoExtraKeys: (partialShape) => createComparison(["not", ["withDeepNoExtraKeys", partialShape]]),
167
+ noExtraDefinedKeys: (partialShape) => createComparison(["not", ["noExtraDefinedKeys", partialShape]]),
168
+ deepNoExtraDefinedKeys: (partialShape) => createComparison(["not", ["deepNoExtraDefinedKeys", partialShape]])
157
169
  }
158
170
  };
159
171
  function find2(iter, tar) {
@@ -161,6 +173,24 @@ function find2(iter, tar) {
161
173
  if (partialEqual(key, tar)) return key;
162
174
  }
163
175
  }
176
+ function executeComparisonWithKeyContext(target, comp, keyExists) {
177
+ const [type, value] = comp;
178
+ if (type === "keyNotBePresent") {
179
+ return !keyExists;
180
+ }
181
+ if (type === "any") {
182
+ for (const childComp of value) {
183
+ if (executeComparisonWithKeyContext(target, childComp, keyExists)) {
184
+ return true;
185
+ }
186
+ }
187
+ return false;
188
+ }
189
+ if (type === "not") {
190
+ return !executeComparisonWithKeyContext(target, value, keyExists);
191
+ }
192
+ return executeComparison(target, comp);
193
+ }
164
194
  function executeComparison(target, comparison) {
165
195
  const [type, value] = comparison;
166
196
  switch (type) {
@@ -215,8 +245,146 @@ function executeComparison(target, comparison) {
215
245
  return partialEqual(target, value);
216
246
  case "custom":
217
247
  return value(target);
248
+ case "keyNotBePresent":
249
+ return false;
250
+ case "any":
251
+ for (const comp of value) {
252
+ if (executeComparison(target, comp)) {
253
+ return true;
254
+ }
255
+ }
256
+ return false;
257
+ case "all":
258
+ for (const comp of value) {
259
+ if (!executeComparison(target, comp)) {
260
+ return false;
261
+ }
262
+ }
263
+ return true;
218
264
  case "not":
219
265
  return !executeComparison(target, value);
266
+ case "withNoExtraKeys":
267
+ if (typeof target !== "object" || target === null || Array.isArray(target)) {
268
+ return false;
269
+ }
270
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
271
+ return false;
272
+ }
273
+ for (const key in target) {
274
+ if (has2.call(target, key) && !has2.call(value, key)) {
275
+ return false;
276
+ }
277
+ }
278
+ for (const key in value) {
279
+ if (has2.call(value, key)) {
280
+ if (!has2.call(target, key)) {
281
+ return false;
282
+ }
283
+ if (!partialEqual(target[key], value[key])) {
284
+ return false;
285
+ }
286
+ }
287
+ }
288
+ return true;
289
+ case "withDeepNoExtraKeys":
290
+ if (typeof target !== "object" || target === null || Array.isArray(target)) {
291
+ return false;
292
+ }
293
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
294
+ return false;
295
+ }
296
+ for (const key in target) {
297
+ if (has2.call(target, key) && !has2.call(value, key)) {
298
+ return false;
299
+ }
300
+ }
301
+ for (const key in value) {
302
+ if (has2.call(value, key)) {
303
+ if (!has2.call(target, key)) {
304
+ return false;
305
+ }
306
+ const targetValue = target[key];
307
+ const partialValue = value[key];
308
+ if (partialValue && typeof partialValue === "object" && "~sc" in partialValue && partialValue["~sc"][0] === "withDeepNoExtraKeys") {
309
+ if (!executeComparison(targetValue, partialValue["~sc"])) {
310
+ return false;
311
+ }
312
+ } else if (partialValue && typeof partialValue === "object" && !Array.isArray(partialValue) && partialValue.constructor === Object && targetValue && typeof targetValue === "object" && !Array.isArray(targetValue) && targetValue.constructor === Object) {
313
+ if (!executeComparison(targetValue, [
314
+ "withDeepNoExtraKeys",
315
+ partialValue
316
+ ])) {
317
+ return false;
318
+ }
319
+ } else {
320
+ if (!partialEqual(targetValue, partialValue)) {
321
+ return false;
322
+ }
323
+ }
324
+ }
325
+ }
326
+ return true;
327
+ case "noExtraDefinedKeys":
328
+ if (typeof target !== "object" || target === null || Array.isArray(target)) {
329
+ return false;
330
+ }
331
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
332
+ return false;
333
+ }
334
+ for (const key in target) {
335
+ if (has2.call(target, key) && target[key] !== void 0 && !has2.call(value, key)) {
336
+ return false;
337
+ }
338
+ }
339
+ for (const key in value) {
340
+ if (has2.call(value, key)) {
341
+ if (!has2.call(target, key)) {
342
+ return false;
343
+ }
344
+ if (!partialEqual(target[key], value[key])) {
345
+ return false;
346
+ }
347
+ }
348
+ }
349
+ return true;
350
+ case "deepNoExtraDefinedKeys":
351
+ if (typeof target !== "object" || target === null || Array.isArray(target)) {
352
+ return false;
353
+ }
354
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
355
+ return false;
356
+ }
357
+ for (const key in target) {
358
+ if (has2.call(target, key) && target[key] !== void 0 && !has2.call(value, key)) {
359
+ return false;
360
+ }
361
+ }
362
+ for (const key in value) {
363
+ if (has2.call(value, key)) {
364
+ if (!has2.call(target, key)) {
365
+ return false;
366
+ }
367
+ const targetValue = target[key];
368
+ const partialValue = value[key];
369
+ if (partialValue && typeof partialValue === "object" && "~sc" in partialValue && partialValue["~sc"][0] === "deepNoExtraDefinedKeys") {
370
+ if (!executeComparison(targetValue, partialValue["~sc"])) {
371
+ return false;
372
+ }
373
+ } else if (partialValue && typeof partialValue === "object" && !Array.isArray(partialValue) && partialValue.constructor === Object && targetValue && typeof targetValue === "object" && !Array.isArray(targetValue) && targetValue.constructor === Object) {
374
+ if (!executeComparison(targetValue, [
375
+ "deepNoExtraDefinedKeys",
376
+ partialValue
377
+ ])) {
378
+ return false;
379
+ }
380
+ } else {
381
+ if (!partialEqual(targetValue, partialValue)) {
382
+ return false;
383
+ }
384
+ }
385
+ }
386
+ }
387
+ return true;
220
388
  default:
221
389
  return false;
222
390
  }
@@ -271,8 +439,25 @@ function partialEqual(target, sub) {
271
439
  if (!ctor || typeof sub === "object") {
272
440
  for (const key in sub) {
273
441
  if (has2.call(sub, key)) {
274
- if (!has2.call(target, key) || !partialEqual(target[key], sub[key])) {
275
- return false;
442
+ const subValue = sub[key];
443
+ if (subValue && typeof subValue === "object" && "~sc" in subValue && subValue["~sc"][0] === "keyNotBePresent") {
444
+ if (has2.call(target, key)) {
445
+ return false;
446
+ }
447
+ } else if (subValue && typeof subValue === "object" && "~sc" in subValue && subValue["~sc"][0] === "any") {
448
+ const targetHasKey = has2.call(target, key);
449
+ const targetValue = targetHasKey ? target[key] : void 0;
450
+ if (!executeComparisonWithKeyContext(
451
+ targetValue,
452
+ subValue["~sc"],
453
+ targetHasKey
454
+ )) {
455
+ return false;
456
+ }
457
+ } else {
458
+ if (!has2.call(target, key) || !partialEqual(target[key], subValue)) {
459
+ return false;
460
+ }
276
461
  }
277
462
  }
278
463
  }
@@ -1,11 +1,15 @@
1
1
  type ComparisonsType = [type: 'strStartsWith', value: string] | [type: 'strEndsWith', value: string] | [
2
2
  type: 'hasType',
3
3
  value: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'function'
4
- ] | [type: 'strContains', value: string] | [type: 'strMatchesRegex', value: RegExp] | [type: 'deepEqual', value: any] | [type: 'numIsGreaterThan', value: number] | [type: 'numIsGreaterThanOrEqual', value: number] | [type: 'numIsLessThan', value: number] | [type: 'numIsLessThanOrEqual', value: number] | [type: 'numIsInRange', value: [number, number]] | [type: 'jsonStringHasPartial', value: any] | [type: 'partialEqual', value: any] | [type: 'custom', value: (target: unknown) => boolean] | [type: 'isInstanceOf', value: new (...args: any[]) => any] | [type: 'not', value: ComparisonsType];
4
+ ] | [type: 'strContains', value: string] | [type: 'strMatchesRegex', value: RegExp] | [type: 'deepEqual', value: any] | [type: 'numIsGreaterThan', value: number] | [type: 'numIsGreaterThanOrEqual', value: number] | [type: 'numIsLessThan', value: number] | [type: 'numIsLessThanOrEqual', value: number] | [type: 'numIsInRange', value: [number, number]] | [type: 'jsonStringHasPartial', value: any] | [type: 'partialEqual', value: any] | [type: 'custom', value: (target: unknown) => boolean] | [type: 'isInstanceOf', value: new (...args: any[]) => any] | [type: 'keyNotBePresent', value: null] | [type: 'not', value: ComparisonsType] | [type: 'any', value: ComparisonsType[]] | [type: 'all', value: ComparisonsType[]] | [type: 'withNoExtraKeys', partialShape: any] | [type: 'withDeepNoExtraKeys', partialShape: any] | [type: 'noExtraDefinedKeys', partialShape: any] | [type: 'deepNoExtraDefinedKeys', partialShape: any];
5
5
  type Comparison = {
6
6
  '~sc': ComparisonsType;
7
7
  };
8
- declare const match: {
8
+ type BaseMatch = {
9
+ noExtraKeys: (partialShape: any) => Comparison;
10
+ deepNoExtraKeys: (partialShape: any) => Comparison;
11
+ noExtraDefinedKeys: (partialShape: any) => Comparison;
12
+ deepNoExtraDefinedKeys: (partialShape: any) => Comparison;
9
13
  hasType: {
10
14
  string: Comparison;
11
15
  number: Comparison;
@@ -34,37 +38,14 @@ declare const match: {
34
38
  equal: (value: any) => Comparison;
35
39
  partialEqual: (value: any) => Comparison;
36
40
  custom: (isEqual: (value: unknown) => boolean) => Comparison;
37
- not: {
38
- hasType: {
39
- string: Comparison;
40
- number: Comparison;
41
- boolean: Comparison;
42
- object: Comparison;
43
- array: Comparison;
44
- function: Comparison;
45
- };
46
- isInstanceOf: (constructor: new (...args: any[]) => any) => Comparison;
47
- str: {
48
- contains: (substring: string) => Comparison;
49
- startsWith: (substring: string) => Comparison;
50
- endsWith: (substring: string) => Comparison;
51
- matchesRegex: (regex: RegExp) => Comparison;
52
- };
53
- num: {
54
- isGreaterThan: (value: number) => Comparison;
55
- isGreaterThanOrEqual: (value: number) => Comparison;
56
- isLessThan: (value: number) => Comparison;
57
- isLessThanOrEqual: (value: number) => Comparison;
58
- isInRange: (value: [number, number]) => Comparison;
59
- };
60
- jsonString: {
61
- hasPartial: (value: any) => Comparison;
62
- };
63
- equal: (value: any) => Comparison;
64
- partialEqual: (value: any) => Comparison;
65
- custom: (value: (target: unknown) => boolean) => Comparison;
66
- };
41
+ keyNotBePresent: Comparison;
42
+ any: (...comparisons: Comparison[]) => Comparison;
43
+ all: (...comparisons: Comparison[]) => Comparison;
44
+ };
45
+ type Match = BaseMatch & {
46
+ not: BaseMatch;
67
47
  };
48
+ declare const match: Match;
68
49
  declare function partialEqual(target: any, sub: any): boolean;
69
50
 
70
51
  export { match, partialEqual };
@@ -1,11 +1,15 @@
1
1
  type ComparisonsType = [type: 'strStartsWith', value: string] | [type: 'strEndsWith', value: string] | [
2
2
  type: 'hasType',
3
3
  value: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'function'
4
- ] | [type: 'strContains', value: string] | [type: 'strMatchesRegex', value: RegExp] | [type: 'deepEqual', value: any] | [type: 'numIsGreaterThan', value: number] | [type: 'numIsGreaterThanOrEqual', value: number] | [type: 'numIsLessThan', value: number] | [type: 'numIsLessThanOrEqual', value: number] | [type: 'numIsInRange', value: [number, number]] | [type: 'jsonStringHasPartial', value: any] | [type: 'partialEqual', value: any] | [type: 'custom', value: (target: unknown) => boolean] | [type: 'isInstanceOf', value: new (...args: any[]) => any] | [type: 'not', value: ComparisonsType];
4
+ ] | [type: 'strContains', value: string] | [type: 'strMatchesRegex', value: RegExp] | [type: 'deepEqual', value: any] | [type: 'numIsGreaterThan', value: number] | [type: 'numIsGreaterThanOrEqual', value: number] | [type: 'numIsLessThan', value: number] | [type: 'numIsLessThanOrEqual', value: number] | [type: 'numIsInRange', value: [number, number]] | [type: 'jsonStringHasPartial', value: any] | [type: 'partialEqual', value: any] | [type: 'custom', value: (target: unknown) => boolean] | [type: 'isInstanceOf', value: new (...args: any[]) => any] | [type: 'keyNotBePresent', value: null] | [type: 'not', value: ComparisonsType] | [type: 'any', value: ComparisonsType[]] | [type: 'all', value: ComparisonsType[]] | [type: 'withNoExtraKeys', partialShape: any] | [type: 'withDeepNoExtraKeys', partialShape: any] | [type: 'noExtraDefinedKeys', partialShape: any] | [type: 'deepNoExtraDefinedKeys', partialShape: any];
5
5
  type Comparison = {
6
6
  '~sc': ComparisonsType;
7
7
  };
8
- declare const match: {
8
+ type BaseMatch = {
9
+ noExtraKeys: (partialShape: any) => Comparison;
10
+ deepNoExtraKeys: (partialShape: any) => Comparison;
11
+ noExtraDefinedKeys: (partialShape: any) => Comparison;
12
+ deepNoExtraDefinedKeys: (partialShape: any) => Comparison;
9
13
  hasType: {
10
14
  string: Comparison;
11
15
  number: Comparison;
@@ -34,37 +38,14 @@ declare const match: {
34
38
  equal: (value: any) => Comparison;
35
39
  partialEqual: (value: any) => Comparison;
36
40
  custom: (isEqual: (value: unknown) => boolean) => Comparison;
37
- not: {
38
- hasType: {
39
- string: Comparison;
40
- number: Comparison;
41
- boolean: Comparison;
42
- object: Comparison;
43
- array: Comparison;
44
- function: Comparison;
45
- };
46
- isInstanceOf: (constructor: new (...args: any[]) => any) => Comparison;
47
- str: {
48
- contains: (substring: string) => Comparison;
49
- startsWith: (substring: string) => Comparison;
50
- endsWith: (substring: string) => Comparison;
51
- matchesRegex: (regex: RegExp) => Comparison;
52
- };
53
- num: {
54
- isGreaterThan: (value: number) => Comparison;
55
- isGreaterThanOrEqual: (value: number) => Comparison;
56
- isLessThan: (value: number) => Comparison;
57
- isLessThanOrEqual: (value: number) => Comparison;
58
- isInRange: (value: [number, number]) => Comparison;
59
- };
60
- jsonString: {
61
- hasPartial: (value: any) => Comparison;
62
- };
63
- equal: (value: any) => Comparison;
64
- partialEqual: (value: any) => Comparison;
65
- custom: (value: (target: unknown) => boolean) => Comparison;
66
- };
41
+ keyNotBePresent: Comparison;
42
+ any: (...comparisons: Comparison[]) => Comparison;
43
+ all: (...comparisons: Comparison[]) => Comparison;
44
+ };
45
+ type Match = BaseMatch & {
46
+ not: BaseMatch;
67
47
  };
48
+ declare const match: Match;
68
49
  declare function partialEqual(target: any, sub: any): boolean;
69
50
 
70
51
  export { match, partialEqual };
@@ -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"]),
@@ -38,6 +40,9 @@ var match = {
38
40
  equal: (value) => createComparison(["deepEqual", value]),
39
41
  partialEqual: (value) => createComparison(["partialEqual", value]),
40
42
  custom: (isEqual) => createComparison(["custom", isEqual]),
43
+ keyNotBePresent: createComparison(["keyNotBePresent", null]),
44
+ any: (...comparisons) => createComparison(["any", comparisons.map((c) => c["~sc"])]),
45
+ all: (...comparisons) => createComparison(["all", comparisons.map((c) => c["~sc"])]),
41
46
  not: {
42
47
  hasType: {
43
48
  string: createComparison(["not", ["hasType", "string"]]),
@@ -47,6 +52,7 @@ var match = {
47
52
  array: createComparison(["not", ["hasType", "array"]]),
48
53
  function: createComparison(["not", ["hasType", "function"]])
49
54
  },
55
+ keyNotBePresent: createComparison(["not", ["keyNotBePresent", null]]),
50
56
  isInstanceOf: (constructor) => createComparison(["not", ["isInstanceOf", constructor]]),
51
57
  str: {
52
58
  contains: (substring) => createComparison(["not", ["strContains", substring]]),
@@ -66,7 +72,13 @@ var match = {
66
72
  },
67
73
  equal: (value) => createComparison(["not", ["deepEqual", value]]),
68
74
  partialEqual: (value) => createComparison(["not", ["partialEqual", value]]),
69
- custom: (value) => createComparison(["not", ["custom", value]])
75
+ custom: (value) => createComparison(["not", ["custom", value]]),
76
+ any: (...comparisons) => createComparison(["not", ["any", 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]])
70
82
  }
71
83
  };
72
84
  function find(iter, tar) {
@@ -74,6 +86,24 @@ function find(iter, tar) {
74
86
  if (partialEqual(key, tar)) return key;
75
87
  }
76
88
  }
89
+ function executeComparisonWithKeyContext(target, comp, keyExists) {
90
+ const [type, value] = comp;
91
+ if (type === "keyNotBePresent") {
92
+ return !keyExists;
93
+ }
94
+ if (type === "any") {
95
+ for (const childComp of value) {
96
+ if (executeComparisonWithKeyContext(target, childComp, keyExists)) {
97
+ return true;
98
+ }
99
+ }
100
+ return false;
101
+ }
102
+ if (type === "not") {
103
+ return !executeComparisonWithKeyContext(target, value, keyExists);
104
+ }
105
+ return executeComparison(target, comp);
106
+ }
77
107
  function executeComparison(target, comparison) {
78
108
  const [type, value] = comparison;
79
109
  switch (type) {
@@ -128,8 +158,146 @@ function executeComparison(target, comparison) {
128
158
  return partialEqual(target, value);
129
159
  case "custom":
130
160
  return value(target);
161
+ case "keyNotBePresent":
162
+ return false;
163
+ case "any":
164
+ for (const comp of value) {
165
+ if (executeComparison(target, comp)) {
166
+ return true;
167
+ }
168
+ }
169
+ return false;
170
+ case "all":
171
+ for (const comp of value) {
172
+ if (!executeComparison(target, comp)) {
173
+ return false;
174
+ }
175
+ }
176
+ return true;
131
177
  case "not":
132
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;
133
301
  default:
134
302
  return false;
135
303
  }
@@ -184,8 +352,25 @@ function partialEqual(target, sub) {
184
352
  if (!ctor || typeof sub === "object") {
185
353
  for (const key in sub) {
186
354
  if (has.call(sub, key)) {
187
- if (!has.call(target, key) || !partialEqual(target[key], sub[key])) {
188
- return false;
355
+ const subValue = sub[key];
356
+ if (subValue && typeof subValue === "object" && "~sc" in subValue && subValue["~sc"][0] === "keyNotBePresent") {
357
+ if (has.call(target, key)) {
358
+ return false;
359
+ }
360
+ } else if (subValue && typeof subValue === "object" && "~sc" in subValue && subValue["~sc"][0] === "any") {
361
+ const targetHasKey = has.call(target, key);
362
+ const targetValue = targetHasKey ? target[key] : void 0;
363
+ if (!executeComparisonWithKeyContext(
364
+ targetValue,
365
+ subValue["~sc"],
366
+ targetHasKey
367
+ )) {
368
+ return false;
369
+ }
370
+ } else {
371
+ if (!has.call(target, key) || !partialEqual(target[key], subValue)) {
372
+ return false;
373
+ }
189
374
  }
190
375
  }
191
376
  }
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.44.1",
4
+ "version": "3.46.0",
5
5
  "license": "MIT",
6
6
  "files": [
7
7
  "dist",