|
1 | 1 | export type Primitive = string | number | symbol |
2 | 2 | export type GenericObject = Record<Primitive, unknown> |
3 | 3 |
|
| 4 | +export type NestedPaths<T> = T extends Array<infer U> |
| 5 | + ? `${NestedPaths<U>}` |
| 6 | + : T extends object |
| 7 | + ? { |
| 8 | + [K in keyof T & (string | number)]: K extends string |
| 9 | + ? `${K}` | `${K}.${NestedPaths<T[K]>}` |
| 10 | + : string; |
| 11 | + }[keyof T & (string | number)] |
| 12 | + : string |
| 13 | + |
| 14 | +export type NestedPathsForType<T, P> = T extends Array<infer U> |
| 15 | + ? NestedPathsForType<U, P> |
| 16 | + : T extends object |
| 17 | + ? { |
| 18 | + [K in keyof T & (string | number)]: K extends string |
| 19 | + ? T[K] extends P |
| 20 | + ? `${K}` | `${K}.${NestedPathsForType<T[K], P>}` |
| 21 | + : T[K] extends object |
| 22 | + ? `${K}.${NestedPathsForType<T[K], P>}` |
| 23 | + : string |
| 24 | + : string; |
| 25 | + }[keyof T & (string | number)] |
| 26 | + : string |
| 27 | + |
4 | 28 | export type Operator = 'AND' | 'OR' | (() => 'AND' | 'OR') |
5 | 29 |
|
6 | 30 | export type FilterMatchMode = |
@@ -44,40 +68,44 @@ export type MatchModeCore = ({ |
44 | 68 | params: ObjectMapFilterParams | ((value: any) => ObjectMapFilterParams) |
45 | 69 | }) |
46 | 70 |
|
47 | | -export type QueryFilter = { |
48 | | - key: string |
| 71 | +export type QueryFilter<Paths extends string = string> = { |
| 72 | + key: Paths |
49 | 73 | value: any |
50 | 74 | operator?: Operator |
51 | 75 | } & MatchModeCore |
52 | 76 |
|
53 | | -export interface QueryFilterGroup { |
| 77 | +export interface QueryFilterGroup<Paths extends string = string> { |
54 | 78 | operator: Operator |
55 | | - filters: QueryFilter[] |
| 79 | + filters: QueryFilter<Paths>[] |
56 | 80 | } |
57 | 81 |
|
58 | | -export type FilterOptions = Array<QueryFilterGroup> | Array<QueryFilter> |
| 82 | +export type FilterOptions<Paths extends string = string> = Array<QueryFilterGroup<Paths>> | Array<QueryFilter<Paths>> |
59 | 83 |
|
60 | | -export interface SearchOptions { |
| 84 | +export interface SearchOptions<Paths extends string = string> { |
61 | 85 | value: string |
62 | | - keys: string[] | Array<{ key: string, caseSensitive?: boolean }> |
| 86 | + keys: Paths[] | Array<{ key: Paths, caseSensitive?: boolean }> |
63 | 87 | caseSensitive?: boolean |
64 | 88 | } |
65 | 89 |
|
66 | | -export interface SortOptions { |
67 | | - key: string |
| 90 | +export interface SortOption<Paths extends string = string> { |
| 91 | + key: Paths |
68 | 92 | dir?: 'asc' | 'desc' |
69 | 93 | parser?: 'number' | 'boolean' | 'string' | ((value: any) => string | number | boolean | null | undefined) |
70 | 94 | } |
71 | 95 |
|
72 | | -export interface QueryParams { |
73 | | - sort?: SortOptions | Array<SortOptions> |
74 | | - search?: SearchOptions |
75 | | - filter?: FilterOptions |
| 96 | +export interface QueryParams< |
| 97 | + T extends GenericObject = GenericObject, |
| 98 | + Paths extends NestedPaths<T> = NestedPaths<T>, |
| 99 | + PrimitivePath extends string = NestedPathsForType<T, string | number | null | boolean | undefined>, |
| 100 | +> { |
| 101 | + sort?: SortOption<PrimitivePath> | Array<SortOption<PrimitivePath>> |
| 102 | + search?: SearchOptions<PrimitivePath> |
| 103 | + filter?: FilterOptions<Paths> |
76 | 104 | limit?: number |
77 | 105 | page?: number |
78 | 106 | } |
79 | 107 |
|
80 | | -export type QueryResult<T extends GenericObject, P extends QueryParams> = P extends { limit: number } ? { totalRows: number, totalPages: number, rows: T[], unpaginatedRows: T[] } : { rows: T[] } |
| 108 | +export type QueryResult<T extends GenericObject, P extends QueryParams<T>> = P extends { limit: number } ? { totalRows: number, totalPages: number, rows: T[], unpaginatedRows: T[] } : { rows: T[] } |
81 | 109 |
|
82 | 110 | export interface MatchModeProcessorMap { |
83 | 111 | equals: ({ value, filter }: { value: any, filter: any }) => boolean |
|
0 commit comments