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