@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.
- package/docs/filterObjectOrArrayKeys.md +3 -1
- package/lib/{chunk-XXYTMSFH.js → chunk-FXRZ4RQU.js} +86 -69
- package/lib/filterObjectOrArrayKeys.cjs +86 -69
- package/lib/filterObjectOrArrayKeys.d.cts +2 -0
- package/lib/filterObjectOrArrayKeys.d.ts +2 -0
- package/lib/filterObjectOrArrayKeys.js +1 -1
- package/lib/testUtils.cjs +86 -69
- package/lib/testUtils.js +1 -1
- package/package.json +1 -1
|
@@ -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:
|
|
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.
|
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