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/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>;