@ls-stack/utils 3.25.0 → 3.26.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.
@@ -14,7 +14,7 @@
14
14
  function filterObjectOrArrayKeys(objOrArray, options): Record<string, any> | Record<string, any>[];
15
15
  ```
16
16
 
17
- Defined in: [packages/utils/src/filterObjectOrArrayKeys.ts:38](https://github.com/lucasols/utils/blob/main/packages/utils/src/filterObjectOrArrayKeys.ts#L38)
17
+ Defined in: [packages/utils/src/filterObjectOrArrayKeys.ts:40](https://github.com/lucasols/utils/blob/main/packages/utils/src/filterObjectOrArrayKeys.ts#L40)
18
18
 
19
19
  Filters the keys of an object based on the provided patterns.
20
20
 
@@ -42,6 +42,8 @@ Filtering patterns in `rejectKeys` and `filterKeys`:
42
42
  - `'[*]**nested'` - all `nested` props of all items of the array
43
43
  - `'[0-2]'` - The first three items of the array
44
44
  - `'[4-*]'` - All items of the array from the fourth index to the end
45
+ - Selecting multiple properties:
46
+ - `'prop.test.(prop1|prop2|prop3)'` - The `prop1`, `prop2`, and `prop3` properties of `prop.test` object
45
47
 
46
48
  #### Parameters
47
49
 
@@ -13,75 +13,6 @@ function filterObjectOrArrayKeys(objOrArray, {
13
13
  const rejectPatternsRaw = toArray(rejectKeys);
14
14
  const hasFilters = filterPatternsRaw.length > 0;
15
15
  const hasRejects = rejectPatternsRaw.length > 0;
16
- function parsePattern(pattern) {
17
- const tokens = [];
18
- let i = 0;
19
- const n = pattern.length;
20
- const pushKey = (name) => {
21
- if (name.length === 0) return;
22
- tokens.push({ type: "KEY", name });
23
- };
24
- while (i < n) {
25
- const ch = pattern[i];
26
- if (ch === ".") {
27
- i += 1;
28
- continue;
29
- }
30
- if (ch === "[") {
31
- const end = pattern.indexOf("]", i + 1);
32
- const inside = end === -1 ? pattern.slice(i + 1) : pattern.slice(i + 1, end);
33
- if (inside === "*") {
34
- tokens.push({ type: "INDEX_ANY" });
35
- } else if (inside.includes("-")) {
36
- const parts = inside.split("-");
37
- const startStr = parts[0] ?? "";
38
- const endStr = parts[1] ?? "";
39
- const start = parseInt(startStr, 10);
40
- const endNum = endStr === "*" ? null : parseInt(endStr, 10);
41
- tokens.push({
42
- type: "INDEX_RANGE",
43
- start,
44
- end: endNum === null || Number.isFinite(endNum) ? endNum : null
45
- });
46
- } else if (inside.length > 0) {
47
- const idx = parseInt(inside, 10);
48
- tokens.push({ type: "INDEX", index: idx });
49
- }
50
- i = end === -1 ? n : end + 1;
51
- continue;
52
- }
53
- if (ch === "*") {
54
- if (pattern[i + 1] === "*") {
55
- tokens.push({ type: "WILDCARD_ANY" });
56
- i += 2;
57
- let j2 = i;
58
- while (j2 < n) {
59
- const c = pattern[j2];
60
- if (c === "." || c === "[") break;
61
- j2 += 1;
62
- }
63
- if (j2 > i) {
64
- pushKey(pattern.slice(i, j2));
65
- i = j2;
66
- }
67
- continue;
68
- } else {
69
- tokens.push({ type: "WILDCARD_ONE" });
70
- i += 1;
71
- continue;
72
- }
73
- }
74
- let j = i;
75
- while (j < n) {
76
- const c = pattern[j];
77
- if (c === "." || c === "[") break;
78
- j += 1;
79
- }
80
- pushKey(pattern.slice(i, j));
81
- i = j;
82
- }
83
- return tokens;
84
- }
85
16
  const filterPatterns = filterPatternsRaw.map(parsePattern);
86
17
  const rejectPatterns = rejectPatternsRaw.map(parsePattern);
87
18
  function matchPath(path, pattern) {
@@ -111,6 +42,11 @@ function filterObjectOrArrayKeys(objOrArray, {
111
42
  return rec(pi + 1, pti + 1);
112
43
  if (ct.type === "INDEX") return rec(pi + 1, pti);
113
44
  return false;
45
+ case "MULTI_KEY":
46
+ if (ct.type === "KEY" && pt.names.includes(ct.name))
47
+ return rec(pi + 1, pti + 1);
48
+ if (ct.type === "INDEX") return rec(pi + 1, pti);
49
+ return false;
114
50
  case "INDEX":
115
51
  if (ct.type === "INDEX" && ct.index === pt.index)
116
52
  return rec(pi + 1, pti + 1);
@@ -234,6 +170,87 @@ function filterObjectOrArrayKeys(objOrArray, {
234
170
  if (built === void 0) return Array.isArray(objOrArray) ? [] : {};
235
171
  return built;
236
172
  }
173
+ function parsePattern(pattern) {
174
+ const tokens = [];
175
+ let i = 0;
176
+ const n = pattern.length;
177
+ const pushKey = (name) => {
178
+ if (name.length === 0) return;
179
+ tokens.push({ type: "KEY", name });
180
+ };
181
+ while (i < n) {
182
+ const ch = pattern[i];
183
+ if (ch === ".") {
184
+ i += 1;
185
+ continue;
186
+ }
187
+ if (ch === "[") {
188
+ const end = pattern.indexOf("]", i + 1);
189
+ const inside = end === -1 ? pattern.slice(i + 1) : pattern.slice(i + 1, end);
190
+ if (inside === "*") {
191
+ tokens.push({ type: "INDEX_ANY" });
192
+ } else if (inside.includes("-")) {
193
+ const parts = inside.split("-");
194
+ const startStr = parts[0] ?? "";
195
+ const endStr = parts[1] ?? "";
196
+ const start = parseInt(startStr, 10);
197
+ const endNum = endStr === "*" ? null : parseInt(endStr, 10);
198
+ tokens.push({
199
+ type: "INDEX_RANGE",
200
+ start,
201
+ end: endNum === null || Number.isFinite(endNum) ? endNum : null
202
+ });
203
+ } else if (inside.length > 0) {
204
+ const idx = parseInt(inside, 10);
205
+ tokens.push({ type: "INDEX", index: idx });
206
+ }
207
+ i = end === -1 ? n : end + 1;
208
+ continue;
209
+ }
210
+ if (ch === "(") {
211
+ const end = pattern.indexOf(")", i + 1);
212
+ const inside = end === -1 ? pattern.slice(i + 1) : pattern.slice(i + 1, end);
213
+ if (inside.includes("|") && inside.trim().length > 0) {
214
+ const names = inside.split("|").filter((name) => name.length > 0);
215
+ if (names.length > 0) {
216
+ tokens.push({ type: "MULTI_KEY", names });
217
+ }
218
+ }
219
+ i = end === -1 ? n : end + 1;
220
+ continue;
221
+ }
222
+ if (ch === "*") {
223
+ if (pattern[i + 1] === "*") {
224
+ tokens.push({ type: "WILDCARD_ANY" });
225
+ i += 2;
226
+ let j2 = i;
227
+ while (j2 < n) {
228
+ const c = pattern[j2];
229
+ if (c === "." || c === "[") break;
230
+ j2 += 1;
231
+ }
232
+ if (j2 > i) {
233
+ pushKey(pattern.slice(i, j2));
234
+ i = j2;
235
+ }
236
+ continue;
237
+ } else {
238
+ tokens.push({ type: "WILDCARD_ONE" });
239
+ i += 1;
240
+ continue;
241
+ }
242
+ }
243
+ let j = i;
244
+ while (j < n) {
245
+ const c = pattern[j];
246
+ if (c === "." || c === "[") break;
247
+ j += 1;
248
+ }
249
+ pushKey(pattern.slice(i, j));
250
+ i = j;
251
+ }
252
+ return tokens;
253
+ }
237
254
 
238
255
  export {
239
256
  filterObjectOrArrayKeys
@@ -48,75 +48,6 @@ function filterObjectOrArrayKeys(objOrArray, {
48
48
  const rejectPatternsRaw = toArray(rejectKeys);
49
49
  const hasFilters = filterPatternsRaw.length > 0;
50
50
  const hasRejects = rejectPatternsRaw.length > 0;
51
- function parsePattern(pattern) {
52
- const tokens = [];
53
- let i = 0;
54
- const n = pattern.length;
55
- const pushKey = (name) => {
56
- if (name.length === 0) return;
57
- tokens.push({ type: "KEY", name });
58
- };
59
- while (i < n) {
60
- const ch = pattern[i];
61
- if (ch === ".") {
62
- i += 1;
63
- continue;
64
- }
65
- if (ch === "[") {
66
- const end = pattern.indexOf("]", i + 1);
67
- const inside = end === -1 ? pattern.slice(i + 1) : pattern.slice(i + 1, end);
68
- if (inside === "*") {
69
- tokens.push({ type: "INDEX_ANY" });
70
- } else if (inside.includes("-")) {
71
- const parts = inside.split("-");
72
- const startStr = parts[0] ?? "";
73
- const endStr = parts[1] ?? "";
74
- const start = parseInt(startStr, 10);
75
- const endNum = endStr === "*" ? null : parseInt(endStr, 10);
76
- tokens.push({
77
- type: "INDEX_RANGE",
78
- start,
79
- end: endNum === null || Number.isFinite(endNum) ? endNum : null
80
- });
81
- } else if (inside.length > 0) {
82
- const idx = parseInt(inside, 10);
83
- tokens.push({ type: "INDEX", index: idx });
84
- }
85
- i = end === -1 ? n : end + 1;
86
- continue;
87
- }
88
- if (ch === "*") {
89
- if (pattern[i + 1] === "*") {
90
- tokens.push({ type: "WILDCARD_ANY" });
91
- i += 2;
92
- let j2 = i;
93
- while (j2 < n) {
94
- const c = pattern[j2];
95
- if (c === "." || c === "[") break;
96
- j2 += 1;
97
- }
98
- if (j2 > i) {
99
- pushKey(pattern.slice(i, j2));
100
- i = j2;
101
- }
102
- continue;
103
- } else {
104
- tokens.push({ type: "WILDCARD_ONE" });
105
- i += 1;
106
- continue;
107
- }
108
- }
109
- let j = i;
110
- while (j < n) {
111
- const c = pattern[j];
112
- if (c === "." || c === "[") break;
113
- j += 1;
114
- }
115
- pushKey(pattern.slice(i, j));
116
- i = j;
117
- }
118
- return tokens;
119
- }
120
51
  const filterPatterns = filterPatternsRaw.map(parsePattern);
121
52
  const rejectPatterns = rejectPatternsRaw.map(parsePattern);
122
53
  function matchPath(path, pattern) {
@@ -146,6 +77,11 @@ function filterObjectOrArrayKeys(objOrArray, {
146
77
  return rec(pi + 1, pti + 1);
147
78
  if (ct.type === "INDEX") return rec(pi + 1, pti);
148
79
  return false;
80
+ case "MULTI_KEY":
81
+ if (ct.type === "KEY" && pt.names.includes(ct.name))
82
+ return rec(pi + 1, pti + 1);
83
+ if (ct.type === "INDEX") return rec(pi + 1, pti);
84
+ return false;
149
85
  case "INDEX":
150
86
  if (ct.type === "INDEX" && ct.index === pt.index)
151
87
  return rec(pi + 1, pti + 1);
@@ -269,6 +205,87 @@ function filterObjectOrArrayKeys(objOrArray, {
269
205
  if (built === void 0) return Array.isArray(objOrArray) ? [] : {};
270
206
  return built;
271
207
  }
208
+ function parsePattern(pattern) {
209
+ const tokens = [];
210
+ let i = 0;
211
+ const n = pattern.length;
212
+ const pushKey = (name) => {
213
+ if (name.length === 0) return;
214
+ tokens.push({ type: "KEY", name });
215
+ };
216
+ while (i < n) {
217
+ const ch = pattern[i];
218
+ if (ch === ".") {
219
+ i += 1;
220
+ continue;
221
+ }
222
+ if (ch === "[") {
223
+ const end = pattern.indexOf("]", i + 1);
224
+ const inside = end === -1 ? pattern.slice(i + 1) : pattern.slice(i + 1, end);
225
+ if (inside === "*") {
226
+ tokens.push({ type: "INDEX_ANY" });
227
+ } else if (inside.includes("-")) {
228
+ const parts = inside.split("-");
229
+ const startStr = parts[0] ?? "";
230
+ const endStr = parts[1] ?? "";
231
+ const start = parseInt(startStr, 10);
232
+ const endNum = endStr === "*" ? null : parseInt(endStr, 10);
233
+ tokens.push({
234
+ type: "INDEX_RANGE",
235
+ start,
236
+ end: endNum === null || Number.isFinite(endNum) ? endNum : null
237
+ });
238
+ } else if (inside.length > 0) {
239
+ const idx = parseInt(inside, 10);
240
+ tokens.push({ type: "INDEX", index: idx });
241
+ }
242
+ i = end === -1 ? n : end + 1;
243
+ continue;
244
+ }
245
+ if (ch === "(") {
246
+ const end = pattern.indexOf(")", i + 1);
247
+ const inside = end === -1 ? pattern.slice(i + 1) : pattern.slice(i + 1, end);
248
+ if (inside.includes("|") && inside.trim().length > 0) {
249
+ const names = inside.split("|").filter((name) => name.length > 0);
250
+ if (names.length > 0) {
251
+ tokens.push({ type: "MULTI_KEY", names });
252
+ }
253
+ }
254
+ i = end === -1 ? n : end + 1;
255
+ continue;
256
+ }
257
+ if (ch === "*") {
258
+ if (pattern[i + 1] === "*") {
259
+ tokens.push({ type: "WILDCARD_ANY" });
260
+ i += 2;
261
+ let j2 = i;
262
+ while (j2 < n) {
263
+ const c = pattern[j2];
264
+ if (c === "." || c === "[") break;
265
+ j2 += 1;
266
+ }
267
+ if (j2 > i) {
268
+ pushKey(pattern.slice(i, j2));
269
+ i = j2;
270
+ }
271
+ continue;
272
+ } else {
273
+ tokens.push({ type: "WILDCARD_ONE" });
274
+ i += 1;
275
+ continue;
276
+ }
277
+ }
278
+ let j = i;
279
+ while (j < n) {
280
+ const c = pattern[j];
281
+ if (c === "." || c === "[") break;
282
+ j += 1;
283
+ }
284
+ pushKey(pattern.slice(i, j));
285
+ i = j;
286
+ }
287
+ return tokens;
288
+ }
272
289
  // Annotate the CommonJS export names for ESM import in node:
273
290
  0 && (module.exports = {
274
291
  filterObjectOrArrayKeys
@@ -25,6 +25,8 @@
25
25
  * - `'[*]**nested'` - all `nested` props of all items of the array
26
26
  * - `'[0-2]'` - The first three items of the array
27
27
  * - `'[4-*]'` - All items of the array from the fourth index to the end
28
+ * - Selecting multiple properties:
29
+ * - `'prop.test.(prop1|prop2|prop3)'` - The `prop1`, `prop2`, and `prop3` properties of `prop.test` object
28
30
  *
29
31
  * @param objOrArray - The object or array to filter.
30
32
  * @param options - The options for the filter.
@@ -25,6 +25,8 @@
25
25
  * - `'[*]**nested'` - all `nested` props of all items of the array
26
26
  * - `'[0-2]'` - The first three items of the array
27
27
  * - `'[4-*]'` - All items of the array from the fourth index to the end
28
+ * - Selecting multiple properties:
29
+ * - `'prop.test.(prop1|prop2|prop3)'` - The `prop1`, `prop2`, and `prop3` properties of `prop.test` object
28
30
  *
29
31
  * @param objOrArray - The object or array to filter.
30
32
  * @param options - The options for the filter.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  filterObjectOrArrayKeys
3
- } from "./chunk-XXYTMSFH.js";
3
+ } from "./chunk-FXRZ4RQU.js";
4
4
  import "./chunk-JF2MDHOJ.js";
5
5
  export {
6
6
  filterObjectOrArrayKeys
package/lib/testUtils.cjs CHANGED
@@ -142,75 +142,6 @@ function filterObjectOrArrayKeys(objOrArray, {
142
142
  const rejectPatternsRaw = toArray(rejectKeys);
143
143
  const hasFilters = filterPatternsRaw.length > 0;
144
144
  const hasRejects = rejectPatternsRaw.length > 0;
145
- function parsePattern(pattern) {
146
- const tokens = [];
147
- let i = 0;
148
- const n = pattern.length;
149
- const pushKey = (name) => {
150
- if (name.length === 0) return;
151
- tokens.push({ type: "KEY", name });
152
- };
153
- while (i < n) {
154
- const ch = pattern[i];
155
- if (ch === ".") {
156
- i += 1;
157
- continue;
158
- }
159
- if (ch === "[") {
160
- const end = pattern.indexOf("]", i + 1);
161
- const inside = end === -1 ? pattern.slice(i + 1) : pattern.slice(i + 1, end);
162
- if (inside === "*") {
163
- tokens.push({ type: "INDEX_ANY" });
164
- } else if (inside.includes("-")) {
165
- const parts = inside.split("-");
166
- const startStr = parts[0] ?? "";
167
- const endStr = parts[1] ?? "";
168
- const start = parseInt(startStr, 10);
169
- const endNum = endStr === "*" ? null : parseInt(endStr, 10);
170
- tokens.push({
171
- type: "INDEX_RANGE",
172
- start,
173
- end: endNum === null || Number.isFinite(endNum) ? endNum : null
174
- });
175
- } else if (inside.length > 0) {
176
- const idx = parseInt(inside, 10);
177
- tokens.push({ type: "INDEX", index: idx });
178
- }
179
- i = end === -1 ? n : end + 1;
180
- continue;
181
- }
182
- if (ch === "*") {
183
- if (pattern[i + 1] === "*") {
184
- tokens.push({ type: "WILDCARD_ANY" });
185
- i += 2;
186
- let j2 = i;
187
- while (j2 < n) {
188
- const c = pattern[j2];
189
- if (c === "." || c === "[") break;
190
- j2 += 1;
191
- }
192
- if (j2 > i) {
193
- pushKey(pattern.slice(i, j2));
194
- i = j2;
195
- }
196
- continue;
197
- } else {
198
- tokens.push({ type: "WILDCARD_ONE" });
199
- i += 1;
200
- continue;
201
- }
202
- }
203
- let j = i;
204
- while (j < n) {
205
- const c = pattern[j];
206
- if (c === "." || c === "[") break;
207
- j += 1;
208
- }
209
- pushKey(pattern.slice(i, j));
210
- i = j;
211
- }
212
- return tokens;
213
- }
214
145
  const filterPatterns = filterPatternsRaw.map(parsePattern);
215
146
  const rejectPatterns = rejectPatternsRaw.map(parsePattern);
216
147
  function matchPath(path, pattern) {
@@ -240,6 +171,11 @@ function filterObjectOrArrayKeys(objOrArray, {
240
171
  return rec(pi + 1, pti + 1);
241
172
  if (ct.type === "INDEX") return rec(pi + 1, pti);
242
173
  return false;
174
+ case "MULTI_KEY":
175
+ if (ct.type === "KEY" && pt.names.includes(ct.name))
176
+ return rec(pi + 1, pti + 1);
177
+ if (ct.type === "INDEX") return rec(pi + 1, pti);
178
+ return false;
243
179
  case "INDEX":
244
180
  if (ct.type === "INDEX" && ct.index === pt.index)
245
181
  return rec(pi + 1, pti + 1);
@@ -363,6 +299,87 @@ function filterObjectOrArrayKeys(objOrArray, {
363
299
  if (built === void 0) return Array.isArray(objOrArray) ? [] : {};
364
300
  return built;
365
301
  }
302
+ function parsePattern(pattern) {
303
+ const tokens = [];
304
+ let i = 0;
305
+ const n = pattern.length;
306
+ const pushKey = (name) => {
307
+ if (name.length === 0) return;
308
+ tokens.push({ type: "KEY", name });
309
+ };
310
+ while (i < n) {
311
+ const ch = pattern[i];
312
+ if (ch === ".") {
313
+ i += 1;
314
+ continue;
315
+ }
316
+ if (ch === "[") {
317
+ const end = pattern.indexOf("]", i + 1);
318
+ const inside = end === -1 ? pattern.slice(i + 1) : pattern.slice(i + 1, end);
319
+ if (inside === "*") {
320
+ tokens.push({ type: "INDEX_ANY" });
321
+ } else if (inside.includes("-")) {
322
+ const parts = inside.split("-");
323
+ const startStr = parts[0] ?? "";
324
+ const endStr = parts[1] ?? "";
325
+ const start = parseInt(startStr, 10);
326
+ const endNum = endStr === "*" ? null : parseInt(endStr, 10);
327
+ tokens.push({
328
+ type: "INDEX_RANGE",
329
+ start,
330
+ end: endNum === null || Number.isFinite(endNum) ? endNum : null
331
+ });
332
+ } else if (inside.length > 0) {
333
+ const idx = parseInt(inside, 10);
334
+ tokens.push({ type: "INDEX", index: idx });
335
+ }
336
+ i = end === -1 ? n : end + 1;
337
+ continue;
338
+ }
339
+ if (ch === "(") {
340
+ const end = pattern.indexOf(")", i + 1);
341
+ const inside = end === -1 ? pattern.slice(i + 1) : pattern.slice(i + 1, end);
342
+ if (inside.includes("|") && inside.trim().length > 0) {
343
+ const names = inside.split("|").filter((name) => name.length > 0);
344
+ if (names.length > 0) {
345
+ tokens.push({ type: "MULTI_KEY", names });
346
+ }
347
+ }
348
+ i = end === -1 ? n : end + 1;
349
+ continue;
350
+ }
351
+ if (ch === "*") {
352
+ if (pattern[i + 1] === "*") {
353
+ tokens.push({ type: "WILDCARD_ANY" });
354
+ i += 2;
355
+ let j2 = i;
356
+ while (j2 < n) {
357
+ const c = pattern[j2];
358
+ if (c === "." || c === "[") break;
359
+ j2 += 1;
360
+ }
361
+ if (j2 > i) {
362
+ pushKey(pattern.slice(i, j2));
363
+ i = j2;
364
+ }
365
+ continue;
366
+ } else {
367
+ tokens.push({ type: "WILDCARD_ONE" });
368
+ i += 1;
369
+ continue;
370
+ }
371
+ }
372
+ let j = i;
373
+ while (j < n) {
374
+ const c = pattern[j];
375
+ if (c === "." || c === "[") break;
376
+ j += 1;
377
+ }
378
+ pushKey(pattern.slice(i, j));
379
+ i = j;
380
+ }
381
+ return tokens;
382
+ }
366
383
 
367
384
  // src/mathUtils.ts
368
385
  function clampMin(value, min) {
package/lib/testUtils.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-JQFUKJU5.js";
12
12
  import {
13
13
  filterObjectOrArrayKeys
14
- } from "./chunk-XXYTMSFH.js";
14
+ } from "./chunk-FXRZ4RQU.js";
15
15
  import {
16
16
  defer
17
17
  } from "./chunk-DFXNVEH6.js";
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.25.0",
4
+ "version": "3.26.0",
5
5
  "license": "MIT",
6
6
  "files": [
7
7
  "lib",