@ls-stack/utils 3.41.0 → 3.43.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.
@@ -0,0 +1,50 @@
1
+ type ComparisonsType = [type: 'strStartsWith', value: string] | [type: 'strEndsWith', value: string] | [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: 'not', value: ComparisonsType];
2
+ declare class Comparisons {
3
+ type: ComparisonsType;
4
+ constructor(type: ComparisonsType);
5
+ }
6
+ declare const match: {
7
+ str: {
8
+ contains: (substring: string) => Comparisons;
9
+ startsWith: (substring: string) => Comparisons;
10
+ endsWith: (substring: string) => Comparisons;
11
+ matchesRegex: (regex: RegExp) => Comparisons;
12
+ };
13
+ num: {
14
+ isGreaterThan: (value: number) => Comparisons;
15
+ isGreaterThanOrEqual: (value: number) => Comparisons;
16
+ isLessThan: (value: number) => Comparisons;
17
+ isLessThanOrEqual: (value: number) => Comparisons;
18
+ isInRange: (value: [number, number]) => Comparisons;
19
+ };
20
+ jsonString: {
21
+ hasPartial: (value: any) => Comparisons;
22
+ };
23
+ equal: (value: any) => Comparisons;
24
+ partialEqual: (value: any) => Comparisons;
25
+ custom: (isEqual: (value: unknown) => boolean) => Comparisons;
26
+ not: {
27
+ str: {
28
+ contains: (substring: string) => Comparisons;
29
+ startsWith: (substring: string) => Comparisons;
30
+ endsWith: (substring: string) => Comparisons;
31
+ matchesRegex: (regex: RegExp) => Comparisons;
32
+ };
33
+ num: {
34
+ isGreaterThan: (value: number) => Comparisons;
35
+ isGreaterThanOrEqual: (value: number) => Comparisons;
36
+ isLessThan: (value: number) => Comparisons;
37
+ isLessThanOrEqual: (value: number) => Comparisons;
38
+ isInRange: (value: [number, number]) => Comparisons;
39
+ };
40
+ jsonString: {
41
+ hasPartial: (value: any) => Comparisons;
42
+ };
43
+ equal: (value: any) => Comparisons;
44
+ partialEqual: (value: any) => Comparisons;
45
+ custom: (value: (target: unknown) => boolean) => Comparisons;
46
+ };
47
+ };
48
+ declare function partialEqual(target: any, sub: any): boolean;
49
+
50
+ export { match, partialEqual };
@@ -0,0 +1,164 @@
1
+ import {
2
+ deepEqual
3
+ } from "./chunk-JQFUKJU5.js";
4
+
5
+ // src/partialEqual.ts
6
+ var has = Object.prototype.hasOwnProperty;
7
+ var Comparisons = class {
8
+ type;
9
+ constructor(type) {
10
+ this.type = type;
11
+ }
12
+ };
13
+ var match = {
14
+ str: {
15
+ contains: (substring) => new Comparisons(["strContains", substring]),
16
+ startsWith: (substring) => new Comparisons(["strStartsWith", substring]),
17
+ endsWith: (substring) => new Comparisons(["strEndsWith", substring]),
18
+ matchesRegex: (regex) => new Comparisons(["strMatchesRegex", regex])
19
+ },
20
+ num: {
21
+ isGreaterThan: (value) => new Comparisons(["numIsGreaterThan", value]),
22
+ isGreaterThanOrEqual: (value) => new Comparisons(["numIsGreaterThanOrEqual", value]),
23
+ isLessThan: (value) => new Comparisons(["numIsLessThan", value]),
24
+ isLessThanOrEqual: (value) => new Comparisons(["numIsLessThanOrEqual", value]),
25
+ isInRange: (value) => new Comparisons(["numIsInRange", value])
26
+ },
27
+ jsonString: {
28
+ hasPartial: (value) => new Comparisons(["jsonStringHasPartial", value])
29
+ },
30
+ equal: (value) => new Comparisons(["deepEqual", value]),
31
+ partialEqual: (value) => new Comparisons(["partialEqual", value]),
32
+ custom: (isEqual) => new Comparisons(["custom", isEqual]),
33
+ not: {
34
+ str: {
35
+ contains: (substring) => new Comparisons(["not", ["strContains", substring]]),
36
+ startsWith: (substring) => new Comparisons(["not", ["strStartsWith", substring]]),
37
+ endsWith: (substring) => new Comparisons(["not", ["strEndsWith", substring]]),
38
+ matchesRegex: (regex) => new Comparisons(["not", ["strMatchesRegex", regex]])
39
+ },
40
+ num: {
41
+ isGreaterThan: (value) => new Comparisons(["not", ["numIsGreaterThan", value]]),
42
+ isGreaterThanOrEqual: (value) => new Comparisons(["not", ["numIsGreaterThanOrEqual", value]]),
43
+ isLessThan: (value) => new Comparisons(["not", ["numIsLessThan", value]]),
44
+ isLessThanOrEqual: (value) => new Comparisons(["not", ["numIsLessThanOrEqual", value]]),
45
+ isInRange: (value) => new Comparisons(["not", ["numIsInRange", value]])
46
+ },
47
+ jsonString: {
48
+ hasPartial: (value) => new Comparisons(["not", ["jsonStringHasPartial", value]])
49
+ },
50
+ equal: (value) => new Comparisons(["not", ["deepEqual", value]]),
51
+ partialEqual: (value) => new Comparisons(["not", ["partialEqual", value]]),
52
+ custom: (value) => new Comparisons(["not", ["custom", value]])
53
+ }
54
+ };
55
+ function find(iter, tar) {
56
+ for (const key of iter.keys()) {
57
+ if (partialEqual(key, tar)) return key;
58
+ }
59
+ }
60
+ function executeComparison(target, comparison) {
61
+ const [type, value] = comparison;
62
+ switch (type) {
63
+ case "strStartsWith":
64
+ return typeof target === "string" && target.startsWith(value);
65
+ case "strEndsWith":
66
+ return typeof target === "string" && target.endsWith(value);
67
+ case "strContains":
68
+ return typeof target === "string" && target.includes(value);
69
+ case "strMatchesRegex":
70
+ return typeof target === "string" && value.test(target);
71
+ case "numIsGreaterThan":
72
+ return typeof target === "number" && target > value;
73
+ case "numIsGreaterThanOrEqual":
74
+ return typeof target === "number" && target >= value;
75
+ case "numIsLessThan":
76
+ return typeof target === "number" && target < value;
77
+ case "numIsLessThanOrEqual":
78
+ return typeof target === "number" && target <= value;
79
+ case "numIsInRange":
80
+ return typeof target === "number" && target >= value[0] && target <= value[1];
81
+ case "jsonStringHasPartial":
82
+ if (typeof target !== "string") return false;
83
+ try {
84
+ const parsed = JSON.parse(target);
85
+ return partialEqual(parsed, value);
86
+ } catch {
87
+ return false;
88
+ }
89
+ case "deepEqual":
90
+ return deepEqual(target, value);
91
+ case "partialEqual":
92
+ return partialEqual(target, value);
93
+ case "custom":
94
+ return value(target);
95
+ case "not":
96
+ return !executeComparison(target, value);
97
+ default:
98
+ return false;
99
+ }
100
+ }
101
+ function partialEqual(target, sub) {
102
+ if (sub === target) return true;
103
+ if (sub instanceof Comparisons) {
104
+ return executeComparison(target, sub.type);
105
+ }
106
+ if (sub && target && sub.constructor === target.constructor) {
107
+ const ctor = sub.constructor;
108
+ if (ctor === Date) {
109
+ return sub.getTime() === target.getTime();
110
+ }
111
+ if (ctor === RegExp) {
112
+ return sub.toString() === target.toString();
113
+ }
114
+ if (ctor === Array) {
115
+ if (sub.length > target.length) return false;
116
+ for (let i = 0; i < sub.length; i++) {
117
+ if (!partialEqual(target[i], sub[i])) return false;
118
+ }
119
+ return true;
120
+ }
121
+ if (ctor === Set) {
122
+ if (sub.size > target.size) return false;
123
+ for (const value of sub) {
124
+ let found = false;
125
+ if (value && typeof value === "object") {
126
+ found = !!find(target, value);
127
+ } else {
128
+ found = target.has(value);
129
+ }
130
+ if (!found) return false;
131
+ }
132
+ return true;
133
+ }
134
+ if (ctor === Map) {
135
+ if (sub.size > target.size) return false;
136
+ for (const [key, value] of sub) {
137
+ let targetKey = key;
138
+ if (key && typeof key === "object") {
139
+ targetKey = find(target, key);
140
+ if (!targetKey) return false;
141
+ }
142
+ if (!target.has(targetKey) || !partialEqual(target.get(targetKey), value)) {
143
+ return false;
144
+ }
145
+ }
146
+ return true;
147
+ }
148
+ if (!ctor || typeof sub === "object") {
149
+ for (const key in sub) {
150
+ if (has.call(sub, key)) {
151
+ if (!has.call(target, key) || !partialEqual(target[key], sub[key])) {
152
+ return false;
153
+ }
154
+ }
155
+ }
156
+ return true;
157
+ }
158
+ }
159
+ return sub !== sub && target !== target;
160
+ }
161
+ export {
162
+ match,
163
+ partialEqual
164
+ };
package/dist/testUtils.js CHANGED
@@ -4,8 +4,8 @@ import {
4
4
  import {
5
5
  omit,
6
6
  pick
7
- } from "./chunk-23KPGKDT.js";
8
- import "./chunk-DTE2QMWE.js";
7
+ } from "./chunk-Y45CE75W.js";
8
+ import "./chunk-GMJTLFM6.js";
9
9
  import "./chunk-IATIXMCE.js";
