@ngutil/data 0.0.10
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/README.md +7 -0
- package/esm2022/index.mjs +3 -0
- package/esm2022/model/index.mjs +2 -0
- package/esm2022/model/meta.mjs +125 -0
- package/esm2022/ngutil-data.mjs +5 -0
- package/esm2022/query/executor.mjs +76 -0
- package/esm2022/query/filter.mjs +288 -0
- package/esm2022/query/grouper.mjs +67 -0
- package/esm2022/query/index.mjs +8 -0
- package/esm2022/query/path.mjs +18 -0
- package/esm2022/query/query.mjs +2 -0
- package/esm2022/query/slice.mjs +61 -0
- package/esm2022/query/slimer.mjs +7 -0
- package/esm2022/query/sorter.mjs +166 -0
- package/fesm2022/ngutil-data.mjs +474 -0
- package/fesm2022/ngutil-data.mjs.map +1 -0
- package/index.d.ts +2 -0
- package/model/index.d.ts +1 -0
- package/model/meta.d.ts +51 -0
- package/package.json +33 -0
- package/query/executor.d.ts +30 -0
- package/query/filter.d.ts +65 -0
- package/query/grouper.d.ts +6 -0
- package/query/index.d.ts +8 -0
- package/query/path.d.ts +2 -0
- package/query/query.d.ts +19 -0
- package/query/slice.d.ts +32 -0
- package/query/slimer.d.ts +18 -0
- package/query/sorter.d.ts +40 -0
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
import { flattenDepth, flattenDeep, isEqual, intersection } from 'lodash';
|
|
2
|
+
import { isPlainObject, deepClone } from '@ngutil/common';
|
|
3
|
+
|
|
4
|
+
function pathGetterCompile(path) {
|
|
5
|
+
if (!path || path.length === 0) {
|
|
6
|
+
throw new Error("Empty path");
|
|
7
|
+
}
|
|
8
|
+
return path.split(".").reduce((parent, part) => makeGetter(part, parent), (obj) => (obj == null ? [] : [obj]));
|
|
9
|
+
}
|
|
10
|
+
const IsNumber = /^\d+$/;
|
|
11
|
+
function makeGetter(part, parent) {
|
|
12
|
+
if (part === "*") {
|
|
13
|
+
return obj => flattenDepth(parent(obj), 1);
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
const key = IsNumber.test(part) ? Number(part) : part;
|
|
17
|
+
return obj => parent(obj).map(v => (v != null ? v[key] : undefined));
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @example
|
|
23
|
+
*```ts
|
|
24
|
+
* items.toSorted(sortBy([{"author.name": "asc"}]))
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
function sortBy(sorters) {
|
|
28
|
+
if (sorters.length === 0) {
|
|
29
|
+
throw new Error("Empty sorter");
|
|
30
|
+
}
|
|
31
|
+
return _sorterCompile(sorters);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Normalize sorter definition
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* normalizeSorter([{id: "asc"}]) -> [{path: "id", isAsc: true, emptyFirst: true}]
|
|
39
|
+
* normalizeSorter([{id: {dir: "desc", emptyFirst: false}}]) -> [{path: "id", isAsc: false, emptyFirst: false}]
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
function sorterNormalize(sorters) {
|
|
43
|
+
return flattenDeep(sorters.map((s) => Object.entries(s).map(([k, v]) => {
|
|
44
|
+
if (typeof v === "string") {
|
|
45
|
+
const isAsc = v.toLowerCase() === "asc";
|
|
46
|
+
return { path: k, isAsc, emptyFirst: isAsc ? false : true };
|
|
47
|
+
}
|
|
48
|
+
else if (isPlainObject(v)) {
|
|
49
|
+
return {
|
|
50
|
+
path: k,
|
|
51
|
+
isAsc: (v.dir || "asc").toLowerCase() === "asc",
|
|
52
|
+
emptyFirst: v.emptyFirst == null ? true : !!v.emptyFirst
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
throw new Error(`Invalid sorter: ${v}`);
|
|
57
|
+
}
|
|
58
|
+
})));
|
|
59
|
+
}
|
|
60
|
+
function _sorterCompile(sorters) {
|
|
61
|
+
if (sorters.length === 0) {
|
|
62
|
+
return (_a, _b) => 0;
|
|
63
|
+
}
|
|
64
|
+
const norm = sorterNormalize(sorters).map(createComparator);
|
|
65
|
+
if (norm.length === 1) {
|
|
66
|
+
return norm[0];
|
|
67
|
+
}
|
|
68
|
+
const initial = norm.pop();
|
|
69
|
+
return norm.reduceRight((next, curr) => (a, b) => {
|
|
70
|
+
const r = curr(a, b);
|
|
71
|
+
return r === 0 ? next(a, b) : r;
|
|
72
|
+
}, initial);
|
|
73
|
+
}
|
|
74
|
+
function createComparator({ path, isAsc, emptyFirst }) {
|
|
75
|
+
const getter = pathGetterCompile(path);
|
|
76
|
+
if (isAsc) {
|
|
77
|
+
return (a, b) => compare(getter(a), getter(b), emptyFirst);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
return (a, b) => compare(getter(a), getter(b), !emptyFirst) * -1;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function compare(a, b, emptyFirst) {
|
|
84
|
+
// console.log("COMPARE", a, b)
|
|
85
|
+
if (a == null && b != null) {
|
|
86
|
+
return emptyFirst === true ? -1 : 1;
|
|
87
|
+
}
|
|
88
|
+
else if (a != null && b == null) {
|
|
89
|
+
return emptyFirst === true ? 1 : -1;
|
|
90
|
+
}
|
|
91
|
+
else if (a == null && b == null) {
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
94
|
+
else if (isEqual(a, b)) {
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
else if (typeof a === "number" && typeof b === "number") {
|
|
98
|
+
return a - b;
|
|
99
|
+
}
|
|
100
|
+
else if (typeof a === "string" && typeof b === "string") {
|
|
101
|
+
const al = a.length;
|
|
102
|
+
const bl = b.length;
|
|
103
|
+
// if both lengths is 0 the code execution not reach that point, because a === b
|
|
104
|
+
if (emptyFirst === true) {
|
|
105
|
+
if (al === 0) {
|
|
106
|
+
return -1;
|
|
107
|
+
}
|
|
108
|
+
else if (bl === 0) {
|
|
109
|
+
return 1;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
if (al === 0) {
|
|
114
|
+
return 1;
|
|
115
|
+
}
|
|
116
|
+
else if (bl === 0) {
|
|
117
|
+
return -1;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return a.localeCompare(b);
|
|
121
|
+
}
|
|
122
|
+
else if (Array.isArray(a) && Array.isArray(b)) {
|
|
123
|
+
const al = a.length;
|
|
124
|
+
const bl = b.length;
|
|
125
|
+
const l = Math.min(al, bl);
|
|
126
|
+
for (let i = 0; i < l; i++) {
|
|
127
|
+
const res = compare(a[i], b[i], emptyFirst);
|
|
128
|
+
if (res !== 0) {
|
|
129
|
+
return res;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (al === bl) {
|
|
133
|
+
return 0;
|
|
134
|
+
}
|
|
135
|
+
if (emptyFirst === true) {
|
|
136
|
+
if (al === 0) {
|
|
137
|
+
return -1;
|
|
138
|
+
}
|
|
139
|
+
else if (bl === 0) {
|
|
140
|
+
return 1;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
if (al === 0) {
|
|
145
|
+
return 1;
|
|
146
|
+
}
|
|
147
|
+
else if (bl === 0) {
|
|
148
|
+
return -1;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return al - bl;
|
|
152
|
+
}
|
|
153
|
+
else if (isPlainObject(a) && isPlainObject(b)) {
|
|
154
|
+
return JSON.stringify(a).localeCompare(JSON.stringify(b));
|
|
155
|
+
}
|
|
156
|
+
return a > b ? -1 : 1;
|
|
157
|
+
}
|
|
158
|
+
function sorterMerge(...sorters) {
|
|
159
|
+
let result;
|
|
160
|
+
for (const sorter of sorters) {
|
|
161
|
+
if (sorter == null) {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (result == null) {
|
|
165
|
+
result = deepClone(sorter);
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
for (const sentry of sorter) {
|
|
169
|
+
for (const [k, v] of Object.entries(sentry)) {
|
|
170
|
+
const existing = result.find((value) => value[k] != null);
|
|
171
|
+
if (existing) {
|
|
172
|
+
;
|
|
173
|
+
existing[k] = deepClone(v);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
result.push({ [k]: deepClone(v) });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const OPERATORS = [
|
|
185
|
+
"==" /* FilterOp.Eq */,
|
|
186
|
+
"===" /* FilterOp.EqStrict */,
|
|
187
|
+
"==*" /* FilterOp.EqInsesitive */,
|
|
188
|
+
"!=" /* FilterOp.Neq */,
|
|
189
|
+
"!==" /* FilterOp.NeqStrict */,
|
|
190
|
+
"!=*" /* FilterOp.NeqInsesitive */,
|
|
191
|
+
">" /* FilterOp.Gt */,
|
|
192
|
+
">*" /* FilterOp.GtInsesitive */,
|
|
193
|
+
">=" /* FilterOp.Gte */,
|
|
194
|
+
">=*" /* FilterOp.GteInsesitive */,
|
|
195
|
+
"<" /* FilterOp.Lt */,
|
|
196
|
+
"<*" /* FilterOp.LtInsesitive */,
|
|
197
|
+
"<=" /* FilterOp.Lte */,
|
|
198
|
+
"<=*" /* FilterOp.LteInsesitive */,
|
|
199
|
+
"%" /* FilterOp.Contains */,
|
|
200
|
+
"%*" /* FilterOp.ContainsInsesitive */,
|
|
201
|
+
"^" /* FilterOp.StartsWith */,
|
|
202
|
+
"^*" /* FilterOp.StartsWithInsesitive */,
|
|
203
|
+
"$" /* FilterOp.EndsWith */,
|
|
204
|
+
"$*" /* FilterOp.EndsWithInsesitive */,
|
|
205
|
+
"~" /* FilterOp.Regexp */,
|
|
206
|
+
"~*" /* FilterOp.RegexpInsesitive */,
|
|
207
|
+
"|" /* FilterOp.Or */,
|
|
208
|
+
"&" /* FilterOp.And */
|
|
209
|
+
];
|
|
210
|
+
function asOperators(value) {
|
|
211
|
+
const ops = intersection(Object.keys(value), OPERATORS);
|
|
212
|
+
if (ops.length > 0) {
|
|
213
|
+
return ops.map(op => {
|
|
214
|
+
return { op, value: value[op] };
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
return [{ op: "==" /* FilterOp.Eq */, value }];
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* @example
|
|
223
|
+
* ```ts
|
|
224
|
+
* items.filter(filterBy({id: 42}))
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
function filterBy(filters) {
|
|
228
|
+
return _filterCompile(filters);
|
|
229
|
+
}
|
|
230
|
+
// TODO: Normalize filter
|
|
231
|
+
// type _Filter = { path: string; op: FilterOp; value: any }
|
|
232
|
+
// type _Or = { "|": Array<_Filter> }
|
|
233
|
+
// type _And = { "&": Array<_Filter> }
|
|
234
|
+
// export type NormalizedFilter = _Or | _And
|
|
235
|
+
// /**
|
|
236
|
+
// * @example
|
|
237
|
+
// * ```ts
|
|
238
|
+
// * normalizeFilter({id: 2, name: {"=*": "AnyName"}}) -> {id: {"==": 2}, name: {"=*": "AnyName"}}}
|
|
239
|
+
// * normalizeFilter({id: {">": 0, "<": 10}}) -> {"&": [{id: {">": 0}}, {id: {"<": 10}}]}
|
|
240
|
+
// * ```
|
|
241
|
+
// */
|
|
242
|
+
// export function normalizeFilter<T extends Model>(filters: Filters<T>): Filters<T> {
|
|
243
|
+
// return _normalizeFilter(filters)
|
|
244
|
+
// }
|
|
245
|
+
// function _normalizeFilter(filters: any, path?: string): any {
|
|
246
|
+
// const result = {} as any
|
|
247
|
+
// for (const [path, v] of Object.entries(filters)) {
|
|
248
|
+
// switch (path) {
|
|
249
|
+
// case FilterOp.And:
|
|
250
|
+
// if (!Array.isArray(v)) {
|
|
251
|
+
// throw new Error("The '&' (AND) operator must have array type")
|
|
252
|
+
// }
|
|
253
|
+
// if (!result[FilterOp.And]) {
|
|
254
|
+
// result[FilterOp.And] = []
|
|
255
|
+
// }
|
|
256
|
+
// result[FilterOp.And] = result[FilterOp.And].concat(v.map(f => _normalizeFilter(f)))
|
|
257
|
+
// break
|
|
258
|
+
// case FilterOp.Or:
|
|
259
|
+
// if (!Array.isArray(v)) {
|
|
260
|
+
// throw new Error("The '|' (OR) operator must have array type")
|
|
261
|
+
// }
|
|
262
|
+
// if (!result[FilterOp.Or]) {
|
|
263
|
+
// result[FilterOp.Or] = []
|
|
264
|
+
// }
|
|
265
|
+
// result[FilterOp.Or] = result[FilterOp.Or].concat(v.map(f => _normalizeFilter(f)))
|
|
266
|
+
// break
|
|
267
|
+
// default:
|
|
268
|
+
// for (const entry of asOperators(v)) {
|
|
269
|
+
// switch (entry.op) {
|
|
270
|
+
// case FilterOp.And:
|
|
271
|
+
// if (!result[FilterOp.And]) {
|
|
272
|
+
// result[FilterOp.And] = []
|
|
273
|
+
// }
|
|
274
|
+
// result[FilterOp.And] = result[FilterOp.And].concat(
|
|
275
|
+
// entry.value.map((v: any) => _normalizeFilter(v, path))
|
|
276
|
+
// )
|
|
277
|
+
// break
|
|
278
|
+
// case FilterOp.Or:
|
|
279
|
+
// if (!result[FilterOp.Or]) {
|
|
280
|
+
// result[FilterOp.Or] = []
|
|
281
|
+
// }
|
|
282
|
+
// result[FilterOp.Or] = result[FilterOp.Or].concat(
|
|
283
|
+
// entry.value.map((v: any) => _normalizeFilter(v, path))
|
|
284
|
+
// )
|
|
285
|
+
// break
|
|
286
|
+
// default:
|
|
287
|
+
// if (!result[FilterOp.And]) {
|
|
288
|
+
// result[FilterOp.And] = []
|
|
289
|
+
// }
|
|
290
|
+
// result[FilterOp.And].push({ path, ...entry })
|
|
291
|
+
// }
|
|
292
|
+
// }
|
|
293
|
+
// }
|
|
294
|
+
// }
|
|
295
|
+
// return result
|
|
296
|
+
// }
|
|
297
|
+
function _filterCompile(filters) {
|
|
298
|
+
let getter;
|
|
299
|
+
const result = [];
|
|
300
|
+
for (const [pth, value] of Object.entries(filters)) {
|
|
301
|
+
switch (pth) {
|
|
302
|
+
case "&" /* FilterOp.And */:
|
|
303
|
+
if (!Array.isArray(value)) {
|
|
304
|
+
throw new Error("Root '&' (AND) operator must have array type");
|
|
305
|
+
}
|
|
306
|
+
result.splice(result.length, 0, ...value.map((_filterCompile)));
|
|
307
|
+
break;
|
|
308
|
+
case "|" /* FilterOp.Or */:
|
|
309
|
+
if (!Array.isArray(value)) {
|
|
310
|
+
throw new Error("Root '|' (OR) operator must have array type");
|
|
311
|
+
}
|
|
312
|
+
result.push(or_(value.map((_filterCompile))));
|
|
313
|
+
break;
|
|
314
|
+
default:
|
|
315
|
+
getter = pathGetterCompile(pth);
|
|
316
|
+
if (isPlainObject(value)) {
|
|
317
|
+
result.push(and_(Object.entries(value).map(([op, opv]) => filterCompileOp(getter, op, opv))));
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
result.push(filterCompileOp(getter, "==" /* FilterOp.Eq */, value));
|
|
321
|
+
}
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return and_(result);
|
|
326
|
+
}
|
|
327
|
+
function filterCompileOp(getter, op, value) {
|
|
328
|
+
let lower;
|
|
329
|
+
let regex;
|
|
330
|
+
switch (op) {
|
|
331
|
+
case "==" /* FilterOp.Eq */:
|
|
332
|
+
// eslint-disable-next-line eqeqeq
|
|
333
|
+
return matcher(getter, v => v == value);
|
|
334
|
+
case "===" /* FilterOp.EqStrict */:
|
|
335
|
+
return matcher(getter, v => v === value);
|
|
336
|
+
case "==*" /* FilterOp.EqInsesitive */:
|
|
337
|
+
lower = String(value).toLocaleLowerCase();
|
|
338
|
+
return matcher(getter, v => String(v).toLocaleLowerCase() === lower);
|
|
339
|
+
case "!=" /* FilterOp.Neq */:
|
|
340
|
+
// eslint-disable-next-line eqeqeq
|
|
341
|
+
return matcher(getter, v => v != value);
|
|
342
|
+
case "!==" /* FilterOp.NeqStrict */:
|
|
343
|
+
return matcher(getter, v => v !== value);
|
|
344
|
+
case "!=*" /* FilterOp.NeqInsesitive */:
|
|
345
|
+
lower = String(value).toLocaleLowerCase();
|
|
346
|
+
return matcher(getter, v => String(v).toLocaleLowerCase() !== lower);
|
|
347
|
+
case ">" /* FilterOp.Gt */:
|
|
348
|
+
return matcher(getter, v => v > value);
|
|
349
|
+
case ">*" /* FilterOp.GtInsesitive */:
|
|
350
|
+
lower = String(value).toLocaleLowerCase();
|
|
351
|
+
return matcher(getter, v => String(v).toLocaleLowerCase() > lower);
|
|
352
|
+
case ">=" /* FilterOp.Gte */:
|
|
353
|
+
return matcher(getter, v => v >= value);
|
|
354
|
+
case ">=*" /* FilterOp.GteInsesitive */:
|
|
355
|
+
lower = String(value).toLocaleLowerCase();
|
|
356
|
+
return matcher(getter, v => String(v).toLocaleLowerCase() >= lower);
|
|
357
|
+
case "<" /* FilterOp.Lt */:
|
|
358
|
+
return matcher(getter, v => v < value);
|
|
359
|
+
case "<*" /* FilterOp.LtInsesitive */:
|
|
360
|
+
lower = String(value).toLocaleLowerCase();
|
|
361
|
+
return matcher(getter, v => String(v).toLocaleLowerCase() < lower);
|
|
362
|
+
case "<=" /* FilterOp.Lte */:
|
|
363
|
+
return matcher(getter, v => v <= value);
|
|
364
|
+
case "<=*" /* FilterOp.LteInsesitive */:
|
|
365
|
+
lower = String(value).toLocaleLowerCase();
|
|
366
|
+
return matcher(getter, v => String(v).toLocaleLowerCase() <= lower);
|
|
367
|
+
case "%" /* FilterOp.Contains */:
|
|
368
|
+
lower = String(value);
|
|
369
|
+
return matcher(getter, v => (Array.isArray(v) ? v.includes(value) : String(v).includes(lower)));
|
|
370
|
+
case "%*" /* FilterOp.ContainsInsesitive */:
|
|
371
|
+
lower = String(value).toLocaleLowerCase();
|
|
372
|
+
return matcher(getter, v => String(v).toLocaleLowerCase().includes(lower));
|
|
373
|
+
case "^" /* FilterOp.StartsWith */:
|
|
374
|
+
lower = String(value);
|
|
375
|
+
return matcher(getter, v => String(v).startsWith(lower));
|
|
376
|
+
case "^*" /* FilterOp.StartsWithInsesitive */:
|
|
377
|
+
lower = String(value).toLocaleLowerCase();
|
|
378
|
+
return matcher(getter, v => String(v).toLocaleLowerCase().startsWith(lower));
|
|
379
|
+
case "$" /* FilterOp.EndsWith */:
|
|
380
|
+
lower = String(value);
|
|
381
|
+
return matcher(getter, v => String(v).endsWith(lower));
|
|
382
|
+
case "$*" /* FilterOp.EndsWithInsesitive */:
|
|
383
|
+
lower = String(value).toLocaleLowerCase();
|
|
384
|
+
return matcher(getter, v => String(v).toLocaleLowerCase().endsWith(lower));
|
|
385
|
+
case "~" /* FilterOp.Regexp */:
|
|
386
|
+
regex = value instanceof RegExp ? value : new RegExp(value, "msv");
|
|
387
|
+
return matcher(getter, v => regex.test(v));
|
|
388
|
+
case "~*" /* FilterOp.RegexpInsesitive */:
|
|
389
|
+
regex = value instanceof RegExp ? value : new RegExp(value, "msvi");
|
|
390
|
+
return matcher(getter, v => regex.test(v));
|
|
391
|
+
case "&" /* FilterOp.And */:
|
|
392
|
+
if (!Array.isArray(value)) {
|
|
393
|
+
throw new Error("Root '&' (AND) operator must have array type");
|
|
394
|
+
}
|
|
395
|
+
return and_(flattenDeep(value.map(v => {
|
|
396
|
+
if (isPlainObject(v)) {
|
|
397
|
+
return Object.entries(v).map(([op, opv]) => filterCompileOp(getter, op, opv));
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
return filterCompileOp(getter, "==" /* FilterOp.Eq */, v);
|
|
401
|
+
}
|
|
402
|
+
})));
|
|
403
|
+
case "|" /* FilterOp.Or */:
|
|
404
|
+
if (!Array.isArray(value)) {
|
|
405
|
+
throw new Error("Root '|' (OR) operator must have array type");
|
|
406
|
+
}
|
|
407
|
+
return or_(flattenDeep(value.map(v => {
|
|
408
|
+
if (isPlainObject(v)) {
|
|
409
|
+
return Object.entries(v).map(([op, opv]) => filterCompileOp(getter, op, opv));
|
|
410
|
+
}
|
|
411
|
+
else {
|
|
412
|
+
return filterCompileOp(getter, "==" /* FilterOp.Eq */, v);
|
|
413
|
+
}
|
|
414
|
+
})));
|
|
415
|
+
}
|
|
416
|
+
throw new Error(`Unexpected operator: ${op}`);
|
|
417
|
+
}
|
|
418
|
+
function matcher(getter, predict) {
|
|
419
|
+
return obj => getter(obj).some(predict);
|
|
420
|
+
}
|
|
421
|
+
function and_(fns) {
|
|
422
|
+
if (fns.length === 0) {
|
|
423
|
+
return _ => true;
|
|
424
|
+
}
|
|
425
|
+
return item => {
|
|
426
|
+
for (const fn of fns) {
|
|
427
|
+
if (!fn(item)) {
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return true;
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
function or_(fns) {
|
|
435
|
+
if (fns.length === 0) {
|
|
436
|
+
return _ => true;
|
|
437
|
+
}
|
|
438
|
+
return item => {
|
|
439
|
+
for (const fn of fns) {
|
|
440
|
+
if (fn(item)) {
|
|
441
|
+
return true;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return false;
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
function filterMerge(...filters) {
|
|
448
|
+
let result = undefined;
|
|
449
|
+
for (const filter of filters) {
|
|
450
|
+
if (filter == null) {
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
if (result == null) {
|
|
454
|
+
result = deepClone(filter);
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
for (const [k, v] of Object.entries(filter)) {
|
|
458
|
+
if (v === undefined) {
|
|
459
|
+
delete result[k];
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
result[k] = deepClone(v);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
return result;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Generated bundle index. Do not edit.
|
|
471
|
+
*/
|
|
472
|
+
|
|
473
|
+
export { filterBy, sortBy };
|
|
474
|
+
//# sourceMappingURL=ngutil-data.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngutil-data.mjs","sources":["../../../../packages/data/src/query/path.ts","../../../../packages/data/src/query/sorter.ts","../../../../packages/data/src/query/filter.ts","../../../../packages/data/src/ngutil-data.ts"],"sourcesContent":["import { flattenDepth } from \"lodash\"\n\ntype GetterFn = (srcs: any[]) => any[]\nexport type PathGetter<T = any, R = any> = (obj: T) => R[]\n\nexport function pathGetterCompile(path: string): PathGetter {\n if (!path || path.length === 0) {\n throw new Error(\"Empty path\")\n }\n\n return path.split(\".\").reduce<GetterFn>(\n (parent, part) => makeGetter(part, parent),\n (obj: any) => (obj == null ? [] : [obj])\n )\n}\n\nconst IsNumber = /^\\d+$/\n\nfunction makeGetter(part: string, parent: GetterFn): GetterFn {\n if (part === \"*\") {\n return obj => flattenDepth(parent(obj), 1)\n } else {\n const key = IsNumber.test(part) ? Number(part) : part\n return obj => parent(obj).map(v => (v != null ? v[key] : undefined))\n }\n}\n","import { flattenDeep, isEqual } from \"lodash\"\n\nimport { deepClone, isPlainObject } from \"@ngutil/common\"\n\nimport { Model } from \"../model\"\nimport { pathGetterCompile } from \"./path\"\n\nexport type SorterFn<T = any> = (a: T, b: T) => number\n\nexport const enum SortDirection {\n Asc = \"asc\",\n Desc = \"desc\"\n}\n\ntype Direction = SortDirection.Asc | SortDirection.Desc | \"asc\" | \"desc\"\ntype DirectionExtra = { dir: Direction; emptyFirst: boolean }\n\ntype _Sorter<F> = { [K in keyof F]: { [key in K]: Direction | DirectionExtra } }[keyof F]\n// TODO: fix recursion\n// export type Sorter<T extends Model> = Array<_Sorter<Flatten<T>>>\nexport type Sorter<T extends Model> = Array<{ [key: string]: Direction | DirectionExtra }>\n\ntype NormalizedEntry = { path: string; isAsc: boolean; emptyFirst: boolean }\nexport type SorterNormalized = Array<NormalizedEntry>\n\n/**\n * @example\n *```ts\n * items.toSorted(sortBy([{\"author.name\": \"asc\"}]))\n * ```\n */\nexport function sortBy<T extends Model>(sorters: Sorter<T>): SorterFn<T> {\n if (sorters.length === 0) {\n throw new Error(\"Empty sorter\")\n }\n return _sorterCompile<T>(sorters) as any\n}\n\n/**\n * Normalize sorter definition\n *\n * @example\n * ```ts\n * normalizeSorter([{id: \"asc\"}]) -> [{path: \"id\", isAsc: true, emptyFirst: true}]\n * normalizeSorter([{id: {dir: \"desc\", emptyFirst: false}}]) -> [{path: \"id\", isAsc: false, emptyFirst: false}]\n * ```\n */\nexport function sorterNormalize<T extends Model>(sorters: Sorter<T>): SorterNormalized {\n return flattenDeep(\n (sorters as any).map((s: any) =>\n Object.entries(s).map(([k, v]) => {\n if (typeof v === \"string\") {\n const isAsc = v.toLowerCase() === \"asc\"\n return { path: k, isAsc, emptyFirst: isAsc ? false : true }\n } else if (isPlainObject(v)) {\n return {\n path: k,\n isAsc: ((v as DirectionExtra).dir || \"asc\").toLowerCase() === \"asc\",\n emptyFirst: (v as DirectionExtra).emptyFirst == null ? true : !!(v as DirectionExtra).emptyFirst\n }\n } else {\n throw new Error(`Invalid sorter: ${v}`)\n }\n })\n )\n )\n}\n\nfunction _sorterCompile<T extends Model>(sorters: Sorter<T>): SorterFn<T> {\n if (sorters.length === 0) {\n return (_a, _b) => 0\n }\n\n const norm = sorterNormalize<T>(sorters).map(createComparator)\n if (norm.length === 1) {\n return norm[0]\n }\n\n const initial = norm.pop()!\n return norm.reduceRight<SorterFn<T>>(\n (next, curr) => (a, b) => {\n const r = curr(a, b)\n return r === 0 ? next(a, b) : r\n },\n initial\n )\n}\n\nfunction createComparator({ path, isAsc, emptyFirst }: NormalizedEntry): SorterFn {\n const getter = pathGetterCompile(path)\n if (isAsc) {\n return (a, b) => compare(getter(a), getter(b), emptyFirst)\n } else {\n return (a, b) => compare(getter(a), getter(b), !emptyFirst) * -1\n }\n}\n\nexport function compare(a: any, b: any, emptyFirst: boolean): number {\n // console.log(\"COMPARE\", a, b)\n if (a == null && b != null) {\n return emptyFirst === true ? -1 : 1\n } else if (a != null && b == null) {\n return emptyFirst === true ? 1 : -1\n } else if (a == null && b == null) {\n return 0\n } else if (isEqual(a, b)) {\n return 0\n } else if (typeof a === \"number\" && typeof b === \"number\") {\n return a - b\n } else if (typeof a === \"string\" && typeof b === \"string\") {\n const al = a.length\n const bl = b.length\n // if both lengths is 0 the code execution not reach that point, because a === b\n if (emptyFirst === true) {\n if (al === 0) {\n return -1\n } else if (bl === 0) {\n return 1\n }\n } else {\n if (al === 0) {\n return 1\n } else if (bl === 0) {\n return -1\n }\n }\n return a.localeCompare(b)\n } else if (Array.isArray(a) && Array.isArray(b)) {\n const al = a.length\n const bl = b.length\n const l = Math.min(al, bl)\n\n for (let i = 0; i < l; i++) {\n const res = compare(a[i], b[i], emptyFirst)\n if (res !== 0) {\n return res\n }\n }\n\n if (al === bl) {\n return 0\n }\n\n if (emptyFirst === true) {\n if (al === 0) {\n return -1\n } else if (bl === 0) {\n return 1\n }\n } else {\n if (al === 0) {\n return 1\n } else if (bl === 0) {\n return -1\n }\n }\n\n return al - bl\n } else if (isPlainObject(a) && isPlainObject(b)) {\n return JSON.stringify(a).localeCompare(JSON.stringify(b))\n }\n\n return a > b ? -1 : 1\n}\n\nexport function sorterMerge<T extends Model>(...sorters: Array<Sorter<T> | undefined | null>): Sorter<T> | undefined {\n let result: Sorter<T> | undefined\n\n for (const sorter of sorters) {\n if (sorter == null) {\n continue\n }\n if (result == null) {\n result = deepClone(sorter)\n continue\n }\n\n for (const sentry of sorter) {\n for (const [k, v] of Object.entries(sentry)) {\n const existing = (result as any).find((value: any) => value[k] != null)\n if (existing) {\n ;(existing as any)[k] = deepClone(v)\n } else {\n result.push({ [k]: deepClone(v) } as any)\n }\n }\n }\n }\n\n return result\n}\n","import { flattenDeep, intersection } from \"lodash\"\n\nimport { AsPrimitive, deepClone, isPlainObject, MaxRecursion } from \"@ngutil/common\"\n\nimport { Model } from \"../model\"\nimport { PathGetter, pathGetterCompile } from \"./path\"\n\nexport const enum FilterOp {\n Eq = \"==\",\n EqStrict = \"===\",\n EqInsesitive = \"==*\",\n Neq = \"!=\",\n NeqStrict = \"!==\",\n NeqInsesitive = \"!=*\",\n Gt = \">\",\n GtInsesitive = \">*\",\n Gte = \">=\",\n GteInsesitive = \">=*\",\n Lt = \"<\",\n LtInsesitive = \"<*\",\n Lte = \"<=\",\n LteInsesitive = \"<=*\",\n Contains = \"%\",\n ContainsInsesitive = \"%*\",\n StartsWith = \"^\",\n StartsWithInsesitive = \"^*\",\n EndsWith = \"$\",\n EndsWithInsesitive = \"$*\",\n Regexp = \"~\",\n RegexpInsesitive = \"~*\",\n Or = \"|\",\n And = \"&\"\n}\n\nexport const OPERATORS: Array<string> = [\n FilterOp.Eq,\n FilterOp.EqStrict,\n FilterOp.EqInsesitive,\n FilterOp.Neq,\n FilterOp.NeqStrict,\n FilterOp.NeqInsesitive,\n FilterOp.Gt,\n FilterOp.GtInsesitive,\n FilterOp.Gte,\n FilterOp.GteInsesitive,\n FilterOp.Lt,\n FilterOp.LtInsesitive,\n FilterOp.Lte,\n FilterOp.LteInsesitive,\n FilterOp.Contains,\n FilterOp.ContainsInsesitive,\n FilterOp.StartsWith,\n FilterOp.StartsWithInsesitive,\n FilterOp.EndsWith,\n FilterOp.EndsWithInsesitive,\n FilterOp.Regexp,\n FilterOp.RegexpInsesitive,\n FilterOp.Or,\n FilterOp.And\n]\n\nexport function asOperators(value: any): Array<{ op: FilterOp; value: any }> {\n const ops = intersection(Object.keys(value), OPERATORS) as FilterOp[]\n if (ops.length > 0) {\n return ops.map(op => {\n return { op, value: value[op] }\n })\n } else {\n return [{ op: FilterOp.Eq, value }]\n }\n}\n\n// export type Filter<T extends Model> = _Filter<Flatten<T>, [], MaxRecursion>\n// TODO: fix recursion\nexport type Filter<T extends Model> = { [key: string]: any }\n\ntype _Filter<F, P extends number[], D extends number> = P[\"length\"] extends D ? never : _ObjectFilter<F, P, D>\n\ntype _ObjectFilter<F, P extends number[], D extends number> = P[\"length\"] extends D\n ? never\n : { [K in keyof F]?: Operators<F[K], P, D> }\n\ntype RootOr<F, P extends number[], D extends number> = P[\"length\"] extends D\n ? never\n : { [FilterOp.Or]: Array<_Filter<F, [...P, 0], D>> | undefined }\n\ntype RootAnd<F, P extends number[], D extends number> = P[\"length\"] extends D\n ? never\n : { [FilterOp.And]: Array<_Filter<F, [...P, 0], D>> | undefined }\n\nexport type Operators<T, P extends number[], D extends number = MaxRecursion> = P[\"length\"] extends D\n ? never\n : SimpleOperators<T>\n\ntype LocalOr<T, P extends number[], D extends number> = P[\"length\"] extends D\n ? never\n : { [FilterOp.Or]: Array<Operators<T, [...P, 0], D>> | undefined }\n\ntype LocalAnd<T, P extends number[], D extends number> = P[\"length\"] extends D\n ? never\n : { [FilterOp.And]: Array<Operators<T, [...P, 0], D>> | undefined }\n\ntype SimpleOperators<T> =\n | EqStrict<T>\n | NeqStrict<T>\n | Eq<T>\n | Neq<T>\n | Gt<T>\n | Gte<T>\n | Lt<T>\n | Lte<T>\n | Contains<T>\n | StartsWith<T>\n | EndsWith<T>\n | Regexp<T>\n | T\n | undefined\n | null\n\ntype EqStrict<T> = Operator<T, T, FilterOp.EqStrict, never, null>\ntype NeqStrict<T> = Operator<T, T, FilterOp.NeqStrict, never, null>\ntype Eq<T> = Operator<T, T | AsPrimitive<T>, FilterOp.Eq, FilterOp.EqInsesitive, null>\ntype Neq<T> = Operator<T, T | AsPrimitive<T>, FilterOp.Neq, FilterOp.NeqInsesitive, null>\ntype Gt<T> = Operator<T, T | AsPrimitive<T>, FilterOp.Gt, FilterOp.GtInsesitive>\ntype Gte<T> = Operator<T, T | AsPrimitive<T>, FilterOp.Gte, FilterOp.GteInsesitive>\ntype Lt<T> = Operator<T, T | AsPrimitive<T>, FilterOp.Lt, FilterOp.LtInsesitive>\ntype Lte<T> = Operator<T, T | AsPrimitive<T>, FilterOp.Lte, FilterOp.LteInsesitive>\ntype Contains<T> = Operator<T, string, FilterOp.Contains, FilterOp.ContainsInsesitive>\ntype StartsWith<T> = Operator<T, string, FilterOp.StartsWith, FilterOp.StartsWithInsesitive>\ntype EndsWith<T> = Operator<T, string, FilterOp.EndsWith, FilterOp.EndsWithInsesitive>\ntype Regexp<T> = Operator<T, string, FilterOp.Regexp, FilterOp.RegexpInsesitive, RegExp>\n\ntype Operator<T, R, OP extends string, OPI extends string = never, ET = never> =\n | (T extends R ? { [k in OP]: T | ET | R } : never)\n | (T extends string ? (OPI extends never ? never : { [k in OPI]: string }) : never)\n\nexport type FilterFn<T = any> = (item: T) => boolean\n\n/**\n * @example\n * ```ts\n * items.filter(filterBy({id: 42}))\n * ```\n */\nexport function filterBy<T extends Model>(filters: Filter<T>): FilterFn<T> {\n return _filterCompile<T>(filters)\n}\n\n// TODO: Normalize filter\n// type _Filter = { path: string; op: FilterOp; value: any }\n// type _Or = { \"|\": Array<_Filter> }\n// type _And = { \"&\": Array<_Filter> }\n// export type NormalizedFilter = _Or | _And\n\n// /**\n// * @example\n// * ```ts\n// * normalizeFilter({id: 2, name: {\"=*\": \"AnyName\"}}) -> {id: {\"==\": 2}, name: {\"=*\": \"AnyName\"}}}\n// * normalizeFilter({id: {\">\": 0, \"<\": 10}}) -> {\"&\": [{id: {\">\": 0}}, {id: {\"<\": 10}}]}\n// * ```\n// */\n// export function normalizeFilter<T extends Model>(filters: Filters<T>): Filters<T> {\n// return _normalizeFilter(filters)\n// }\n\n// function _normalizeFilter(filters: any, path?: string): any {\n// const result = {} as any\n\n// for (const [path, v] of Object.entries(filters)) {\n// switch (path) {\n// case FilterOp.And:\n// if (!Array.isArray(v)) {\n// throw new Error(\"The '&' (AND) operator must have array type\")\n// }\n\n// if (!result[FilterOp.And]) {\n// result[FilterOp.And] = []\n// }\n\n// result[FilterOp.And] = result[FilterOp.And].concat(v.map(f => _normalizeFilter(f)))\n// break\n\n// case FilterOp.Or:\n// if (!Array.isArray(v)) {\n// throw new Error(\"The '|' (OR) operator must have array type\")\n// }\n\n// if (!result[FilterOp.Or]) {\n// result[FilterOp.Or] = []\n// }\n\n// result[FilterOp.Or] = result[FilterOp.Or].concat(v.map(f => _normalizeFilter(f)))\n// break\n\n// default:\n// for (const entry of asOperators(v)) {\n// switch (entry.op) {\n// case FilterOp.And:\n// if (!result[FilterOp.And]) {\n// result[FilterOp.And] = []\n// }\n\n// result[FilterOp.And] = result[FilterOp.And].concat(\n// entry.value.map((v: any) => _normalizeFilter(v, path))\n// )\n// break\n\n// case FilterOp.Or:\n// if (!result[FilterOp.Or]) {\n// result[FilterOp.Or] = []\n// }\n\n// result[FilterOp.Or] = result[FilterOp.Or].concat(\n// entry.value.map((v: any) => _normalizeFilter(v, path))\n// )\n// break\n\n// default:\n// if (!result[FilterOp.And]) {\n// result[FilterOp.And] = []\n// }\n\n// result[FilterOp.And].push({ path, ...entry })\n// }\n// }\n// }\n// }\n\n// return result\n// }\n\nfunction _filterCompile<T extends Model>(filters: Filter<T>): FilterFn<T> {\n let getter: PathGetter\n const result: FilterFn<T>[] = []\n for (const [pth, value] of Object.entries(filters)) {\n switch (pth) {\n case FilterOp.And:\n if (!Array.isArray(value)) {\n throw new Error(\"Root '&' (AND) operator must have array type\")\n }\n result.splice(result.length, 0, ...value.map(_filterCompile<T>))\n break\n\n case FilterOp.Or:\n if (!Array.isArray(value)) {\n throw new Error(\"Root '|' (OR) operator must have array type\")\n }\n result.push(or_(value.map(_filterCompile<T>)))\n break\n\n default:\n getter = pathGetterCompile(pth)\n if (isPlainObject(value)) {\n result.push(and_(Object.entries(value).map(([op, opv]) => filterCompileOp(getter, op as any, opv))))\n } else {\n result.push(filterCompileOp(getter, FilterOp.Eq, value))\n }\n\n break\n }\n }\n return and_(result)\n}\n\nfunction filterCompileOp(getter: PathGetter, op: FilterOp, value: any): FilterFn {\n let lower: string\n let regex: RegExp\n switch (op) {\n case FilterOp.Eq:\n // eslint-disable-next-line eqeqeq\n return matcher(getter, v => v == value)\n\n case FilterOp.EqStrict:\n return matcher(getter, v => v === value)\n\n case FilterOp.EqInsesitive:\n lower = String(value).toLocaleLowerCase()\n return matcher(getter, v => String(v).toLocaleLowerCase() === lower)\n\n case FilterOp.Neq:\n // eslint-disable-next-line eqeqeq\n return matcher(getter, v => v != value)\n\n case FilterOp.NeqStrict:\n return matcher(getter, v => v !== value)\n\n case FilterOp.NeqInsesitive:\n lower = String(value).toLocaleLowerCase()\n return matcher(getter, v => String(v).toLocaleLowerCase() !== lower)\n\n case FilterOp.Gt:\n return matcher(getter, v => v > value)\n\n case FilterOp.GtInsesitive:\n lower = String(value).toLocaleLowerCase()\n return matcher(getter, v => String(v).toLocaleLowerCase() > lower)\n\n case FilterOp.Gte:\n return matcher(getter, v => v >= value)\n\n case FilterOp.GteInsesitive:\n lower = String(value).toLocaleLowerCase()\n return matcher(getter, v => String(v).toLocaleLowerCase() >= lower)\n\n case FilterOp.Lt:\n return matcher(getter, v => v < value)\n\n case FilterOp.LtInsesitive:\n lower = String(value).toLocaleLowerCase()\n return matcher(getter, v => String(v).toLocaleLowerCase() < lower)\n\n case FilterOp.Lte:\n return matcher(getter, v => v <= value)\n\n case FilterOp.LteInsesitive:\n lower = String(value).toLocaleLowerCase()\n return matcher(getter, v => String(v).toLocaleLowerCase() <= lower)\n\n case FilterOp.Contains:\n lower = String(value)\n return matcher(getter, v => (Array.isArray(v) ? v.includes(value) : String(v).includes(lower)))\n\n case FilterOp.ContainsInsesitive:\n lower = String(value).toLocaleLowerCase()\n return matcher(getter, v => String(v).toLocaleLowerCase().includes(lower))\n\n case FilterOp.StartsWith:\n lower = String(value)\n return matcher(getter, v => String(v).startsWith(lower))\n\n case FilterOp.StartsWithInsesitive:\n lower = String(value).toLocaleLowerCase()\n return matcher(getter, v => String(v).toLocaleLowerCase().startsWith(lower))\n\n case FilterOp.EndsWith:\n lower = String(value)\n return matcher(getter, v => String(v).endsWith(lower))\n\n case FilterOp.EndsWithInsesitive:\n lower = String(value).toLocaleLowerCase()\n return matcher(getter, v => String(v).toLocaleLowerCase().endsWith(lower))\n\n case FilterOp.Regexp:\n regex = value instanceof RegExp ? value : new RegExp(value, \"msv\")\n return matcher(getter, v => regex.test(v))\n\n case FilterOp.RegexpInsesitive:\n regex = value instanceof RegExp ? value : new RegExp(value, \"msvi\")\n return matcher(getter, v => regex.test(v))\n\n case FilterOp.And:\n if (!Array.isArray(value)) {\n throw new Error(\"Root '&' (AND) operator must have array type\")\n }\n return and_(\n flattenDeep(\n value.map(v => {\n if (isPlainObject(v)) {\n return Object.entries(v).map(([op, opv]) => filterCompileOp(getter, op as any, opv))\n } else {\n return filterCompileOp(getter, FilterOp.Eq, v)\n }\n })\n )\n )\n\n case FilterOp.Or:\n if (!Array.isArray(value)) {\n throw new Error(\"Root '|' (OR) operator must have array type\")\n }\n return or_(\n flattenDeep(\n value.map(v => {\n if (isPlainObject(v)) {\n return Object.entries(v).map(([op, opv]) => filterCompileOp(getter, op as any, opv))\n } else {\n return filterCompileOp(getter, FilterOp.Eq, v)\n }\n })\n )\n )\n }\n\n throw new Error(`Unexpected operator: ${op}`)\n}\n\nfunction matcher(getter: PathGetter, predict: (value: any) => boolean): FilterFn {\n return obj => getter(obj).some(predict)\n}\n\nfunction and_(fns: FilterFn[]): FilterFn {\n if (fns.length === 0) {\n return _ => true\n }\n\n return item => {\n for (const fn of fns) {\n if (!fn(item)) {\n return false\n }\n }\n return true\n }\n}\n\nfunction or_(fns: FilterFn[]): FilterFn {\n if (fns.length === 0) {\n return _ => true\n }\n\n return item => {\n for (const fn of fns) {\n if (fn(item)) {\n return true\n }\n }\n return false\n }\n}\n\nexport function filterMerge(...filters: any[]): any | undefined {\n let result: { [key: string]: any } | undefined = undefined\n\n for (const filter of filters) {\n if (filter == null) {\n continue\n }\n if (result == null) {\n result = deepClone(filter)\n } else {\n for (const [k, v] of Object.entries(filter)) {\n if (v === undefined) {\n delete result[k]\n continue\n }\n\n result[k] = deepClone(v)\n }\n }\n }\n\n return result as any\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/index.d.ts
ADDED
package/model/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Model, ModelRef, ModelRefNorm, ModelMeta, ModelMetaProps, ModelRefFilter, ModelMetaInput, ModelRefByIndex, ModelRefByKey, UnknownMeta } from "./meta";
|
package/model/meta.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { TrackByFunction } from "@angular/core";
|
|
2
|
+
import { Primitive } from "utility-types";
|
|
3
|
+
export type Model = {
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
};
|
|
6
|
+
export type ModelRef = {
|
|
7
|
+
key?: Primitive | Array<Primitive>;
|
|
8
|
+
index?: number;
|
|
9
|
+
};
|
|
10
|
+
export type ModelRefFilter<T> = (item: T, index: number) => boolean;
|
|
11
|
+
export interface ModelMetaProps<T extends Model> {
|
|
12
|
+
readonly keys: readonly string[];
|
|
13
|
+
readonly trackBy?: TrackByFunction<T>;
|
|
14
|
+
}
|
|
15
|
+
export type ModelMetaInput<T extends Model> = ModelMeta<T> | ModelMetaProps<T>;
|
|
16
|
+
export type TrackedModel<T extends Model> = {
|
|
17
|
+
index: number;
|
|
18
|
+
model: T;
|
|
19
|
+
};
|
|
20
|
+
export declare class ModelMeta<T extends Model> implements ModelMetaProps<T> {
|
|
21
|
+
#private;
|
|
22
|
+
static coerce<M extends Model>(value: ModelMetaInput<M>): ModelMeta<M>;
|
|
23
|
+
readonly keys: readonly string[];
|
|
24
|
+
readonly trackBy: TrackByFunction<T>;
|
|
25
|
+
constructor(props: ModelMetaProps<T>);
|
|
26
|
+
isEqual(a: T, b: T): boolean;
|
|
27
|
+
isEqualByTrack(a: TrackedModel<T>, b: TrackedModel<T>): boolean;
|
|
28
|
+
isEqualByKey(a: T, b: T): boolean;
|
|
29
|
+
normalizeRef(ref: ModelRef | ModelRefNorm): ModelRefNorm;
|
|
30
|
+
}
|
|
31
|
+
export declare abstract class ModelRefNorm {
|
|
32
|
+
#private;
|
|
33
|
+
readonly key?: readonly Primitive[];
|
|
34
|
+
readonly index?: number;
|
|
35
|
+
toFilter(): ModelRefFilter<any>;
|
|
36
|
+
protected abstract _asFilter(): ModelRefFilter<any>;
|
|
37
|
+
}
|
|
38
|
+
export declare class ModelRefByKey extends ModelRefNorm {
|
|
39
|
+
#private;
|
|
40
|
+
readonly key: readonly Primitive[];
|
|
41
|
+
constructor(key: readonly Primitive[], keys: readonly string[]);
|
|
42
|
+
protected _asFilter(): ModelRefFilter<any>;
|
|
43
|
+
}
|
|
44
|
+
export declare class ModelRefByIndex extends ModelRefNorm {
|
|
45
|
+
readonly index: number;
|
|
46
|
+
constructor(index: number);
|
|
47
|
+
protected _asFilter(): ModelRefFilter<any>;
|
|
48
|
+
}
|
|
49
|
+
export declare class UnknownMeta<T extends Model> extends ModelMeta<T> {
|
|
50
|
+
constructor();
|
|
51
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ngutil/data",
|
|
3
|
+
"version": "0.0.10",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public",
|
|
6
|
+
"directory": "../../dist/packages/data/"
|
|
7
|
+
},
|
|
8
|
+
"peerDependencies": {
|
|
9
|
+
"@angular/cdk": "^17.3.5",
|
|
10
|
+
"@angular/core": "^17.3.5",
|
|
11
|
+
"lodash": "^4.17.21",
|
|
12
|
+
"utility-types": "^3.11.0",
|
|
13
|
+
"rxjs": "^7.8.1",
|
|
14
|
+
"@ngutil/common": "0.0.10"
|
|
15
|
+
},
|
|
16
|
+
"sideEffects": false,
|
|
17
|
+
"module": "fesm2022/ngutil-data.mjs",
|
|
18
|
+
"typings": "index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
"./package.json": {
|
|
21
|
+
"default": "./package.json"
|
|
22
|
+
},
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./index.d.ts",
|
|
25
|
+
"esm2022": "./esm2022/ngutil-data.mjs",
|
|
26
|
+
"esm": "./esm2022/ngutil-data.mjs",
|
|
27
|
+
"default": "./fesm2022/ngutil-data.mjs"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"tslib": "^2.3.0"
|
|
32
|
+
}
|
|
33
|
+
}
|