@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,30 @@
|
|
|
1
|
+
import { Primitive } from "utility-types";
|
|
2
|
+
import { Model } from "../model";
|
|
3
|
+
import { Query, QueryResult } from "./query";
|
|
4
|
+
declare const INPUT: unique symbol;
|
|
5
|
+
interface PartialExecutor {
|
|
6
|
+
[INPUT]: any;
|
|
7
|
+
}
|
|
8
|
+
export interface QueryExecutors<T extends Model> {
|
|
9
|
+
readonly filterFn?: FilterExecutor<T>;
|
|
10
|
+
readonly sorterFn?: SorterExecutor<T>;
|
|
11
|
+
readonly grouperFn?: GrouperExecutor<T>;
|
|
12
|
+
readonly slicerFn?: SliceExecutor<T>;
|
|
13
|
+
}
|
|
14
|
+
export interface QueryExecutor<T extends Model> extends QueryExecutors<T> {
|
|
15
|
+
(items: readonly T[]): QueryResult<T>;
|
|
16
|
+
}
|
|
17
|
+
export declare function queryExecutor<T extends Model>(query: Query<T>, previous?: QueryExecutor<T>): QueryExecutor<T>;
|
|
18
|
+
interface FilterExecutor<T extends Model> extends PartialExecutor {
|
|
19
|
+
(item: T): boolean;
|
|
20
|
+
}
|
|
21
|
+
interface SorterExecutor<T extends Model> extends PartialExecutor {
|
|
22
|
+
(a: T, b: T): number;
|
|
23
|
+
}
|
|
24
|
+
interface GrouperExecutor<T extends Model> extends PartialExecutor {
|
|
25
|
+
(item: T): Primitive;
|
|
26
|
+
}
|
|
27
|
+
interface SliceExecutor<T extends Model> extends PartialExecutor {
|
|
28
|
+
(items: readonly T[]): T[];
|
|
29
|
+
}
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { AsPrimitive, MaxRecursion } from "@ngutil/common";
|
|
2
|
+
import { Model } from "../model";
|
|
3
|
+
export declare const enum FilterOp {
|
|
4
|
+
Eq = "==",
|
|
5
|
+
EqStrict = "===",
|
|
6
|
+
EqInsesitive = "==*",
|
|
7
|
+
Neq = "!=",
|
|
8
|
+
NeqStrict = "!==",
|
|
9
|
+
NeqInsesitive = "!=*",
|
|
10
|
+
Gt = ">",
|
|
11
|
+
GtInsesitive = ">*",
|
|
12
|
+
Gte = ">=",
|
|
13
|
+
GteInsesitive = ">=*",
|
|
14
|
+
Lt = "<",
|
|
15
|
+
LtInsesitive = "<*",
|
|
16
|
+
Lte = "<=",
|
|
17
|
+
LteInsesitive = "<=*",
|
|
18
|
+
Contains = "%",
|
|
19
|
+
ContainsInsesitive = "%*",
|
|
20
|
+
StartsWith = "^",
|
|
21
|
+
StartsWithInsesitive = "^*",
|
|
22
|
+
EndsWith = "$",
|
|
23
|
+
EndsWithInsesitive = "$*",
|
|
24
|
+
Regexp = "~",
|
|
25
|
+
RegexpInsesitive = "~*",
|
|
26
|
+
Or = "|",
|
|
27
|
+
And = "&"
|
|
28
|
+
}
|
|
29
|
+
export declare const OPERATORS: Array<string>;
|
|
30
|
+
export declare function asOperators(value: any): Array<{
|
|
31
|
+
op: FilterOp;
|
|
32
|
+
value: any;
|
|
33
|
+
}>;
|
|
34
|
+
export type Filter<T extends Model> = {
|
|
35
|
+
[key: string]: any;
|
|
36
|
+
};
|
|
37
|
+
export type Operators<T, P extends number[], D extends number = MaxRecursion> = P["length"] extends D ? never : SimpleOperators<T>;
|
|
38
|
+
type SimpleOperators<T> = EqStrict<T> | NeqStrict<T> | Eq<T> | Neq<T> | Gt<T> | Gte<T> | Lt<T> | Lte<T> | Contains<T> | StartsWith<T> | EndsWith<T> | Regexp<T> | T | undefined | null;
|
|
39
|
+
type EqStrict<T> = Operator<T, T, FilterOp.EqStrict, never, null>;
|
|
40
|
+
type NeqStrict<T> = Operator<T, T, FilterOp.NeqStrict, never, null>;
|
|
41
|
+
type Eq<T> = Operator<T, T | AsPrimitive<T>, FilterOp.Eq, FilterOp.EqInsesitive, null>;
|
|
42
|
+
type Neq<T> = Operator<T, T | AsPrimitive<T>, FilterOp.Neq, FilterOp.NeqInsesitive, null>;
|
|
43
|
+
type Gt<T> = Operator<T, T | AsPrimitive<T>, FilterOp.Gt, FilterOp.GtInsesitive>;
|
|
44
|
+
type Gte<T> = Operator<T, T | AsPrimitive<T>, FilterOp.Gte, FilterOp.GteInsesitive>;
|
|
45
|
+
type Lt<T> = Operator<T, T | AsPrimitive<T>, FilterOp.Lt, FilterOp.LtInsesitive>;
|
|
46
|
+
type Lte<T> = Operator<T, T | AsPrimitive<T>, FilterOp.Lte, FilterOp.LteInsesitive>;
|
|
47
|
+
type Contains<T> = Operator<T, string, FilterOp.Contains, FilterOp.ContainsInsesitive>;
|
|
48
|
+
type StartsWith<T> = Operator<T, string, FilterOp.StartsWith, FilterOp.StartsWithInsesitive>;
|
|
49
|
+
type EndsWith<T> = Operator<T, string, FilterOp.EndsWith, FilterOp.EndsWithInsesitive>;
|
|
50
|
+
type Regexp<T> = Operator<T, string, FilterOp.Regexp, FilterOp.RegexpInsesitive, RegExp>;
|
|
51
|
+
type Operator<T, R, OP extends string, OPI extends string = never, ET = never> = (T extends R ? {
|
|
52
|
+
[k in OP]: T | ET | R;
|
|
53
|
+
} : never) | (T extends string ? (OPI extends never ? never : {
|
|
54
|
+
[k in OPI]: string;
|
|
55
|
+
}) : never);
|
|
56
|
+
export type FilterFn<T = any> = (item: T) => boolean;
|
|
57
|
+
/**
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* items.filter(filterBy({id: 42}))
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare function filterBy<T extends Model>(filters: Filter<T>): FilterFn<T>;
|
|
64
|
+
export declare function filterMerge(...filters: any[]): any | undefined;
|
|
65
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Flatten, Primitive } from "@ngutil/common";
|
|
2
|
+
import { Model } from "../model";
|
|
3
|
+
export type GrouperFn<T = any> = (item: any) => Primitive;
|
|
4
|
+
export type Grouper<T extends Model, F = Flatten<T>> = any;
|
|
5
|
+
export declare function groupBy<T extends Model, F = Flatten<T>>(grouper: Grouper<T, F>): GrouperFn<T>;
|
|
6
|
+
export declare function grouperMerge<T extends Model, F = Flatten<T>>(...groupers: Array<Grouper<T, F> | undefined | null>): Grouper<T, F> | undefined;
|
package/query/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { Filter, filterBy, filterMerge, FilterOp } from "./filter";
|
|
2
|
+
export { Grouper, groupBy, grouperMerge } from "./grouper";
|
|
3
|
+
export { Sorter, sortBy, sorterMerge } from "./sorter";
|
|
4
|
+
export { Slimer, slimBy, slimerMerge } from "./slimer";
|
|
5
|
+
export { Slice, sliceMerge, sliceApply, sliceInsert, sliceToPages, sliceClamp, sliceEq } from "./slice";
|
|
6
|
+
export { pathGetterCompile } from "./path";
|
|
7
|
+
export { Query, QueryResult } from "./query";
|
|
8
|
+
export { queryExecutor, QueryExecutor } from "./executor";
|
package/query/path.d.ts
ADDED
package/query/query.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type DeepReadonly } from "@ngutil/common";
|
|
2
|
+
import { type Model } from "../model";
|
|
3
|
+
import { type Filter } from "./filter";
|
|
4
|
+
import { type Grouper } from "./grouper";
|
|
5
|
+
import { type Slice } from "./slice";
|
|
6
|
+
import { type Slimer } from "./slimer";
|
|
7
|
+
import { type Sorter } from "./sorter";
|
|
8
|
+
export interface Query<T extends Model> {
|
|
9
|
+
filter?: DeepReadonly<Filter<T>>;
|
|
10
|
+
sorter?: DeepReadonly<Sorter<T>>;
|
|
11
|
+
slimer?: DeepReadonly<Slimer<T>>;
|
|
12
|
+
grouper?: DeepReadonly<Grouper<T>>;
|
|
13
|
+
slice?: DeepReadonly<Slice>;
|
|
14
|
+
}
|
|
15
|
+
export interface QueryResult<T extends Model> {
|
|
16
|
+
items: readonly T[];
|
|
17
|
+
total?: number;
|
|
18
|
+
groups?: any[];
|
|
19
|
+
}
|
package/query/slice.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ListRange } from "@angular/cdk/collections";
|
|
2
|
+
/**
|
|
3
|
+
* @example
|
|
4
|
+
* ```ts
|
|
5
|
+
* {start: 0, end: 0} // empty range
|
|
6
|
+
* {start: 0, end: 1} // range with one item.eg sliceApply([1, 2, 3], {start:0, end:1}) -> [1]
|
|
7
|
+
* ```
|
|
8
|
+
*/
|
|
9
|
+
export interface Slice extends ListRange {
|
|
10
|
+
/**
|
|
11
|
+
* Start of slice, exact index of item in list
|
|
12
|
+
*/
|
|
13
|
+
readonly start: number;
|
|
14
|
+
/**
|
|
15
|
+
* End of slice, not include end index of item in list
|
|
16
|
+
*/
|
|
17
|
+
readonly end: number;
|
|
18
|
+
readonly pageSize?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function sliceMerge(...slices: Slice[]): Slice | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Apply slice to array, and force the result length to equal with Slice length,
|
|
23
|
+
* so fill array with undefined if not enought elements
|
|
24
|
+
*/
|
|
25
|
+
export declare function sliceApply(slice: Slice, array: readonly any[]): any[];
|
|
26
|
+
/**
|
|
27
|
+
* @returns Page numbers, eg.: `[10, 11, 12, 13, ...]`
|
|
28
|
+
*/
|
|
29
|
+
export declare function sliceToPages(slice: Slice): number[];
|
|
30
|
+
export declare function sliceInsert(slice: Slice, array: readonly any[], newItems: readonly any[]): any[];
|
|
31
|
+
export declare function sliceClamp(slice: Slice, constraint: Slice): Slice;
|
|
32
|
+
export declare function sliceEq(a: Slice, b: Slice): boolean;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Model } from "../model";
|
|
2
|
+
/**
|
|
3
|
+
* @exmaple
|
|
4
|
+
* ```ts
|
|
5
|
+
* [
|
|
6
|
+
* "field_name",
|
|
7
|
+
* {"child_name": ["child_field_name"]},
|
|
8
|
+
* {"children": ["children_field_name", {"$type": Article, slimer: ["id", "title"]}]},
|
|
9
|
+
* {"$type": Employee, slimer: ["name"]}.
|
|
10
|
+
* {"$filter": Filter<T, F>}
|
|
11
|
+
* ]
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export type Slimer<T extends Model> = any;
|
|
15
|
+
export type SlimerFn<T> = (item: T) => T;
|
|
16
|
+
export declare function slimBy<T extends Model>(slimer: Slimer<T>): void;
|
|
17
|
+
export declare function slimerNormalize<T extends Model>(slimer: Slimer<T>): void;
|
|
18
|
+
export declare function slimerMerge<T extends Model>(...slimers: Slimer<T>): void;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Model } from "../model";
|
|
2
|
+
export type SorterFn<T = any> = (a: T, b: T) => number;
|
|
3
|
+
export declare const enum SortDirection {
|
|
4
|
+
Asc = "asc",
|
|
5
|
+
Desc = "desc"
|
|
6
|
+
}
|
|
7
|
+
type Direction = SortDirection.Asc | SortDirection.Desc | "asc" | "desc";
|
|
8
|
+
type DirectionExtra = {
|
|
9
|
+
dir: Direction;
|
|
10
|
+
emptyFirst: boolean;
|
|
11
|
+
};
|
|
12
|
+
export type Sorter<T extends Model> = Array<{
|
|
13
|
+
[key: string]: Direction | DirectionExtra;
|
|
14
|
+
}>;
|
|
15
|
+
type NormalizedEntry = {
|
|
16
|
+
path: string;
|
|
17
|
+
isAsc: boolean;
|
|
18
|
+
emptyFirst: boolean;
|
|
19
|
+
};
|
|
20
|
+
export type SorterNormalized = Array<NormalizedEntry>;
|
|
21
|
+
/**
|
|
22
|
+
* @example
|
|
23
|
+
*```ts
|
|
24
|
+
* items.toSorted(sortBy([{"author.name": "asc"}]))
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function sortBy<T extends Model>(sorters: Sorter<T>): SorterFn<T>;
|
|
28
|
+
/**
|
|
29
|
+
* Normalize sorter definition
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* normalizeSorter([{id: "asc"}]) -> [{path: "id", isAsc: true, emptyFirst: true}]
|
|
34
|
+
* normalizeSorter([{id: {dir: "desc", emptyFirst: false}}]) -> [{path: "id", isAsc: false, emptyFirst: false}]
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function sorterNormalize<T extends Model>(sorters: Sorter<T>): SorterNormalized;
|
|
38
|
+
export declare function compare(a: any, b: any, emptyFirst: boolean): number;
|
|
39
|
+
export declare function sorterMerge<T extends Model>(...sorters: Array<Sorter<T> | undefined | null>): Sorter<T> | undefined;
|
|
40
|
+
export {};
|