10
10
  import {
11
11
  deepEqual
@@ -23,9 +23,12 @@ __export(typingFnUtils_exports, {
23
23
  asNonPartial: () => asNonPartial,
24
24
  asPartialUndefinedValues: () => asPartialUndefinedValues,
25
25
  asType: () => asType,
26
+ isNonEmptyArray: () => isNonEmptyArray,
26
27
  isObjKey: () => isObjKey,
27
28
  isSubTypeOf: () => isSubTypeOf,
28
29
  narrowStringToUnion: () => narrowStringToUnion,
30
+ objectHasKey: () => objectHasKey,
31
+ strictTypedObjectEntries: () => strictTypedObjectEntries,
29
32
  typeOnRightExtendsLeftType: () => typeOnRightExtendsLeftType,
30
33
  typedObjectEntries: () => typedObjectEntries,
31
34
  typedObjectKeys: () => typedObjectKeys,
@@ -38,6 +41,9 @@ function asNonPartial(obj) {
38
41
  function typedObjectEntries(obj) {
39
42
  return Object.entries(obj);
40
43
  }
44
+ function strictTypedObjectEntries(obj) {
45
+ return Object.entries(obj);
46
+ }
41
47
  function typedObjectKeys(obj) {
42
48
  return Object.keys(obj);
43
49
  }
@@ -66,14 +72,23 @@ function unionsAreTheSame(_diff) {
66
72
  function asPartialUndefinedValues(value) {
67
73
  return value;
68
74
  }
75
+ function isNonEmptyArray(array) {
76
+ return array.length > 0;
77
+ }
78
+ function objectHasKey(obj, key) {
79
+ return key in obj;
80
+ }
69
81
  // Annotate the CommonJS export names for ESM import in node:
70
82
  0 && (module.exports = {
71
83
  asNonPartial,
72
84
  asPartialUndefinedValues,
73
85
  asType,
86
+ isNonEmptyArray,
74
87
  isObjKey,
75
88
  isSubTypeOf,
76
89
  narrowStringToUnion,
90
+ objectHasKey,
91
+ strictTypedObjectEntries,
77
92
  typeOnRightExtendsLeftType,
78
93
  typedObjectEntries,
79
94
  typedObjectKeys,
@@ -10,6 +10,15 @@ declare function asNonPartial<T extends Record<string, unknown>>(obj: T): NonPar
10
10
  declare function typedObjectEntries<T extends Record<string, unknown>>(obj: T): NonNullable<{
11
11
  [K in keyof T]: [K, T[K]];
12
12
  }[keyof T]>[];
13
+ /**
14
+ * A wrapper to Object.entries with a better typing inference, but with strict
15
+ * typing narrowing keys to strings.
16
+ *
17
+ * @param obj
18
+ */
19
+ declare function strictTypedObjectEntries<T extends Record<string, unknown>>(obj: T): NonNullable<{
20
+ [K in keyof T]: [K & string, T[K]];
21
+ }[keyof T]>[];
13
22
  /**
14
23
  * A wrapper to Object.keys with a better typing inference
15
24
  *
@@ -68,5 +77,24 @@ type UnionDiff<T, U> = [
68
77
  */
69
78
  declare function unionsAreTheSame<T, U>(_diff: UnionDiff<T, U>): void;
70
79
  declare function asPartialUndefinedValues<T extends Record<string, unknown>>(value: PartialPossiblyUndefinedValues<T>): T;
80
+ /** A type representing an array that is guaranteed to have at least one element. */
81
+ type NonEmptyArray<T> = [T, ...T[]];
82
+ /**
83
+ * Type guard to check if an array has at least one element.
84
+ *
85
+ * @param array - The array to check
86
+ * @returns True if the array is non-empty, false otherwise
87
+ */
88
+ declare function isNonEmptyArray<T>(array: T[]): array is NonEmptyArray<T>;
89
+ /**
90
+ * Type guard to check if an object has a specific key and narrow its type.
91
+ *
92
+ * @param obj - The object to check
93
+ * @param key - The key to check for
94
+ * @returns True if the object has the key, false otherwise
95
+ */
96
+ declare function objectHasKey<T extends string>(obj: object, key: T): obj is object & {
97
+ [K in T]: unknown;
98
+ };
71
99
 
72
- export { asNonPartial, asPartialUndefinedValues, asType, isObjKey, isSubTypeOf, narrowStringToUnion, typeOnRightExtendsLeftType, typedObjectEntries, typedObjectKeys, unionsAreTheSame };
100
+ export { type NonEmptyArray, asNonPartial, asPartialUndefinedValues, asType, isNonEmptyArray, isObjKey, isSubTypeOf, narrowStringToUnion, objectHasKey, strictTypedObjectEntries, typeOnRightExtendsLeftType, typedObjectEntries, typedObjectKeys, unionsAreTheSame };
@@ -10,6 +10,15 @@ declare function asNonPartial<T extends Record<string, unknown>>(obj: T): NonPar
10
10
  declare function typedObjectEntries<T extends Record<string, unknown>>(obj: T): NonNullable<{
11
11
  [K in keyof T]: [K, T[K]];
12
12
  }[keyof T]>[];
13
+ /**
14
+ * A wrapper to Object.entries with a better typing inference, but with strict
15
+ * typing narrowing keys to strings.
16
+ *
17
+ * @param obj
18
+ */
19
+ declare function strictTypedObjectEntries<T extends Record<string, unknown>>(obj: T): NonNullable<{
20
+ [K in keyof T]: [K & string, T[K]];
21
+ }[keyof T]>[];
13
22
  /**
14
23
  * A wrapper to Object.keys with a better typing inference
15
24
  *
@@ -68,5 +77,24 @@ type UnionDiff<T, U> = [
68
77
  */
69
78
  declare function unionsAreTheSame<T, U>(_diff: UnionDiff<T, U>): void;
70
79
  declare function asPartialUndefinedValues<T extends Record<string, unknown>>(value: PartialPossiblyUndefinedValues<T>): T;
80
+ /** A type representing an array that is guaranteed to have at least one element. */
81
+ type NonEmptyArray<T> = [T, ...T[]];
82
+ /**
83
+ * Type guard to check if an array has at least one element.
84
+ *
85
+ * @param array - The array to check
86
+ * @returns True if the array is non-empty, false otherwise
87
+ */
88
+ declare function isNonEmptyArray<T>(array: T[]): array is NonEmptyArray<T>;
89
+ /**
90
+ * Type guard to check if an object has a specific key and narrow its type.
91
+ *
92
+ * @param obj - The object to check
93
+ * @param key - The key to check for
94
+ * @returns True if the object has the key, false otherwise
95
+ */
96
+ declare function objectHasKey<T extends string>(obj: object, key: T): obj is object & {
97
+ [K in T]: unknown;
98
+ };
71
99
 
72
- export { asNonPartial, asPartialUndefinedValues, asType, isObjKey, isSubTypeOf, narrowStringToUnion, typeOnRightExtendsLeftType, typedObjectEntries, typedObjectKeys, unionsAreTheSame };
100
+ export { type NonEmptyArray, asNonPartial, asPartialUndefinedValues, asType, isNonEmptyArray, isObjKey, isSubTypeOf, narrowStringToUnion, objectHasKey, strictTypedObjectEntries, typeOnRightExtendsLeftType, typedObjectEntries, typedObjectKeys, unionsAreTheSame };
@@ -2,21 +2,27 @@ import {
2
2
  asNonPartial,
3
3
  asPartialUndefinedValues,
4
4
  asType,
5
+ isNonEmptyArray,
5
6
  isObjKey,
6
7
  isSubTypeOf,
7
8
  narrowStringToUnion,
9
+ objectHasKey,
10
+ strictTypedObjectEntries,
8
11
  typeOnRightExtendsLeftType,
9
12
  typedObjectEntries,
10
13
  typedObjectKeys,
11
14
  unionsAreTheSame
12
- } from "./chunk-DTE2QMWE.js";
15
+ } from "./chunk-GMJTLFM6.js";
13
16
  export {
14
17
  asNonPartial,
15
18
  asPartialUndefinedValues,
16
19
  asType,
20
+ isNonEmptyArray,
17
21
  isObjKey,
18
22
  isSubTypeOf,
19
23
  narrowStringToUnion,
24
+ objectHasKey,
25
+ strictTypedObjectEntries,
20
26
  typeOnRightExtendsLeftType,
21
27
  typedObjectEntries,
22
28
  typedObjectKeys,
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.41.0",
4
+ "version": "3.43.0",
5
5
  "license": "MIT",
6
6
  "files": [
7
7
  "dist",
@@ -116,6 +116,10 @@
116
116
  "import": "./dist/levenshtein.js",
117
117
  "require": "./dist/levenshtein.cjs"
118
118
  },
119
+ "./matchPath": {
120
+ "import": "./dist/matchPath.js",
121
+ "require": "./dist/matchPath.cjs"
122
+ },
119
123
  "./mathUtils": {
120
124
  "import": "./dist/mathUtils.js",
121
125
  "require": "./dist/mathUtils.cjs"
@@ -132,6 +136,10 @@
132
136
  "import": "./dist/parallelAsyncCalls.js",
133
137
  "require": "./dist/parallelAsyncCalls.cjs"
134
138
  },
139
+ "./partialEqual": {
140
+ "import": "./dist/partialEqual.js",
141
+ "require": "./dist/partialEqual.cjs"
142
+ },
135
143
  "./promiseUtils": {
136
144
  "import": "./dist/promiseUtils.js",
137
145
  "require": "./dist/promiseUtils.cjs"