@ls-stack/utils 3.24.1 → 3.25.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/_media/modules.md +1 -0
- package/docs/arrayUtils/-internal-.md +1 -1
- package/docs/arrayUtils/README.md +12 -12
- package/docs/consoleFmt.md +2 -2
- package/docs/exhaustiveMatch/-internal-.md +1 -1
- package/docs/exhaustiveMatch/README.md +1 -1
- package/docs/filterObjectOrArrayKeys.md +80 -0
- package/docs/modules.md +1 -0
- package/docs/objUtils.md +7 -7
- package/docs/parallelAsyncCalls/-internal-.md +3 -3
- package/docs/parallelAsyncCalls/README.md +1 -1
- package/docs/retryOnError/README.md +1 -1
- package/docs/runShellCmd/README.md +9 -9
- package/docs/safeJson.md +2 -2
- package/docs/saferTyping.md +7 -7
- package/docs/stringUtils/README.md +6 -6
- package/docs/testUtils.md +40 -6
- package/docs/time.md +1 -1
- package/docs/tsResult/README.md +17 -11
- package/docs/typingFnUtils/-internal-.md +1 -1
- package/docs/typingFnUtils/README.md +8 -10
- package/lib/arrayUtils.d.cts +6 -1
- package/lib/arrayUtils.d.ts +6 -1
- package/lib/{chunk-JAPKLFIK.js → chunk-QLD7KG5I.js} +34 -20
- package/lib/chunk-XXYTMSFH.js +240 -0
- package/lib/filterObjectOrArrayKeys.cjs +275 -0
- package/lib/filterObjectOrArrayKeys.d.cts +42 -0
- package/lib/filterObjectOrArrayKeys.d.ts +42 -0
- package/lib/filterObjectOrArrayKeys.js +7 -0
- package/lib/objUtils.d.cts +4 -1
- package/lib/objUtils.d.ts +4 -1
- package/lib/parallelAsyncCalls.cjs +4 -1
- package/lib/parallelAsyncCalls.d.cts +4 -1
- package/lib/parallelAsyncCalls.d.ts +4 -1
- package/lib/parallelAsyncCalls.js +4 -1
- package/lib/retryOnError.d.cts +2 -0
- package/lib/retryOnError.d.ts +2 -0
- package/lib/runShellCmd.d.cts +17 -0
- package/lib/runShellCmd.d.ts +17 -0
- package/lib/safeJson.d.cts +8 -2
- package/lib/safeJson.d.ts +8 -2
- package/lib/saferTyping.d.cts +3 -0
- package/lib/saferTyping.d.ts +3 -0
- package/lib/stringUtils.d.cts +1 -0
- package/lib/stringUtils.d.ts +1 -0
- package/lib/testUtils.cjs +273 -144
- package/lib/testUtils.d.cts +40 -12
- package/lib/testUtils.d.ts +40 -12
- package/lib/testUtils.js +10 -125
- package/lib/tsResult.d.cts +31 -7
- package/lib/tsResult.d.ts +31 -7
- package/lib/typingFnUtils.d.cts +20 -6
- package/lib/typingFnUtils.d.ts +20 -6
- package/lib/yamlStringify.cjs +34 -20
- package/lib/yamlStringify.js +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isPlainObject
|
|
3
|
+
} from "./chunk-JF2MDHOJ.js";
|
|
4
|
+
|
|
5
|
+
// src/filterObjectOrArrayKeys.ts
|
|
6
|
+
function filterObjectOrArrayKeys(objOrArray, {
|
|
7
|
+
filterKeys,
|
|
8
|
+
rejectKeys,
|
|
9
|
+
rejectEmptyObjectsInArray = true
|
|
10
|
+
}) {
|
|
11
|
+
const toArray = (v) => v === void 0 ? [] : Array.isArray(v) ? v : [v];
|
|
12
|
+
const filterPatternsRaw = toArray(filterKeys);
|
|
13
|
+
const rejectPatternsRaw = toArray(rejectKeys);
|
|
14
|
+
const hasFilters = filterPatternsRaw.length > 0;
|
|
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
|
+
const filterPatterns = filterPatternsRaw.map(parsePattern);
|
|
86
|
+
const rejectPatterns = rejectPatternsRaw.map(parsePattern);
|
|
87
|
+
function matchPath(path, pattern) {
|
|
88
|
+
function rec(pi, pti) {
|
|
89
|
+
if (pti >= pattern.length) return pi === path.length;
|
|
90
|
+
const pt = pattern[pti];
|
|
91
|
+
if (pt.type === "WILDCARD_ANY") {
|
|
92
|
+
if (rec(pi, pti + 1)) return true;
|
|
93
|
+
if (pi < path.length) return rec(pi + 1, pti);
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
if (pt.type === "WILDCARD_ONE") {
|
|
97
|
+
let j = pi;
|
|
98
|
+
let sawKey = false;
|
|
99
|
+
while (j < path.length) {
|
|
100
|
+
if (path[j].type === "KEY") sawKey = true;
|
|
101
|
+
if (sawKey && rec(j, pti + 1)) return true;
|
|
102
|
+
j += 1;
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
if (pi >= path.length) return false;
|
|
107
|
+
const ct = path[pi];
|
|
108
|
+
switch (pt.type) {
|
|
109
|
+
case "KEY":
|
|
110
|
+
if (ct.type === "KEY" && ct.name === pt.name)
|
|
111
|
+
return rec(pi + 1, pti + 1);
|
|
112
|
+
if (ct.type === "INDEX") return rec(pi + 1, pti);
|
|
113
|
+
return false;
|
|
114
|
+
case "INDEX":
|
|
115
|
+
if (ct.type === "INDEX" && ct.index === pt.index)
|
|
116
|
+
return rec(pi + 1, pti + 1);
|
|
117
|
+
return false;
|
|
118
|
+
case "INDEX_ANY":
|
|
119
|
+
if (ct.type === "INDEX") return rec(pi + 1, pti + 1);
|
|
120
|
+
return false;
|
|
121
|
+
case "INDEX_RANGE":
|
|
122
|
+
if (ct.type === "INDEX") {
|
|
123
|
+
const okLower = ct.index >= pt.start;
|
|
124
|
+
const okUpper = pt.end === null ? true : ct.index <= pt.end;
|
|
125
|
+
if (okLower && okUpper) return rec(pi + 1, pti + 1);
|
|
126
|
+
}
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return rec(0, 0);
|
|
131
|
+
}
|
|
132
|
+
const matchesAnyFilter = (path) => filterPatterns.some((p) => matchPath(path, p));
|
|
133
|
+
const matchesAnyReject = (path) => rejectPatterns.some((p) => matchPath(path, p));
|
|
134
|
+
const build = (value, path, allowedByFilter, stack2, isRoot, parentIsArray) => {
|
|
135
|
+
if (Array.isArray(value)) {
|
|
136
|
+
if (stack2.has(value)) {
|
|
137
|
+
throw new TypeError("Circular references are not supported");
|
|
138
|
+
}
|
|
139
|
+
stack2.add(value);
|
|
140
|
+
const out = [];
|
|
141
|
+
const includeAllChildren = allowedByFilter || !hasFilters;
|
|
142
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
143
|
+
const childPath = path.concat({ type: "INDEX", index });
|
|
144
|
+
if (hasRejects && matchesAnyReject(childPath)) continue;
|
|
145
|
+
const child = value[index];
|
|
146
|
+
const directInclude = hasFilters ? matchesAnyFilter(childPath) : true;
|
|
147
|
+
const childAllowed = includeAllChildren || directInclude;
|
|
148
|
+
if (isPlainObject(child) || Array.isArray(child)) {
|
|
149
|
+
const builtChild = build(
|
|
150
|
+
child,
|
|
151
|
+
childPath,
|
|
152
|
+
childAllowed,
|
|
153
|
+
stack2,
|
|
154
|
+
false,
|
|
155
|
+
true
|
|
156
|
+
);
|
|
157
|
+
if (builtChild !== void 0) {
|
|
158
|
+
out.push(builtChild);
|
|
159
|
+
}
|
|
160
|
+
} else {
|
|
161
|
+
if (childAllowed) {
|
|
162
|
+
out.push(child);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
stack2.delete(value);
|
|
167
|
+
const filteredOut = rejectEmptyObjectsInArray ? out.filter(
|
|
168
|
+
(item) => !(isPlainObject(item) && Object.keys(item).length === 0)
|
|
169
|
+
) : out;
|
|
170
|
+
if (filteredOut.length === 0 && !allowedByFilter && !isRoot)
|
|
171
|
+
return void 0;
|
|
172
|
+
return filteredOut;
|
|
173
|
+
}
|
|
174
|
+
if (isPlainObject(value)) {
|
|
175
|
+
if (stack2.has(value)) {
|
|
176
|
+
throw new TypeError("Circular references are not supported");
|
|
177
|
+
}
|
|
178
|
+
stack2.add(value);
|
|
179
|
+
const result = {};
|
|
180
|
+
const includeAllChildren = allowedByFilter || !hasFilters;
|
|
181
|
+
for (const key of Object.keys(value)) {
|
|
182
|
+
const childPath = path.concat({ type: "KEY", name: key });
|
|
183
|
+
if (hasRejects && matchesAnyReject(childPath)) continue;
|
|
184
|
+
const val = value[key];
|
|
185
|
+
const directInclude = hasFilters ? matchesAnyFilter(childPath) : true;
|
|
186
|
+
const childAllowed = includeAllChildren || directInclude;
|
|
187
|
+
if (isPlainObject(val) || Array.isArray(val)) {
|
|
188
|
+
const builtChild = build(
|
|
189
|
+
val,
|
|
190
|
+
childPath,
|
|
191
|
+
childAllowed,
|
|
192
|
+
stack2,
|
|
193
|
+
false,
|
|
194
|
+
false
|
|
195
|
+
);
|
|
196
|
+
if (builtChild === void 0) {
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
if (Array.isArray(builtChild) && builtChild.length === 0 && !childAllowed) {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
if (isPlainObject(builtChild) && Object.keys(builtChild).length === 0 && !childAllowed) {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
result[key] = builtChild;
|
|
206
|
+
} else {
|
|
207
|
+
if (childAllowed) {
|
|
208
|
+
result[key] = val;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
stack2.delete(value);
|
|
213
|
+
if (Object.keys(result).length === 0 && !allowedByFilter && !isRoot) {
|
|
214
|
+
if (parentIsArray && !rejectEmptyObjectsInArray) {
|
|
215
|
+
return {};
|
|
216
|
+
}
|
|
217
|
+
return void 0;
|
|
218
|
+
}
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
return allowedByFilter || !hasFilters ? value : void 0;
|
|
222
|
+
};
|
|
223
|
+
const startPath = [];
|
|
224
|
+
const initialAllowed = !hasFilters;
|
|
225
|
+
const stack = /* @__PURE__ */ new WeakSet();
|
|
226
|
+
const built = build(
|
|
227
|
+
objOrArray,
|
|
228
|
+
startPath,
|
|
229
|
+
initialAllowed,
|
|
230
|
+
stack,
|
|
231
|
+
true,
|
|
232
|
+
false
|
|
233
|
+
);
|
|
234
|
+
if (built === void 0) return Array.isArray(objOrArray) ? [] : {};
|
|
235
|
+
return built;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export {
|
|
239
|
+
filterObjectOrArrayKeys
|
|
240
|
+
};
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/filterObjectOrArrayKeys.ts
|
|
21
|
+
var filterObjectOrArrayKeys_exports = {};
|
|
22
|
+
__export(filterObjectOrArrayKeys_exports, {
|
|
23
|
+
filterObjectOrArrayKeys: () => filterObjectOrArrayKeys
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(filterObjectOrArrayKeys_exports);
|
|
26
|
+
|
|
27
|
+
// src/typeGuards.ts
|
|
28
|
+
function isPlainObject(value) {
|
|
29
|
+
if (!value || typeof value !== "object") return false;
|
|
30
|
+
const proto = Object.getPrototypeOf(value);
|
|
31
|
+
if (proto === null) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
const Ctor = Object.hasOwnProperty.call(proto, "constructor") && proto.constructor;
|
|
35
|
+
if (Ctor === Object) return true;
|
|
36
|
+
const objectCtorString = Object.prototype.constructor.toString();
|
|
37
|
+
return typeof Ctor == "function" && Function.toString.call(Ctor) === objectCtorString;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/filterObjectOrArrayKeys.ts
|
|
41
|
+
function filterObjectOrArrayKeys(objOrArray, {
|
|
42
|
+
filterKeys,
|
|
43
|
+
rejectKeys,
|
|
44
|
+
rejectEmptyObjectsInArray = true
|
|
45
|
+
}) {
|
|
46
|
+
const toArray = (v) => v === void 0 ? [] : Array.isArray(v) ? v : [v];
|
|
47
|
+
const filterPatternsRaw = toArray(filterKeys);
|
|
48
|
+
const rejectPatternsRaw = toArray(rejectKeys);
|
|
49
|
+
const hasFilters = filterPatternsRaw.length > 0;
|
|
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
|
+
const filterPatterns = filterPatternsRaw.map(parsePattern);
|
|
121
|
+
const rejectPatterns = rejectPatternsRaw.map(parsePattern);
|
|
122
|
+
function matchPath(path, pattern) {
|
|
123
|
+
function rec(pi, pti) {
|
|
124
|
+
if (pti >= pattern.length) return pi === path.length;
|
|
125
|
+
const pt = pattern[pti];
|
|
126
|
+
if (pt.type === "WILDCARD_ANY") {
|
|
127
|
+
if (rec(pi, pti + 1)) return true;
|
|
128
|
+
if (pi < path.length) return rec(pi + 1, pti);
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
if (pt.type === "WILDCARD_ONE") {
|
|
132
|
+
let j = pi;
|
|
133
|
+
let sawKey = false;
|
|
134
|
+
while (j < path.length) {
|
|
135
|
+
if (path[j].type === "KEY") sawKey = true;
|
|
136
|
+
if (sawKey && rec(j, pti + 1)) return true;
|
|
137
|
+
j += 1;
|
|
138
|
+
}
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
if (pi >= path.length) return false;
|
|
142
|
+
const ct = path[pi];
|
|
143
|
+
switch (pt.type) {
|
|
144
|
+
case "KEY":
|
|
145
|
+
if (ct.type === "KEY" && ct.name === pt.name)
|
|
146
|
+
return rec(pi + 1, pti + 1);
|
|
147
|
+
if (ct.type === "INDEX") return rec(pi + 1, pti);
|
|
148
|
+
return false;
|
|
149
|
+
case "INDEX":
|
|
150
|
+
if (ct.type === "INDEX" && ct.index === pt.index)
|
|
151
|
+
return rec(pi + 1, pti + 1);
|
|
152
|
+
return false;
|
|
153
|
+
case "INDEX_ANY":
|
|
154
|
+
if (ct.type === "INDEX") return rec(pi + 1, pti + 1);
|
|
155
|
+
return false;
|
|
156
|
+
case "INDEX_RANGE":
|
|
157
|
+
if (ct.type === "INDEX") {
|
|
158
|
+
const okLower = ct.index >= pt.start;
|
|
159
|
+
const okUpper = pt.end === null ? true : ct.index <= pt.end;
|
|
160
|
+
if (okLower && okUpper) return rec(pi + 1, pti + 1);
|
|
161
|
+
}
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return rec(0, 0);
|
|
166
|
+
}
|
|
167
|
+
const matchesAnyFilter = (path) => filterPatterns.some((p) => matchPath(path, p));
|
|
168
|
+
const matchesAnyReject = (path) => rejectPatterns.some((p) => matchPath(path, p));
|
|
169
|
+
const build = (value, path, allowedByFilter, stack2, isRoot, parentIsArray) => {
|
|
170
|
+
if (Array.isArray(value)) {
|
|
171
|
+
if (stack2.has(value)) {
|
|
172
|
+
throw new TypeError("Circular references are not supported");
|
|
173
|
+
}
|
|
174
|
+
stack2.add(value);
|
|
175
|
+
const out = [];
|
|
176
|
+
const includeAllChildren = allowedByFilter || !hasFilters;
|
|
177
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
178
|
+
const childPath = path.concat({ type: "INDEX", index });
|
|
179
|
+
if (hasRejects && matchesAnyReject(childPath)) continue;
|
|
180
|
+
const child = value[index];
|
|
181
|
+
const directInclude = hasFilters ? matchesAnyFilter(childPath) : true;
|
|
182
|
+
const childAllowed = includeAllChildren || directInclude;
|
|
183
|
+
if (isPlainObject(child) || Array.isArray(child)) {
|
|
184
|
+
const builtChild = build(
|
|
185
|
+
child,
|
|
186
|
+
childPath,
|
|
187
|
+
childAllowed,
|
|
188
|
+
stack2,
|
|
189
|
+
false,
|
|
190
|
+
true
|
|
191
|
+
);
|
|
192
|
+
if (builtChild !== void 0) {
|
|
193
|
+
out.push(builtChild);
|
|
194
|
+
}
|
|
195
|
+
} else {
|
|
196
|
+
if (childAllowed) {
|
|
197
|
+
out.push(child);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
stack2.delete(value);
|
|
202
|
+
const filteredOut = rejectEmptyObjectsInArray ? out.filter(
|
|
203
|
+
(item) => !(isPlainObject(item) && Object.keys(item).length === 0)
|
|
204
|
+
) : out;
|
|
205
|
+
if (filteredOut.length === 0 && !allowedByFilter && !isRoot)
|
|
206
|
+
return void 0;
|
|
207
|
+
return filteredOut;
|
|
208
|
+
}
|
|
209
|
+
if (isPlainObject(value)) {
|
|
210
|
+
if (stack2.has(value)) {
|
|
211
|
+
throw new TypeError("Circular references are not supported");
|
|
212
|
+
}
|
|
213
|
+
stack2.add(value);
|
|
214
|
+
const result = {};
|
|
215
|
+
const includeAllChildren = allowedByFilter || !hasFilters;
|
|
216
|
+
for (const key of Object.keys(value)) {
|
|
217
|
+
const childPath = path.concat({ type: "KEY", name: key });
|
|
218
|
+
if (hasRejects && matchesAnyReject(childPath)) continue;
|
|
219
|
+
const val = value[key];
|
|
220
|
+
const directInclude = hasFilters ? matchesAnyFilter(childPath) : true;
|
|
221
|
+
const childAllowed = includeAllChildren || directInclude;
|
|
222
|
+
if (isPlainObject(val) || Array.isArray(val)) {
|
|
223
|
+
const builtChild = build(
|
|
224
|
+
val,
|
|
225
|
+
childPath,
|
|
226
|
+
childAllowed,
|
|
227
|
+
stack2,
|
|
228
|
+
false,
|
|
229
|
+
false
|
|
230
|
+
);
|
|
231
|
+
if (builtChild === void 0) {
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
if (Array.isArray(builtChild) && builtChild.length === 0 && !childAllowed) {
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
if (isPlainObject(builtChild) && Object.keys(builtChild).length === 0 && !childAllowed) {
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
result[key] = builtChild;
|
|
241
|
+
} else {
|
|
242
|
+
if (childAllowed) {
|
|
243
|
+
result[key] = val;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
stack2.delete(value);
|
|
248
|
+
if (Object.keys(result).length === 0 && !allowedByFilter && !isRoot) {
|
|
249
|
+
if (parentIsArray && !rejectEmptyObjectsInArray) {
|
|
250
|
+
return {};
|
|
251
|
+
}
|
|
252
|
+
return void 0;
|
|
253
|
+
}
|
|
254
|
+
return result;
|
|
255
|
+
}
|
|
256
|
+
return allowedByFilter || !hasFilters ? value : void 0;
|
|
257
|
+
};
|
|
258
|
+
const startPath = [];
|
|
259
|
+
const initialAllowed = !hasFilters;
|
|
260
|
+
const stack = /* @__PURE__ */ new WeakSet();
|
|
261
|
+
const built = build(
|
|
262
|
+
objOrArray,
|
|
263
|
+
startPath,
|
|
264
|
+
initialAllowed,
|
|
265
|
+
stack,
|
|
266
|
+
true,
|
|
267
|
+
false
|
|
268
|
+
);
|
|
269
|
+
if (built === void 0) return Array.isArray(objOrArray) ? [] : {};
|
|
270
|
+
return built;
|
|
271
|
+
}
|
|
272
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
273
|
+
0 && (module.exports = {
|
|
274
|
+
filterObjectOrArrayKeys
|
|
275
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filters the keys of an object based on the provided patterns.
|
|
3
|
+
*
|
|
4
|
+
* Filtering patterns in `rejectKeys` and `filterKeys`:
|
|
5
|
+
* - `'prop'` - Only root-level properties named 'prop'
|
|
6
|
+
* - `'**prop'` - Any property named exactly 'prop' at any level (root or nested)
|
|
7
|
+
* - `'*.prop'` - Any nested property named 'prop' at second level (excludes root-level matches)
|
|
8
|
+
* - `'test.*.prop'` - Any property named 'prop' at second level of 'test'
|
|
9
|
+
* - `'test.*.test.**prop'` - Any property named 'prop' inside of 'test.*.test'
|
|
10
|
+
* - `'prop.nested'` - Exact nested property paths like `obj.prop.nested`
|
|
11
|
+
* - `'prop.**nested'` - All nested properties inside root `prop` with name `nested`
|
|
12
|
+
* - `'prop[0]'` - The first item of the `prop` array
|
|
13
|
+
* - `'prop[*]'` - All items of the `prop` array
|
|
14
|
+
* - `'prop[0].nested'` - `nested` prop of the first item of the `prop` array
|
|
15
|
+
* - `'prop[*].nested'` - `nested` prop of all items of the `prop` array
|
|
16
|
+
* - `'prop[*]**nested'` - all `nested` props of all items of the `prop` array
|
|
17
|
+
* - `'prop[0-2]'` - The first three items of the `prop` array
|
|
18
|
+
* - `'prop[4-*]'` - All items of the `prop` array from the fourth index to the end
|
|
19
|
+
* - `'prop[0-2].nested.**prop'` - Combining multiple nested patterns is supported
|
|
20
|
+
* - Root array:
|
|
21
|
+
* - `'[0]'` - The first item of the root array
|
|
22
|
+
* - `'[*]'` - All items of the array
|
|
23
|
+
* - `'[0].nested'` - `nested` prop of the first item of the array
|
|
24
|
+
* - `'[*].nested'` - `nested` prop of all items of the array
|
|
25
|
+
* - `'[*]**nested'` - all `nested` props of all items of the array
|
|
26
|
+
* - `'[0-2]'` - The first three items of the array
|
|
27
|
+
* - `'[4-*]'` - All items of the array from the fourth index to the end
|
|
28
|
+
*
|
|
29
|
+
* @param objOrArray - The object or array to filter.
|
|
30
|
+
* @param options - The options for the filter.
|
|
31
|
+
* @param options.filterKeys - The keys to filter.
|
|
32
|
+
* @param options.rejectKeys - The keys to reject.
|
|
33
|
+
* @param options.rejectEmptyObjectsInArray - Whether to reject empty objects in arrays (default: true).
|
|
34
|
+
* @returns The filtered object or array.
|
|
35
|
+
*/
|
|
36
|
+
declare function filterObjectOrArrayKeys(objOrArray: Record<string, any> | Record<string, any>[], { filterKeys, rejectKeys, rejectEmptyObjectsInArray, }: {
|
|
37
|
+
filterKeys?: string[] | string;
|
|
38
|
+
rejectKeys?: string[] | string;
|
|
39
|
+
rejectEmptyObjectsInArray?: boolean;
|
|
40
|
+
}): Record<string, any> | Record<string, any>[];
|
|
41
|
+
|
|
42
|
+
export { filterObjectOrArrayKeys };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filters the keys of an object based on the provided patterns.
|
|
3
|
+
*
|
|
4
|
+
* Filtering patterns in `rejectKeys` and `filterKeys`:
|
|
5
|
+
* - `'prop'` - Only root-level properties named 'prop'
|
|
6
|
+
* - `'**prop'` - Any property named exactly 'prop' at any level (root or nested)
|
|
7
|
+
* - `'*.prop'` - Any nested property named 'prop' at second level (excludes root-level matches)
|
|
8
|
+
* - `'test.*.prop'` - Any property named 'prop' at second level of 'test'
|
|
9
|
+
* - `'test.*.test.**prop'` - Any property named 'prop' inside of 'test.*.test'
|
|
10
|
+
* - `'prop.nested'` - Exact nested property paths like `obj.prop.nested`
|
|
11
|
+
* - `'prop.**nested'` - All nested properties inside root `prop` with name `nested`
|
|
12
|
+
* - `'prop[0]'` - The first item of the `prop` array
|
|
13
|
+
* - `'prop[*]'` - All items of the `prop` array
|
|
14
|
+
* - `'prop[0].nested'` - `nested` prop of the first item of the `prop` array
|
|
15
|
+
* - `'prop[*].nested'` - `nested` prop of all items of the `prop` array
|
|
16
|
+
* - `'prop[*]**nested'` - all `nested` props of all items of the `prop` array
|
|
17
|
+
* - `'prop[0-2]'` - The first three items of the `prop` array
|
|
18
|
+
* - `'prop[4-*]'` - All items of the `prop` array from the fourth index to the end
|
|
19
|
+
* - `'prop[0-2].nested.**prop'` - Combining multiple nested patterns is supported
|
|
20
|
+
* - Root array:
|
|
21
|
+
* - `'[0]'` - The first item of the root array
|
|
22
|
+
* - `'[*]'` - All items of the array
|
|
23
|
+
* - `'[0].nested'` - `nested` prop of the first item of the array
|
|
24
|
+
* - `'[*].nested'` - `nested` prop of all items of the array
|
|
25
|
+
* - `'[*]**nested'` - all `nested` props of all items of the array
|
|
26
|
+
* - `'[0-2]'` - The first three items of the array
|
|
27
|
+
* - `'[4-*]'` - All items of the array from the fourth index to the end
|
|
28
|
+
*
|
|
29
|
+
* @param objOrArray - The object or array to filter.
|
|
30
|
+
* @param options - The options for the filter.
|
|
31
|
+
* @param options.filterKeys - The keys to filter.
|
|
32
|
+
* @param options.rejectKeys - The keys to reject.
|
|
33
|
+
* @param options.rejectEmptyObjectsInArray - Whether to reject empty objects in arrays (default: true).
|
|
34
|
+
* @returns The filtered object or array.
|
|
35
|
+
*/
|
|
36
|
+
declare function filterObjectOrArrayKeys(objOrArray: Record<string, any> | Record<string, any>[], { filterKeys, rejectKeys, rejectEmptyObjectsInArray, }: {
|
|
37
|
+
filterKeys?: string[] | string;
|
|
38
|
+
rejectKeys?: string[] | string;
|
|
39
|
+
rejectEmptyObjectsInArray?: boolean;
|
|
40
|
+
}): Record<string, any> | Record<string, any>[];
|
|
41
|
+
|
|
42
|
+
export { filterObjectOrArrayKeys };
|
package/lib/objUtils.d.cts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* @param obj
|
|
3
|
+
* @deprecated use typedObjectEntries from @ls-stack/utils/typingFnUtils instead
|
|
4
|
+
*/
|
|
2
5
|
declare function objectTypedEntries<T extends Record<string, unknown>>(obj: T): [Extract<keyof T, string>, T[keyof T]][];
|
|
3
6
|
declare function pick<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: K[]): Pick<T, K>;
|
|
4
7
|
declare function mapArrayToObject<T, K extends string, O>(array: T[], mapper: (item: T, index: number) => [K, O]): Record<K, O>;
|
package/lib/objUtils.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* @param obj
|
|
3
|
+
* @deprecated use typedObjectEntries from @ls-stack/utils/typingFnUtils instead
|
|
4
|
+
*/
|
|
2
5
|
declare function objectTypedEntries<T extends Record<string, unknown>>(obj: T): [Extract<keyof T, string>, T[keyof T]][];
|
|
3
6
|
declare function pick<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: K[]): Pick<T, K>;
|
|
4
7
|
declare function mapArrayToObject<T, K extends string, O>(array: T[], mapper: (item: T, index: number) => [K, O]): Record<K, O>;
|
|
@@ -55,7 +55,10 @@ var ParallelAsyncResultCalls = class {
|
|
|
55
55
|
);
|
|
56
56
|
return this;
|
|
57
57
|
}
|
|
58
|
-
/**
|
|
58
|
+
/**
|
|
59
|
+
* adds calls return tuples with inferred results
|
|
60
|
+
* @param calls
|
|
61
|
+
*/
|
|
59
62
|
addTuple(...calls) {
|
|
60
63
|
for (const call of calls) {
|
|
61
64
|
this.pendingCalls.push(
|
|
@@ -37,7 +37,10 @@ declare class ParallelAsyncResultCalls<M extends ValidMetadata | undefined = und
|
|
|
37
37
|
metadata: M;
|
|
38
38
|
fn: () => Promise<Result<R>>;
|
|
39
39
|
}): this;
|
|
40
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* adds calls return tuples with inferred results
|
|
42
|
+
* @param calls
|
|
43
|
+
*/
|
|
41
44
|
addTuple<T extends (M extends undefined ? () => Promise<Result<R>> : {
|
|
42
45
|
metadata: M;
|
|
43
46
|
fn: () => Promise<Result<R>>;
|
|
@@ -37,7 +37,10 @@ declare class ParallelAsyncResultCalls<M extends ValidMetadata | undefined = und
|
|
|
37
37
|
metadata: M;
|
|
38
38
|
fn: () => Promise<Result<R>>;
|
|
39
39
|
}): this;
|
|
40
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* adds calls return tuples with inferred results
|
|
42
|
+
* @param calls
|
|
43
|
+
*/
|
|
41
44
|
addTuple<T extends (M extends undefined ? () => Promise<Result<R>> : {
|
|
42
45
|
metadata: M;
|
|
43
46
|
fn: () => Promise<Result<R>>;
|
|
@@ -20,7 +20,10 @@ var ParallelAsyncResultCalls = class {
|
|
|
20
20
|
);
|
|
21
21
|
return this;
|
|
22
22
|
}
|
|
23
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* adds calls return tuples with inferred results
|
|
25
|
+
* @param calls
|
|
26
|
+
*/
|
|
24
27
|
addTuple(...calls) {
|
|
25
28
|
for (const call of calls) {
|
|
26
29
|
this.pendingCalls.push(
|
package/lib/retryOnError.d.cts
CHANGED
|
@@ -18,6 +18,8 @@ type RetryOptions = {
|
|
|
18
18
|
* @param fn - Function to retry that receives context with retry count
|
|
19
19
|
* @param maxRetries - Maximum number of retries
|
|
20
20
|
* @param options - Configuration options
|
|
21
|
+
* @param retry
|
|
22
|
+
* @param originalMaxRetries
|
|
21
23
|
* @returns Promise resolving to the function result or rejecting with the final error
|
|
22
24
|
*
|
|
23
25
|
* @example
|