orange-orm 4.7.8 → 4.7.10-beta.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/dist/index.browser.mjs +8 -8
- package/dist/index.mjs +16 -10
- package/docs/changelog.md +6 -4
- package/package.json +3 -1
- package/src/cyclic.d.ts +132 -0
- package/src/index.d.ts +13 -24
- package/src/map.d.ts +133 -32
- package/src/map2.d.ts +844 -0
- package/src/table/column/newColumn.js +4 -4
- package/src/table/relatedTable/relatedColumn.js +4 -4
- package/src/tedious/wrapQuery.js +8 -2
package/src/map2.d.ts
ADDED
|
@@ -0,0 +1,844 @@
|
|
|
1
|
+
//map2.d.ts
|
|
2
|
+
import type { PGliteOptions } from './pglite.d.ts';
|
|
3
|
+
import type { ConnectionConfiguration } from 'tedious';
|
|
4
|
+
import type { D1Database } from '@cloudflare/workers-types';
|
|
5
|
+
import type { PoolAttributes } from 'oracledb';
|
|
6
|
+
import type { AxiosInterceptorManager, InternalAxiosRequestConfig, AxiosResponse } from 'axios';
|
|
7
|
+
|
|
8
|
+
export type ORMColumnType = 'string' | 'bigint' | 'uuid' | 'date' | 'numeric' | 'boolean' | 'json' | 'binary';
|
|
9
|
+
|
|
10
|
+
// Base column definition with space-prefixed required properties
|
|
11
|
+
export type ORMColumnDefinition = {
|
|
12
|
+
' type': ORMColumnType;
|
|
13
|
+
' notNull'?: boolean;
|
|
14
|
+
' notNullExceptInsert'?: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// JSON column definition with custom TypeScript type
|
|
18
|
+
export type ORMJsonColumnDefinition<T = any> = {
|
|
19
|
+
' type': 'json';
|
|
20
|
+
' tsType': T;
|
|
21
|
+
' notNull'?: boolean;
|
|
22
|
+
' notNullExceptInsert'?: boolean;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type NormalizeColumn<T> =
|
|
26
|
+
T extends ORMColumnType
|
|
27
|
+
? { ' type': T; ' notNull'?: boolean; ' notNullExceptInsert'?: boolean }
|
|
28
|
+
: T extends { ' type': ORMColumnType }
|
|
29
|
+
? { ' notNull'?: boolean; ' notNullExceptInsert'?: boolean } & T
|
|
30
|
+
: T extends { ' type': 'json'; ' tsType': any }
|
|
31
|
+
? { ' notNull'?: boolean; ' notNullExceptInsert'?: boolean } & T
|
|
32
|
+
: never;
|
|
33
|
+
|
|
34
|
+
type IsRequired<CT> = CT extends { ' notNull': true } ? true : false;
|
|
35
|
+
|
|
36
|
+
type IsRequiredInsert<CT> =
|
|
37
|
+
NormalizeColumn<CT>[' notNullExceptInsert'] extends true
|
|
38
|
+
? false // If notNullExceptInsert is true, then it's NOT required for insert
|
|
39
|
+
: NormalizeColumn<CT>[' notNull'] extends true
|
|
40
|
+
? true // If notNull is true (and notNullExceptInsert is not true), then it IS required for insert
|
|
41
|
+
: false; // Otherwise, it's optional
|
|
42
|
+
|
|
43
|
+
type ColumnTypeToTS<CT> =
|
|
44
|
+
NormalizeColumn<CT>[' type'] extends 'numeric' ? number :
|
|
45
|
+
NormalizeColumn<CT>[' type'] extends 'boolean' ? boolean :
|
|
46
|
+
NormalizeColumn<CT>[' type'] extends 'json'
|
|
47
|
+
? CT extends { ' type': 'json'; ' tsType': infer T } ? T : any :
|
|
48
|
+
NormalizeColumn<CT>[' type'] extends 'date' ? (string | Date) :
|
|
49
|
+
string;
|
|
50
|
+
|
|
51
|
+
export type RelationType = 'hasMany' | 'hasOne' | 'references';
|
|
52
|
+
|
|
53
|
+
export type RelationDefinition<Tables extends Record<string, any>> = {
|
|
54
|
+
type: RelationType;
|
|
55
|
+
target: keyof Tables;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export type TableDefinition<Tables extends Record<string, any>> = {
|
|
59
|
+
columns: Record<string, ORMColumnDefinition | ORMJsonColumnDefinition>;
|
|
60
|
+
primaryKey: readonly (keyof any)[];
|
|
61
|
+
relations?: Record<string, RelationDefinition<Tables>>;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export interface RawFilter {
|
|
65
|
+
sql: string | (() => string);
|
|
66
|
+
parameters?: any[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface Filter extends RawFilter {
|
|
70
|
+
and(other: RawFilter | RawFilter[], ...filters: RawFilter[]): Filter;
|
|
71
|
+
or(other: RawFilter | RawFilter[], ...filters: RawFilter[]): Filter;
|
|
72
|
+
not(): Filter;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
type StringOnlyMethods = {
|
|
76
|
+
startsWith(value: string | null | undefined): Filter;
|
|
77
|
+
iStartsWith(value: string | null | undefined): Filter;
|
|
78
|
+
endsWith(value: string | null | undefined): Filter;
|
|
79
|
+
iEndsWith(value: string | null | undefined): Filter;
|
|
80
|
+
contains(value: string | null | undefined): Filter;
|
|
81
|
+
iContains(value: string | null | undefined): Filter;
|
|
82
|
+
iEqual(value: string | null | undefined): Filter;
|
|
83
|
+
ieq(value: string | null | undefined): Filter;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export type ColumnFilterType<Val, ColumnType = any> = {
|
|
87
|
+
equal(value: Val | null | undefined): Filter;
|
|
88
|
+
eq(value: Val | null | undefined): Filter;
|
|
89
|
+
notEqual(value: Val | null | undefined): Filter;
|
|
90
|
+
ne(value: Val | null | undefined): Filter;
|
|
91
|
+
lessThan(value: Val | null | undefined): Filter;
|
|
92
|
+
lt(value: Val | null | undefined): Filter;
|
|
93
|
+
le(value: Val | null | undefined): Filter;
|
|
94
|
+
greaterThan(value: Val | null | undefined): Filter;
|
|
95
|
+
gt(value: Val | null | undefined): Filter;
|
|
96
|
+
greaterThanOrEqual(value: Val | null | undefined): Filter;
|
|
97
|
+
ge(value: Val | null | undefined): Filter;
|
|
98
|
+
in(values: (Val | null | undefined)[]): Filter;
|
|
99
|
+
between(from: Val | null | undefined, to: Val | null | undefined): Filter;
|
|
100
|
+
notIn(values: (Val | null | undefined)[]): Filter;
|
|
101
|
+
// isNull(): Filter;
|
|
102
|
+
// isNotNull(): Filter;
|
|
103
|
+
} & (ColumnType extends 'string' ? StringOnlyMethods : {});
|
|
104
|
+
|
|
105
|
+
export type JsonArray = Array<JsonValue>;
|
|
106
|
+
export type JsonObject = { [key: string]: JsonValue };
|
|
107
|
+
export type JsonValue = string | number | boolean | null | JsonArray | JsonObject;
|
|
108
|
+
|
|
109
|
+
export type ColumnRefs<M extends Record<string, TableDefinition<M>>, K extends keyof M> = {
|
|
110
|
+
[C in keyof M[K]['columns']]: ColumnFilterType<
|
|
111
|
+
ColumnTypeToTS<M[K]['columns'][C]>,
|
|
112
|
+
NormalizeColumn<M[K]['columns'][C]>[' type']
|
|
113
|
+
>;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export type RootTableRefs<M extends Record<string, TableDefinition<M>>, Target extends keyof M> =
|
|
117
|
+
ColumnRefs<M, Target> & RelationRefs<M, Target>;
|
|
118
|
+
|
|
119
|
+
export type RelationTableRefs<M extends Record<string, TableDefinition<M>>, Target extends keyof M> =
|
|
120
|
+
ColumnRefs<M, Target> & RelationRefs<M, Target> & {
|
|
121
|
+
exists(): Filter;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export type HasManyRelationFilter<M extends Record<string, TableDefinition<M>>, Target extends keyof M> = {
|
|
125
|
+
any(predicate: (row: RelationTableRefs<M, Target>) => Filter): Filter;
|
|
126
|
+
all(predicate: (row: RelationTableRefs<M, Target>) => Filter): Filter;
|
|
127
|
+
none(predicate: (row: RelationTableRefs<M, Target>) => Filter): Filter;
|
|
128
|
+
exists(): Filter;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export type FilterableSingleRelation<M extends Record<string, TableDefinition<M>>, Target extends keyof M> =
|
|
132
|
+
RelationTableRefs<M, Target> & {
|
|
133
|
+
(predicate: (row: RelationTableRefs<M, Target>) => Filter): Filter;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export type RelationRefs<M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
137
|
+
M[K] extends { relations: infer R }
|
|
138
|
+
? {
|
|
139
|
+
[RName in keyof R]: R[RName] extends RelationDefinition<M>
|
|
140
|
+
? R[RName]['type'] extends 'hasMany'
|
|
141
|
+
? HasManyRelationFilter<M, R[RName]['target']> & RelationTableRefs<M, R[RName]['target']>
|
|
142
|
+
: R[RName]['type'] extends 'hasOne' | 'references'
|
|
143
|
+
? FilterableSingleRelation<M, R[RName]['target']>
|
|
144
|
+
: never
|
|
145
|
+
: never;
|
|
146
|
+
}
|
|
147
|
+
: {};
|
|
148
|
+
|
|
149
|
+
export type OrderBy<M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
150
|
+
| `${Extract<keyof M[K]['columns'], string>}`
|
|
151
|
+
| `${Extract<keyof M[K]['columns'], string>} asc`
|
|
152
|
+
| `${Extract<keyof M[K]['columns'], string>} desc`
|
|
153
|
+
| Array<
|
|
154
|
+
| `${Extract<keyof M[K]['columns'], string>}`
|
|
155
|
+
| `${Extract<keyof M[K]['columns'], string>} asc`
|
|
156
|
+
| `${Extract<keyof M[K]['columns'], string>} desc`
|
|
157
|
+
>;
|
|
158
|
+
|
|
159
|
+
// Reserved property names that should not conflict with relation selectors
|
|
160
|
+
type ReservedFetchStrategyProps = 'orderBy' | 'where';
|
|
161
|
+
|
|
162
|
+
// Base fetch strategy properties (reserved props)
|
|
163
|
+
type BaseFetchStrategy<M extends Record<string, TableDefinition<M>>, K extends keyof M> = {
|
|
164
|
+
orderBy?: OrderBy<M, K>;
|
|
165
|
+
limit?: number;
|
|
166
|
+
offset?: number;
|
|
167
|
+
where?: WhereFunc<M, K>;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
export type PrimaryKeyObject<M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
171
|
+
M[K]['primaryKey'] extends readonly (infer Keys extends keyof M[K]['columns'])[]
|
|
172
|
+
? { [PK in Keys]: ColumnTypeToTS<M[K]['columns'][PK]> }
|
|
173
|
+
: never;
|
|
174
|
+
|
|
175
|
+
// Column selection properties
|
|
176
|
+
type ColumnSelection<M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
177
|
+
Partial<Record<keyof M[K]['columns'], boolean>>;
|
|
178
|
+
|
|
179
|
+
// Relation selection properties (excluding reserved names)
|
|
180
|
+
type RelationSelection<M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
181
|
+
M[K] extends { relations: infer R }
|
|
182
|
+
? {
|
|
183
|
+
[RName in keyof R as RName extends ReservedFetchStrategyProps ? never : RName]?:
|
|
184
|
+
R[RName] extends { target: infer T }
|
|
185
|
+
? T extends keyof M
|
|
186
|
+
? true | false | FetchStrategy<M, T>
|
|
187
|
+
: never
|
|
188
|
+
: never;
|
|
189
|
+
}
|
|
190
|
+
: {};
|
|
191
|
+
|
|
192
|
+
// Helper type to extract only column filter types (not relation objects)
|
|
193
|
+
type AllColumnFilterTypes<M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
194
|
+
ColumnRefs<M, K>[keyof ColumnRefs<M, K>];
|
|
195
|
+
|
|
196
|
+
// Helper type to get column filter types from related tables
|
|
197
|
+
type RelatedColumnFilterTypes<M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
198
|
+
M[K] extends { relations: infer R }
|
|
199
|
+
? {
|
|
200
|
+
[RName in keyof R]: R[RName] extends { target: infer Target extends keyof M }
|
|
201
|
+
? ColumnRefs<M, Target>[keyof ColumnRefs<M, Target>]
|
|
202
|
+
: never;
|
|
203
|
+
}[keyof R]
|
|
204
|
+
: never;
|
|
205
|
+
|
|
206
|
+
// All valid column filter types (direct columns + related table columns)
|
|
207
|
+
type ValidColumnFilterTypes<M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
208
|
+
AllColumnFilterTypes<M, K> | RelatedColumnFilterTypes<M, K>;
|
|
209
|
+
|
|
210
|
+
// Column selection refs without filter methods - only for getting values/references
|
|
211
|
+
type ColumnSelectionRefs<M extends Record<string, TableDefinition<M>>, K extends keyof M> = {
|
|
212
|
+
// Required columns (notNull = true)
|
|
213
|
+
[C in keyof M[K]['columns'] as IsRequired<M[K]['columns'][C]> extends true ? C : never]: ColumnTypeToTS<M[K]['columns'][C]>;
|
|
214
|
+
} & {
|
|
215
|
+
// Optional columns (nullable)
|
|
216
|
+
[C in keyof M[K]['columns'] as IsRequired<M[K]['columns'][C]> extends true ? never : C]?: ColumnTypeToTS<M[K]['columns'][C]> | null | undefined;
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
// Relation selection refs without filter methods - supports deep nesting
|
|
221
|
+
// In selectors, all relation types just provide access to the target table structure
|
|
222
|
+
// But WITHOUT aggregate functions (only available at root level)
|
|
223
|
+
type RelationSelectionRefs<M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
224
|
+
M[K] extends { relations: infer R }
|
|
225
|
+
? {
|
|
226
|
+
[RName in keyof R]: R[RName] extends RelationDefinition<M>
|
|
227
|
+
? R[RName]['type'] extends 'hasMany' | 'hasOne' | 'references'
|
|
228
|
+
? SelectionRefsWithoutAggregates<M, R[RName]['target']> // Use version without aggregates
|
|
229
|
+
: never
|
|
230
|
+
: never;
|
|
231
|
+
}
|
|
232
|
+
: {};
|
|
233
|
+
|
|
234
|
+
// Selection refs without aggregate functions (for use inside aggregate function selectors)
|
|
235
|
+
type SelectionRefsWithoutAggregates<M extends Record<string, TableDefinition<M>>, Target extends keyof M> =
|
|
236
|
+
ColumnSelectionRefs<M, Target> & RelationSelectionRefs<M, Target>;
|
|
237
|
+
|
|
238
|
+
// Base aggregate function type
|
|
239
|
+
type BaseAggregateFunction = {
|
|
240
|
+
__aggregateFunction: true;
|
|
241
|
+
__functionType?: 'count' | 'sum' | 'avg' | 'max' | 'min';
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
// Standard aggregate function for count, sum, avg
|
|
245
|
+
type AggregateFunction = BaseAggregateFunction & {
|
|
246
|
+
returnType: 'numeric';
|
|
247
|
+
__functionType?: 'count' | 'sum' | 'avg';
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
// Special type for max/min that preserves the column type
|
|
251
|
+
type AggregateMinMaxFunction<T> = BaseAggregateFunction & {
|
|
252
|
+
returnType: T;
|
|
253
|
+
__functionType: 'max' | 'min';
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
// Update AggregateFunctions to include the function type and proper return types
|
|
257
|
+
type AggregateFunctions<M extends Record<string, TableDefinition<M>>, K extends keyof M> = {
|
|
258
|
+
count(selector: (row: SelectionRefsWithoutAggregates<M, K>) => AnyColumnDefinition<M, K>): AggregateFunction & { __functionType: 'count' };
|
|
259
|
+
avg(selector: (row: SelectionRefsWithoutAggregates<M, K>) => NumericColumnDefinition<M, K>): AggregateFunction & { __functionType: 'avg' };
|
|
260
|
+
sum(selector: (row: SelectionRefsWithoutAggregates<M, K>) => NumericColumnDefinition<M, K>): AggregateFunction & { __functionType: 'sum' };
|
|
261
|
+
max<T extends AnyColumnDefinition<M, K>>(selector: (row: SelectionRefsWithoutAggregates<M, K>) => T): AggregateMinMaxFunction<T> & { __functionType: 'max' };
|
|
262
|
+
min<T extends AnyColumnDefinition<M, K>>(selector: (row: SelectionRefsWithoutAggregates<M, K>) => T): AggregateMinMaxFunction<T> & { __functionType: 'min' };
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
// NEW ── any column, any table (local or related)
|
|
266
|
+
type AnyColumnDefinition<
|
|
267
|
+
M extends Record<string, TableDefinition<M>>,
|
|
268
|
+
K extends keyof M
|
|
269
|
+
> =
|
|
270
|
+
// columns on the current table
|
|
271
|
+
M[K]['columns'][keyof M[K]['columns']] |
|
|
272
|
+
// columns on related tables
|
|
273
|
+
(M[K] extends { relations: infer R }
|
|
274
|
+
? {
|
|
275
|
+
[RName in keyof R]: R[RName] extends { target: infer Target extends keyof M }
|
|
276
|
+
? M[Target]['columns'][keyof M[Target]['columns']]
|
|
277
|
+
: never;
|
|
278
|
+
}[keyof R]
|
|
279
|
+
: never);
|
|
280
|
+
|
|
281
|
+
// CHANGE from NumericColumnValue to NumericColumnDefinition:
|
|
282
|
+
type NumericColumnDefinition<M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
283
|
+
// Direct numeric columns
|
|
284
|
+
{
|
|
285
|
+
[C in keyof M[K]['columns']]: NormalizeColumn<M[K]['columns'][C]>[' type'] extends 'numeric'
|
|
286
|
+
? M[K]['columns'][C] // Return column definition, not TS type
|
|
287
|
+
: never;
|
|
288
|
+
}[keyof M[K]['columns']] |
|
|
289
|
+
// Numeric columns from related tables
|
|
290
|
+
(M[K] extends { relations: infer R }
|
|
291
|
+
? {
|
|
292
|
+
[RName in keyof R]: R[RName] extends { target: infer Target extends keyof M }
|
|
293
|
+
? {
|
|
294
|
+
[C in keyof M[Target]['columns']]: NormalizeColumn<M[Target]['columns'][C]>[' type'] extends 'numeric'
|
|
295
|
+
? M[Target]['columns'][C] // Return column definition, not TS type
|
|
296
|
+
: never;
|
|
297
|
+
}[keyof M[Target]['columns']]
|
|
298
|
+
: never;
|
|
299
|
+
}[keyof R]
|
|
300
|
+
: never);
|
|
301
|
+
|
|
302
|
+
// Root selection refs for custom selectors (no filter methods) - supports deep nesting + aggregates
|
|
303
|
+
type RootSelectionRefs<M extends Record<string, TableDefinition<M>>, Target extends keyof M> =
|
|
304
|
+
ColumnSelectionRefs<M, Target> & RelationSelectionRefs<M, Target> & AggregateFunctions<M, Target>;
|
|
305
|
+
|
|
306
|
+
// Valid return types for custom selectors - now supports deep paths through any relation type
|
|
307
|
+
type ValidSelectorReturnTypes<M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
308
|
+
// Column definitions from any table
|
|
309
|
+
(M extends Record<string, TableDefinition<M>>
|
|
310
|
+
? {
|
|
311
|
+
[TableKey in keyof M]: M[TableKey]['columns'][keyof M[TableKey]['columns']]
|
|
312
|
+
}[keyof M]
|
|
313
|
+
: never) |
|
|
314
|
+
// Base aggregate function marker (covers both regular and min/max)
|
|
315
|
+
BaseAggregateFunction;
|
|
316
|
+
|
|
317
|
+
// ADD helper to convert column definition to TypeScript type:
|
|
318
|
+
type ColumnDefinitionToTS<CD> = CD extends ORMColumnDefinition | ORMJsonColumnDefinition
|
|
319
|
+
? ColumnTypeToTS<CD>
|
|
320
|
+
: never;
|
|
321
|
+
|
|
322
|
+
// Custom selector functions - allows arbitrary property names with selector functions
|
|
323
|
+
// Uses RootSelectionRefs which supports deep nesting without filter methods
|
|
324
|
+
type CustomSelectors<M extends Record<string, TableDefinition<M>>, K extends keyof M> = {
|
|
325
|
+
[key: string]: (row: RootSelectionRefs<M, K>) => ValidSelectorReturnTypes<M, K>;
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
// Main FetchStrategy type using union to avoid conflicts
|
|
329
|
+
export type FetchStrategy<M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
330
|
+
BaseFetchStrategy<M, K> &
|
|
331
|
+
(ColumnSelection<M, K> | RelationSelection<M, K> | CustomSelectors<M, K> |
|
|
332
|
+
(ColumnSelection<M, K> & RelationSelection<M, K>) |
|
|
333
|
+
(ColumnSelection<M, K> & CustomSelectors<M, K>) |
|
|
334
|
+
(RelationSelection<M, K> & CustomSelectors<M, K>) |
|
|
335
|
+
(ColumnSelection<M, K> & RelationSelection<M, K> & CustomSelectors<M, K>));
|
|
336
|
+
|
|
337
|
+
export type AggregateStrategy<M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
338
|
+
BaseAggregateStrategy<M, K>
|
|
339
|
+
| CustomAggregateSelectors<M, K>;
|
|
340
|
+
|
|
341
|
+
type WhereFunc<M extends Record<string, TableDefinition<M>>, K extends keyof M> = (row: RootTableRefs<M, K>) => RawFilter | Array<PrimaryKeyObject<M, K>>;
|
|
342
|
+
|
|
343
|
+
type BaseAggregateStrategy<M extends Record<string, TableDefinition<M>>, K extends keyof M> = {
|
|
344
|
+
limit?: number;
|
|
345
|
+
offset?: number;
|
|
346
|
+
where?: WhereFunc<M, K>;
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
type CustomAggregateSelectors<M extends Record<string, TableDefinition<M>>, K extends keyof M> = {
|
|
350
|
+
[key: string]: (row: RootSelectionRefs<M, K>) => ValidSelectorReturnTypes<M, K>;
|
|
351
|
+
} & {
|
|
352
|
+
where?: WhereFunc<M, K>;
|
|
353
|
+
} & {
|
|
354
|
+
// Explicitly prevent limit/offset in selectors
|
|
355
|
+
limit?: never;
|
|
356
|
+
offset?: never;
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
type TrueKeys<M extends Record<string, TableDefinition<M>>, K extends keyof M, FS extends Record<string, any>> = {
|
|
360
|
+
[C in keyof M[K]['columns']]: FS extends Record<C, infer B> ? (B extends true ? C : never) : never;
|
|
361
|
+
}[keyof M[K]['columns']];
|
|
362
|
+
|
|
363
|
+
type FalseKeys<M extends Record<string, TableDefinition<M>>, K extends keyof M, FS extends Record<string, any>> = {
|
|
364
|
+
[C in keyof M[K]['columns']]: FS extends Record<C, infer B> ? (B extends false ? C : never) : never;
|
|
365
|
+
}[keyof M[K]['columns']];
|
|
366
|
+
|
|
367
|
+
type SelectedColumns<M extends Record<string, TableDefinition<M>>, K extends keyof M, FS extends Record<string, any>> =
|
|
368
|
+
TrueKeys<M, K, FS> extends never
|
|
369
|
+
? (FalseKeys<M, K, FS> extends never
|
|
370
|
+
? keyof M[K]['columns']
|
|
371
|
+
: Exclude<keyof M[K]['columns'], FalseKeys<M, K, FS>>)
|
|
372
|
+
: TrueKeys<M, K, FS>;
|
|
373
|
+
|
|
374
|
+
type RequiredColumnKeys<M extends Record<string, TableDefinition<M>>, K extends keyof M, FS extends Record<string, any>> = {
|
|
375
|
+
[C in SelectedColumns<M, K, FS>]: IsRequired<M[K]['columns'][C]> extends true ? C : never;
|
|
376
|
+
}[SelectedColumns<M, K, FS>];
|
|
377
|
+
|
|
378
|
+
type OptionalColumnKeys<M extends Record<string, TableDefinition<M>>, K extends keyof M, FS extends Record<string, any>> =
|
|
379
|
+
Exclude<SelectedColumns<M, K, FS>, RequiredColumnKeys<M, K, FS>>;
|
|
380
|
+
|
|
381
|
+
// Helper type to check if a value is actually a column reference from the row object
|
|
382
|
+
// This is a bit of a hack - we check if the type has the structure of a ColumnFilterType
|
|
383
|
+
// but without the filter methods (which is what ColumnSelectionRefs provides)
|
|
384
|
+
type IsActualColumnReference<T, M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
385
|
+
T extends ColumnTypeToTS<infer CT>
|
|
386
|
+
? CT extends ORMColumnDefinition | ORMJsonColumnDefinition
|
|
387
|
+
? true
|
|
388
|
+
: false
|
|
389
|
+
: false;
|
|
390
|
+
|
|
391
|
+
// Alternative approach: Check if the type matches what we'd get from accessing ColumnSelectionRefs
|
|
392
|
+
type IsFromColumnSelectionRefs<M extends Record<string, TableDefinition<M>>, K extends keyof M, T = any> =
|
|
393
|
+
T extends ColumnSelectionRefs<M, K>[keyof ColumnSelectionRefs<M, K>] ? true :
|
|
394
|
+
T extends (M[K] extends { relations: infer R }
|
|
395
|
+
? {
|
|
396
|
+
[RName in keyof R]: R[RName] extends { target: infer Target extends keyof M }
|
|
397
|
+
? ColumnSelectionRefs<M, Target>[keyof ColumnSelectionRefs<M, Target>]
|
|
398
|
+
: never;
|
|
399
|
+
}[keyof R]
|
|
400
|
+
: never) ? true :
|
|
401
|
+
T extends number ? true : // Allow aggregate function return type (number)
|
|
402
|
+
false;
|
|
403
|
+
|
|
404
|
+
// Helper type to infer the TypeScript type from selector return values
|
|
405
|
+
// Only allows types that come from actual column selections or aggregate functions
|
|
406
|
+
type InferSelectorReturnType<T, M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
407
|
+
IsFromColumnSelectionRefs<M, K, T> extends true ? T : never;
|
|
408
|
+
|
|
409
|
+
// ADD helper to check if return type is an aggregate function:
|
|
410
|
+
type IsAggregateFunction<T> = T extends BaseAggregateFunction ? true : false;
|
|
411
|
+
|
|
412
|
+
type IsRequiredAggregate<T> = T extends BaseAggregateFunction & { __functionType: infer FType }
|
|
413
|
+
? FType extends 'count' | 'sum' | 'avg' ? true : false
|
|
414
|
+
: false;
|
|
415
|
+
|
|
416
|
+
// Helper to check if it's a min/max function that should preserve column type
|
|
417
|
+
type IsMinMaxAggregate<T> = T extends AggregateMinMaxFunction<any> & { __functionType: infer FType }
|
|
418
|
+
? FType extends 'max' | 'min' ? true : false
|
|
419
|
+
: false;
|
|
420
|
+
|
|
421
|
+
// Helper to extract the column type from min/max aggregate
|
|
422
|
+
type ExtractMinMaxColumnType<T> = T extends AggregateMinMaxFunction<infer ColType>
|
|
423
|
+
? ColumnDefinitionToTS<ColType>
|
|
424
|
+
: never;
|
|
425
|
+
|
|
426
|
+
// Updated CustomSelectorProperties with conditional nullability
|
|
427
|
+
type CustomSelectorProperties<M extends Record<string, TableDefinition<M>>, K extends keyof M, FS extends Record<string, any>> = {
|
|
428
|
+
// Required properties (count, sum, avg) - no question mark, no null/undefined
|
|
429
|
+
[P in keyof FS as
|
|
430
|
+
P extends keyof M[K]['columns'] ? never :
|
|
431
|
+
P extends ReservedFetchStrategyProps ? never :
|
|
432
|
+
P extends (M[K] extends { relations: infer R } ? keyof R : never) ? never :
|
|
433
|
+
FS[P] extends (row: any) => any ?
|
|
434
|
+
(FS[P] extends (row: RootSelectionRefs<M, K>) => infer ReturnType
|
|
435
|
+
? IsRequiredAggregate<ReturnType> extends true
|
|
436
|
+
? P // Required aggregates
|
|
437
|
+
: never
|
|
438
|
+
: never)
|
|
439
|
+
: never
|
|
440
|
+
]: FS[P] extends (row: RootSelectionRefs<M, K>) => infer ReturnType
|
|
441
|
+
? number // Required aggregate functions (count, sum, avg) return required number
|
|
442
|
+
: never;
|
|
443
|
+
} & {
|
|
444
|
+
// Optional properties (max, min, plain columns) - with question mark AND null/undefined
|
|
445
|
+
[P in keyof FS as
|
|
446
|
+
P extends keyof M[K]['columns'] ? never :
|
|
447
|
+
P extends ReservedFetchStrategyProps ? never :
|
|
448
|
+
P extends (M[K] extends { relations: infer R } ? keyof R : never) ? never :
|
|
449
|
+
FS[P] extends (row: any) => any ?
|
|
450
|
+
(FS[P] extends (row: RootSelectionRefs<M, K>) => infer ReturnType
|
|
451
|
+
? IsRequiredAggregate<ReturnType> extends true
|
|
452
|
+
? never // Required aggregates are not optional
|
|
453
|
+
: P // Everything else is optional
|
|
454
|
+
: never)
|
|
455
|
+
: never
|
|
456
|
+
]?: FS[P] extends (row: RootSelectionRefs<M, K>) => infer ReturnType
|
|
457
|
+
? IsMinMaxAggregate<ReturnType> extends true
|
|
458
|
+
? ExtractMinMaxColumnType<ReturnType> | null | undefined
|
|
459
|
+
: IsAggregateFunction<ReturnType> extends true
|
|
460
|
+
? number | null | undefined
|
|
461
|
+
: ReturnType extends ORMColumnDefinition | ORMJsonColumnDefinition
|
|
462
|
+
? ColumnDefinitionToTS<ReturnType> | null | undefined
|
|
463
|
+
: never
|
|
464
|
+
: never;
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
export type Selection<
|
|
468
|
+
M extends Record<string, TableDefinition<M>>,
|
|
469
|
+
K extends keyof M,
|
|
470
|
+
FS extends Record<string, any>
|
|
471
|
+
> = {
|
|
472
|
+
[C in RequiredColumnKeys<M, K, FS>]: ColumnTypeToTS<M[K]['columns'][C]>;
|
|
473
|
+
} & {
|
|
474
|
+
[C in OptionalColumnKeys<M, K, FS>]?: ColumnTypeToTS<M[K]['columns'][C]> | null | undefined;
|
|
475
|
+
} & (
|
|
476
|
+
M[K] extends { relations: infer R }
|
|
477
|
+
? {
|
|
478
|
+
[RName in keyof R & keyof FS as
|
|
479
|
+
R[RName] extends { type: 'hasMany' } ? RName : never
|
|
480
|
+
]:
|
|
481
|
+
R[RName] extends { target: infer Target extends keyof M }
|
|
482
|
+
? FS[RName] extends true
|
|
483
|
+
? Array<DeepExpand<Selection<M, Target, {}>>>
|
|
484
|
+
: FS[RName] extends Record<string, any>
|
|
485
|
+
? Array<DeepExpand<Selection<M, Target, FS[RName]>>>
|
|
486
|
+
: never
|
|
487
|
+
: never;
|
|
488
|
+
} & {
|
|
489
|
+
[RName in keyof R & keyof FS as
|
|
490
|
+
R[RName] extends { type: 'hasOne' | 'references' } ? RName : never
|
|
491
|
+
]?:
|
|
492
|
+
R[RName] extends { target: infer Target extends keyof M }
|
|
493
|
+
? FS[RName] extends true
|
|
494
|
+
? DeepExpand<Selection<M, Target, {}>> | null
|
|
495
|
+
: FS[RName] extends Record<string, any>
|
|
496
|
+
? DeepExpand<Selection<M, Target, FS[RName]>> | null
|
|
497
|
+
: never
|
|
498
|
+
: never;
|
|
499
|
+
}
|
|
500
|
+
: {}
|
|
501
|
+
) & CustomSelectorProperties<M, K, FS>;
|
|
502
|
+
|
|
503
|
+
export type PrimaryKeyArgs<M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
504
|
+
M[K]['primaryKey'] extends readonly [infer A extends keyof M[K]['columns']]
|
|
505
|
+
? [key1: ColumnTypeToTS<M[K]['columns'][A]>]
|
|
506
|
+
: M[K]['primaryKey'] extends readonly [infer A extends keyof M[K]['columns'], infer B extends keyof M[K]['columns']]
|
|
507
|
+
? [key1: ColumnTypeToTS<M[K]['columns'][A]>, key2: ColumnTypeToTS<M[K]['columns'][B]>]
|
|
508
|
+
: M[K]['primaryKey'] extends readonly [infer A extends keyof M[K]['columns'], infer B extends keyof M[K]['columns'], infer C extends keyof M[K]['columns']]
|
|
509
|
+
? [key1: ColumnTypeToTS<M[K]['columns'][A]>, key2: ColumnTypeToTS<M[K]['columns'][B]>, key3: ColumnTypeToTS<M[K]['columns'][C]>]
|
|
510
|
+
: M[K]['primaryKey'] extends readonly [infer A extends keyof M[K]['columns'], infer B extends keyof M[K]['columns'], infer C extends keyof M[K]['columns'], infer D extends keyof M[K]['columns']]
|
|
511
|
+
? [key1: ColumnTypeToTS<M[K]['columns'][A]>, key2: ColumnTypeToTS<M[K]['columns'][B]>, key3: ColumnTypeToTS<M[K]['columns'][C]>, key4: ColumnTypeToTS<M[K]['columns'][D]>]
|
|
512
|
+
: M[K]['primaryKey'] extends readonly [infer A extends keyof M[K]['columns'], infer B extends keyof M[K]['columns'], infer C extends keyof M[K]['columns'], infer D extends keyof M[K]['columns'], infer E extends keyof M[K]['columns']]
|
|
513
|
+
? [key1: ColumnTypeToTS<M[K]['columns'][A]>, key2: ColumnTypeToTS<M[K]['columns'][B]>, key3: ColumnTypeToTS<M[K]['columns'][C]>, key4: ColumnTypeToTS<M[K]['columns'][D]>, key5: ColumnTypeToTS<M[K]['columns'][E]>]
|
|
514
|
+
: M[K]['primaryKey'] extends readonly [infer A extends keyof M[K]['columns'], infer B extends keyof M[K]['columns'], infer C extends keyof M[K]['columns'], infer D extends keyof M[K]['columns'], infer E extends keyof M[K]['columns'], infer F extends keyof M[K]['columns']]
|
|
515
|
+
? [key1: ColumnTypeToTS<M[K]['columns'][A]>, key2: ColumnTypeToTS<M[K]['columns'][B]>, key3: ColumnTypeToTS<M[K]['columns'][C]>, key4: ColumnTypeToTS<M[K]['columns'][D]>, key5: ColumnTypeToTS<M[K]['columns'][E]>, key6: ColumnTypeToTS<M[K]['columns'][F]>]
|
|
516
|
+
: never;
|
|
517
|
+
|
|
518
|
+
// Helper type to get primary key columns that are required (notNull)
|
|
519
|
+
type RequiredPrimaryKeyColumns<M extends Record<string, TableDefinition<M>>, K extends keyof M> = {
|
|
520
|
+
[PK in M[K]['primaryKey'][number]]: PK extends keyof M[K]['columns']
|
|
521
|
+
? IsRequired<M[K]['columns'][PK]> extends true
|
|
522
|
+
? PK
|
|
523
|
+
: never
|
|
524
|
+
: never;
|
|
525
|
+
}[M[K]['primaryKey'][number]];
|
|
526
|
+
|
|
527
|
+
// Helper type to get primary key columns that are optional (nullable)
|
|
528
|
+
type OptionalPrimaryKeyColumns<M extends Record<string, TableDefinition<M>>, K extends keyof M> = {
|
|
529
|
+
[PK in M[K]['primaryKey'][number]]: PK extends keyof M[K]['columns']
|
|
530
|
+
? IsRequired<M[K]['columns'][PK]> extends true
|
|
531
|
+
? never
|
|
532
|
+
: PK
|
|
533
|
+
: never;
|
|
534
|
+
}[M[K]['primaryKey'][number]];
|
|
535
|
+
|
|
536
|
+
// Type for insert operations - requires notNull columns but allows notNullExceptInsert to be optional
|
|
537
|
+
type InsertRow<M extends Record<string, TableDefinition<M>>, K extends keyof M> = {
|
|
538
|
+
// Required columns (notNull but not notNullExceptInsert)
|
|
539
|
+
[C in keyof M[K]['columns'] as IsRequiredInsert<M[K]['columns'][C]> extends true ? C : never]: ColumnTypeToTS<M[K]['columns'][C]>;
|
|
540
|
+
} & {
|
|
541
|
+
// Optional columns (nullable, or notNullExceptInsert)
|
|
542
|
+
[C in keyof M[K]['columns'] as IsRequiredInsert<M[K]['columns'][C]> extends true ? never : C]?: ColumnTypeToTS<M[K]['columns'][C]> | null | undefined;
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
// Type for updateChanges and replace operations
|
|
546
|
+
type UpdateChangesRow<M extends Record<string, TableDefinition<M>>, K extends keyof M> = {
|
|
547
|
+
// Required primary key columns
|
|
548
|
+
[C in RequiredPrimaryKeyColumns<M, K>]: ColumnTypeToTS<M[K]['columns'][C]>;
|
|
549
|
+
} & {
|
|
550
|
+
// Optional primary key columns
|
|
551
|
+
[C in OptionalPrimaryKeyColumns<M, K>]?: ColumnTypeToTS<M[K]['columns'][C]> | null | undefined;
|
|
552
|
+
} & {
|
|
553
|
+
// All other columns are optional
|
|
554
|
+
[C in Exclude<keyof M[K]['columns'], M[K]['primaryKey'][number]>]?: IsRequired<M[K]['columns'][C]> extends true
|
|
555
|
+
? ColumnTypeToTS<M[K]['columns'][C]>
|
|
556
|
+
: ColumnTypeToTS<M[K]['columns'][C]> | null | undefined;
|
|
557
|
+
};
|
|
558
|
+
|
|
559
|
+
// Active record methods for top-level entities
|
|
560
|
+
type ActiveRecordMethods<M extends Record<string, TableDefinition<M>>, K extends keyof M> = {
|
|
561
|
+
saveChanges(): Promise<void>;
|
|
562
|
+
saveChanges(concurrency: ConcurrencyConfig<M>[K]): Promise<void>;
|
|
563
|
+
acceptChanges(): void;
|
|
564
|
+
clearChanges(): void;
|
|
565
|
+
refresh(): Promise<void>;
|
|
566
|
+
refresh<strategy extends FetchStrategy<M, K>>(strategy: strategy): Promise<DeepExpand<Selection<M, K, strategy>> & ActiveRecordMethods<M, K>>;
|
|
567
|
+
delete(): Promise<void>;
|
|
568
|
+
delete<strategy extends FetchStrategy<M, K>>(strategy: strategy): Promise<void>;
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
// Helper type to add active record methods to selection results
|
|
572
|
+
type WithActiveRecord<T, M extends Record<string, TableDefinition<M>>, K extends keyof M> =
|
|
573
|
+
T & ActiveRecordMethods<M, K>;
|
|
574
|
+
|
|
575
|
+
export type TableClient<M extends Record<string, TableDefinition<M>>, K extends keyof M> = {
|
|
576
|
+
getAll(): Promise<Array<WithActiveRecord<DeepExpand<Selection<M, K, {}>>, M, K>>>;
|
|
577
|
+
getAll<strategy extends FetchStrategy<M, K>>(strategy: strategy): Promise<Array<WithActiveRecord<DeepExpand<Selection<M, K, strategy>>, M, K>>>;
|
|
578
|
+
getMany(filter: RawFilter | Array<PrimaryKeyObject<M, K>>): Promise<Array<WithActiveRecord<DeepExpand<Selection<M, K, {}>>, M, K>>>;
|
|
579
|
+
getMany<strategy extends FetchStrategy<M, K>>(filter: RawFilter | Array<PrimaryKeyObject<M, K>>, strategy: strategy): Promise<Array<WithActiveRecord<DeepExpand<Selection<M, K, strategy>>, M, K>>>;
|
|
580
|
+
|
|
581
|
+
aggregate<strategy extends AggregateStrategy<M, K>>(strategy: strategy): Promise<Array<DeepExpand<CustomSelectorProperties<M, K, strategy>>>>;
|
|
582
|
+
|
|
583
|
+
getOne<strategy extends FetchStrategy<M, K>>(
|
|
584
|
+
filter: RawFilter | Array<PrimaryKeyObject<M, K>>
|
|
585
|
+
): Promise<WithActiveRecord<DeepExpand<Selection<M, K, strategy>>, M, K>>;
|
|
586
|
+
|
|
587
|
+
getOne<strategy extends FetchStrategy<M, K>>(
|
|
588
|
+
filter: RawFilter | Array<PrimaryKeyObject<M, K>>,
|
|
589
|
+
strategy: strategy
|
|
590
|
+
): Promise<WithActiveRecord<DeepExpand<Selection<M, K, strategy>>, M, K>>;
|
|
591
|
+
|
|
592
|
+
getById<strategy extends FetchStrategy<M, K>>(
|
|
593
|
+
...args: [...PrimaryKeyArgs<M, K>, strategy: strategy]
|
|
594
|
+
): Promise<WithActiveRecord<DeepExpand<Selection<M, K, strategy>>, M, K>>;
|
|
595
|
+
|
|
596
|
+
getById(
|
|
597
|
+
...args: [...PrimaryKeyArgs<M, K>]
|
|
598
|
+
): Promise<WithActiveRecord<DeepExpand<Selection<M, K, {}>>, M, K>>;
|
|
599
|
+
|
|
600
|
+
update(
|
|
601
|
+
row: Partial<{
|
|
602
|
+
[C in keyof M[K]['columns']]: IsRequired<M[K]['columns'][C]> extends true
|
|
603
|
+
? ColumnTypeToTS<M[K]['columns'][C]>
|
|
604
|
+
: ColumnTypeToTS<M[K]['columns'][C]> | null | undefined;
|
|
605
|
+
}>,
|
|
606
|
+
opts: { where: (row: RootTableRefs<M, K>) => RawFilter }
|
|
607
|
+
): Promise<void>;
|
|
608
|
+
|
|
609
|
+
count(filter: RawFilter | Array<PrimaryKeyObject<M, K>>,): Promise<number>;
|
|
610
|
+
delete(filter: RawFilter | Array<PrimaryKeyObject<M, K>>,): Promise<void>;
|
|
611
|
+
deleteCascade(filter: RawFilter | Array<PrimaryKeyObject<M, K>>,): Promise<void>;
|
|
612
|
+
|
|
613
|
+
update<strategy extends FetchStrategy<M, K>>(
|
|
614
|
+
row: Partial<{
|
|
615
|
+
[C in keyof M[K]['columns']]: IsRequired<M[K]['columns'][C]> extends true
|
|
616
|
+
? ColumnTypeToTS<M[K]['columns'][C]>
|
|
617
|
+
: ColumnTypeToTS<M[K]['columns'][C]> | null | undefined;
|
|
618
|
+
}>,
|
|
619
|
+
opts: { where: (row: RootTableRefs<M, K>) => RawFilter },
|
|
620
|
+
strategy: strategy
|
|
621
|
+
): Promise<Array<WithActiveRecord<DeepExpand<Selection<M, K, strategy>>, M, K>>>;
|
|
622
|
+
|
|
623
|
+
replace(
|
|
624
|
+
row: Array<UpdateChangesRow<M, K>>
|
|
625
|
+
): Promise<void>;
|
|
626
|
+
|
|
627
|
+
replace<strategy extends FetchStrategy<M, K>>(
|
|
628
|
+
row: UpdateChangesRow<M, K>,
|
|
629
|
+
strategy: strategy
|
|
630
|
+
): Promise<WithActiveRecord<DeepExpand<Selection<M, K, strategy>>, M, K>>;
|
|
631
|
+
|
|
632
|
+
replace<strategy extends FetchStrategy<M, K>>(
|
|
633
|
+
rows: Array<UpdateChangesRow<M, K>>,
|
|
634
|
+
strategy: strategy
|
|
635
|
+
): Promise<Array<WithActiveRecord<DeepExpand<Selection<M, K, strategy>>, M, K>>>;
|
|
636
|
+
|
|
637
|
+
updateChanges(
|
|
638
|
+
row: UpdateChangesRow<M, K>,
|
|
639
|
+
originalRow: UpdateChangesRow<M, K>
|
|
640
|
+
): Promise<WithActiveRecord<DeepExpand<Selection<M, K, {}>>, M, K>>;
|
|
641
|
+
|
|
642
|
+
updateChanges(
|
|
643
|
+
rows: Array<UpdateChangesRow<M, K>>,
|
|
644
|
+
originalRows: Array<UpdateChangesRow<M, K>>
|
|
645
|
+
): Promise<Array<WithActiveRecord<DeepExpand<Selection<M, K, {}>>, M, K>>>;
|
|
646
|
+
|
|
647
|
+
updateChanges<strategy extends FetchStrategy<M, K>>(
|
|
648
|
+
row: UpdateChangesRow<M, K>,
|
|
649
|
+
originalRow: UpdateChangesRow<M, K>,
|
|
650
|
+
strategy: strategy
|
|
651
|
+
): Promise<WithActiveRecord<DeepExpand<Selection<M, K, strategy>>, M, K>>;
|
|
652
|
+
|
|
653
|
+
updateChanges<strategy extends FetchStrategy<M, K>>(
|
|
654
|
+
rows: Array<UpdateChangesRow<M, K>>,
|
|
655
|
+
originalRows: Array<UpdateChangesRow<M, K>>,
|
|
656
|
+
strategy: strategy
|
|
657
|
+
): Promise<Array<WithActiveRecord<DeepExpand<Selection<M, K, strategy>>, M, K>>>;
|
|
658
|
+
|
|
659
|
+
insertAndForget(
|
|
660
|
+
row: InsertRow<M, K>
|
|
661
|
+
): Promise<void>;
|
|
662
|
+
|
|
663
|
+
insertAndForget(
|
|
664
|
+
rows: Array<InsertRow<M, K>>
|
|
665
|
+
): Promise<void>;
|
|
666
|
+
|
|
667
|
+
insert(
|
|
668
|
+
row: InsertRow<M, K>
|
|
669
|
+
): Promise<WithActiveRecord<DeepExpand<Selection<M, K, {}>>, M, K>>;
|
|
670
|
+
|
|
671
|
+
insert(
|
|
672
|
+
rows: Array<InsertRow<M, K>>
|
|
673
|
+
): Promise<Array<WithActiveRecord<DeepExpand<Selection<M, K, {}>>, M, K>>>;
|
|
674
|
+
|
|
675
|
+
insert<strategy extends FetchStrategy<M, K>>(
|
|
676
|
+
row: InsertRow<M, K>,
|
|
677
|
+
strategy: strategy
|
|
678
|
+
): Promise<WithActiveRecord<DeepExpand<Selection<M, K, strategy>>, M, K>>;
|
|
679
|
+
|
|
680
|
+
insert<strategy extends FetchStrategy<M, K>>(
|
|
681
|
+
rows: Array<InsertRow<M, K>>,
|
|
682
|
+
strategy: strategy
|
|
683
|
+
): Promise<Array<WithActiveRecord<DeepExpand<Selection<M, K, strategy>>, M, K>>>;
|
|
684
|
+
|
|
685
|
+
proxify(
|
|
686
|
+
row: UpdateChangesRow<M, K>
|
|
687
|
+
): Promise<WithActiveRecord<DeepExpand<Selection<M, K, {}>>, M, K>>;
|
|
688
|
+
|
|
689
|
+
proxify(
|
|
690
|
+
rows: Array<UpdateChangesRow<M, K>>
|
|
691
|
+
): Promise<Array<WithActiveRecord<DeepExpand<Selection<M, K, {}>>, M, K>>>;
|
|
692
|
+
|
|
693
|
+
proxify<strategy extends FetchStrategy<M, K>>(
|
|
694
|
+
row: UpdateChangesRow<M, K>,
|
|
695
|
+
strategy: strategy
|
|
696
|
+
): Promise<WithActiveRecord<DeepExpand<Selection<M, K, strategy>>, M, K>>;
|
|
697
|
+
|
|
698
|
+
proxify<strategy extends FetchStrategy<M, K>>(
|
|
699
|
+
rows: Array<UpdateChangesRow<M, K>>,
|
|
700
|
+
strategy: strategy
|
|
701
|
+
): Promise<Array<WithActiveRecord<DeepExpand<Selection<M, K, strategy>>, M, K>>>;
|
|
702
|
+
|
|
703
|
+
patch<strategy extends FetchStrategy<M, K>>(
|
|
704
|
+
patches: JsonPatch,
|
|
705
|
+
strategy: strategy,
|
|
706
|
+
concurrency?: ConcurrencyConfig<M>[K]
|
|
707
|
+
): Promise<void>;
|
|
708
|
+
|
|
709
|
+
tsType(): DeepExpand<Selection<M, K, {}>>;
|
|
710
|
+
|
|
711
|
+
tsType<strategy extends FetchStrategy<M, K>>(
|
|
712
|
+
strategy: strategy
|
|
713
|
+
): DeepExpand<Selection<M, K, strategy>>;
|
|
714
|
+
};
|
|
715
|
+
|
|
716
|
+
export type ConcurrencyStrategy = 'optimistic' | 'overwrite' | 'skipOnConflict';
|
|
717
|
+
|
|
718
|
+
export interface ColumnConcurrency {
|
|
719
|
+
readonly?: boolean;
|
|
720
|
+
concurrency?: ConcurrencyStrategy;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
export type ConcurrencyConfig<M extends Record<string, TableDefinition<M>>> = {
|
|
724
|
+
[K in keyof M]?: ColumnConcurrency & {
|
|
725
|
+
[C in keyof M[K]['columns']]?: {
|
|
726
|
+
concurrency: ConcurrencyStrategy;
|
|
727
|
+
};
|
|
728
|
+
} & (
|
|
729
|
+
M[K] extends { relations: infer R }
|
|
730
|
+
? {
|
|
731
|
+
[RName in keyof R]?: ConcurrencyConfig<M>[R[RName] extends { target: infer T extends keyof M } ? T : never];
|
|
732
|
+
}
|
|
733
|
+
: {}
|
|
734
|
+
);
|
|
735
|
+
};
|
|
736
|
+
|
|
737
|
+
export type DbOptions<M extends Record<string, TableDefinition<M>>> =
|
|
738
|
+
ConcurrencyConfig<M>
|
|
739
|
+
& ColumnConcurrency & {
|
|
740
|
+
db?: Pool | ((connectors: Connectors) => Pool | Promise<Pool>);
|
|
741
|
+
};
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
// type NegotiateDbInstance<T, C> = C extends WithDb
|
|
745
|
+
// ? DbConnectable<SchemaFromMappedDb<MappedDb<T>>>
|
|
746
|
+
// : MappedDb<T>;
|
|
747
|
+
|
|
748
|
+
// type WithDb = {
|
|
749
|
+
// db: Pool | ((connectors: Connectors) => Pool | Promise<Pool>)
|
|
750
|
+
// };
|
|
751
|
+
|
|
752
|
+
export type DbConcurrency<M extends Record<string, TableDefinition<M>>> =
|
|
753
|
+
ConcurrencyConfig<M>
|
|
754
|
+
& ColumnConcurrency;
|
|
755
|
+
|
|
756
|
+
type JsonPatch = Array<{
|
|
757
|
+
op: 'add' | 'remove' | 'replace' | 'copy' | 'move' | 'test';
|
|
758
|
+
path: string;
|
|
759
|
+
value?: any;
|
|
760
|
+
from?: string;
|
|
761
|
+
}>;
|
|
762
|
+
|
|
763
|
+
interface WithInterceptors {
|
|
764
|
+
request: AxiosInterceptorManager<InternalAxiosRequestConfig>;
|
|
765
|
+
response: AxiosInterceptorManager<AxiosResponse>;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
interface Connectors {
|
|
769
|
+
http(url: string): Pool;
|
|
770
|
+
d1(database: D1Database): Pool;
|
|
771
|
+
postgres(connectionString: string, options?: PoolOptions): Pool;
|
|
772
|
+
pglite(config?: PGliteOptions | string | undefined, options?: PoolOptions): Pool;
|
|
773
|
+
sqlite(connectionString: string, options?: PoolOptions): Pool;
|
|
774
|
+
sap(connectionString: string, options?: PoolOptions): Pool;
|
|
775
|
+
mssql(connectionConfig: ConnectionConfiguration, options?: PoolOptions): Pool;
|
|
776
|
+
mssql(connectionString: string, options?: PoolOptions): Pool;
|
|
777
|
+
oracle(config: PoolAttributes, options?: PoolOptions): Pool;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
type DbConnectable<M extends Record<string, TableDefinition<M>>> = {
|
|
781
|
+
http(url: string): DBClient<M>;
|
|
782
|
+
d1(database: D1Database): DBClient<M>;
|
|
783
|
+
postgres(connectionString: string, options?: PoolOptions): DBClient<M>;
|
|
784
|
+
pglite(config?: PGliteOptions | string | undefined, options?: PoolOptions): DBClient<M>;
|
|
785
|
+
sqlite(connectionString: string, options?: PoolOptions): DBClient<M>;
|
|
786
|
+
sap(connectionString: string, options?: PoolOptions): DBClient<M>;
|
|
787
|
+
mssql(connectionConfig: ConnectionConfiguration, options?: PoolOptions): DBClient<M>;
|
|
788
|
+
mssql(connectionString: string, options?: PoolOptions): DBClient<M>;
|
|
789
|
+
mssqlNative(connectionString: string, options?: PoolOptions): DBClient<M>;
|
|
790
|
+
mysql(connectionString: string, options?: PoolOptions): DBClient<M>;
|
|
791
|
+
oracle(config: PoolAttributes, options?: PoolOptions): DBClient<M>;
|
|
792
|
+
};
|
|
793
|
+
|
|
794
|
+
export interface Pool {
|
|
795
|
+
end(): Promise<void>;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
export interface PoolOptions {
|
|
799
|
+
size?: number;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
export type DBClient<M extends Record<string, TableDefinition<M>>> = {
|
|
803
|
+
[TableName in keyof M]: RootTableRefs<M, TableName> & TableClient<M, TableName>;
|
|
804
|
+
} & {
|
|
805
|
+
close(): Promise<void>;
|
|
806
|
+
filter: Filter;
|
|
807
|
+
and(f: Filter | RawFilter[], ...filters: RawFilter[]): Filter;
|
|
808
|
+
or(f: Filter | RawFilter[], ...filters: RawFilter[]): Filter;
|
|
809
|
+
not(): Filter;
|
|
810
|
+
query(filter: RawFilter | string): Promise<unknown[]>;
|
|
811
|
+
query<T>(filter: RawFilter | string): Promise<T[]>;
|
|
812
|
+
createPatch(original: any[], modified: any[]): JsonPatch;
|
|
813
|
+
createPatch(original: any, modified: any): JsonPatch;
|
|
814
|
+
(
|
|
815
|
+
config?: DbOptions<M>
|
|
816
|
+
): DBClient<M>;
|
|
817
|
+
transaction(
|
|
818
|
+
fn: (db: DBClient<M>) => Promise<unknown>
|
|
819
|
+
): Promise<void>;
|
|
820
|
+
// saveChanges(arraysOrRow: { saveChanges(): Promise<void> }): Promise<void>;
|
|
821
|
+
express(): import('express').RequestHandler;
|
|
822
|
+
express(config: ExpressConfig<M>): import('express').RequestHandler;
|
|
823
|
+
readonly metaData: DbConcurrency<M>;
|
|
824
|
+
|
|
825
|
+
interceptors: WithInterceptors;
|
|
826
|
+
} & WithInterceptors;
|
|
827
|
+
|
|
828
|
+
type ExpressConfig<M extends Record<string, TableDefinition<M>>> = {
|
|
829
|
+
[TableName in keyof M]?: ExpressTableConfig<M>;
|
|
830
|
+
} & {
|
|
831
|
+
db?: Pool | ((connectors: Connectors) => Pool | Promise<Pool>);
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
type ExpressTableConfig<M extends Record<string, TableDefinition<M>>> = {
|
|
835
|
+
baseFilter?: RawFilter | ((db: DBClient<M>, req: import('express').Request, res: import('express').Response) => RawFilter);
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
export type DeepExpand<T> =
|
|
839
|
+
T extends Date ? T :
|
|
840
|
+
T extends Array<infer U> ? Array<DeepExpand<U>> :
|
|
841
|
+
T extends object ? { [K in keyof T]: DeepExpand<T[K]> } :
|
|
842
|
+
T;
|
|
843
|
+
|
|
844
|
+
export function db<M extends Record<string, TableDefinition<M>>>(): DBClient<M>;
|