linkgress-orm 0.0.3 → 0.1.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.
Files changed (73) hide show
  1. package/README.md +3 -3
  2. package/dist/entity/db-column.d.ts +38 -1
  3. package/dist/entity/db-column.d.ts.map +1 -1
  4. package/dist/entity/db-column.js.map +1 -1
  5. package/dist/entity/db-context.d.ts +429 -50
  6. package/dist/entity/db-context.d.ts.map +1 -1
  7. package/dist/entity/db-context.js +884 -203
  8. package/dist/entity/db-context.js.map +1 -1
  9. package/dist/entity/entity-base.d.ts +8 -0
  10. package/dist/entity/entity-base.d.ts.map +1 -1
  11. package/dist/entity/entity-base.js.map +1 -1
  12. package/dist/index.d.ts +2 -2
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +4 -3
  15. package/dist/index.js.map +1 -1
  16. package/dist/query/collection-strategy.factory.d.ts.map +1 -1
  17. package/dist/query/collection-strategy.factory.js +7 -3
  18. package/dist/query/collection-strategy.factory.js.map +1 -1
  19. package/dist/query/collection-strategy.interface.d.ts +12 -6
  20. package/dist/query/collection-strategy.interface.d.ts.map +1 -1
  21. package/dist/query/conditions.d.ts +134 -23
  22. package/dist/query/conditions.d.ts.map +1 -1
  23. package/dist/query/conditions.js +58 -0
  24. package/dist/query/conditions.js.map +1 -1
  25. package/dist/query/cte-builder.d.ts +24 -5
  26. package/dist/query/cte-builder.d.ts.map +1 -1
  27. package/dist/query/cte-builder.js +45 -7
  28. package/dist/query/cte-builder.js.map +1 -1
  29. package/dist/query/grouped-query.d.ts +196 -8
  30. package/dist/query/grouped-query.d.ts.map +1 -1
  31. package/dist/query/grouped-query.js +586 -54
  32. package/dist/query/grouped-query.js.map +1 -1
  33. package/dist/query/join-builder.d.ts +5 -4
  34. package/dist/query/join-builder.d.ts.map +1 -1
  35. package/dist/query/join-builder.js +21 -47
  36. package/dist/query/join-builder.js.map +1 -1
  37. package/dist/query/query-builder.d.ts +118 -20
  38. package/dist/query/query-builder.d.ts.map +1 -1
  39. package/dist/query/query-builder.js +511 -280
  40. package/dist/query/query-builder.js.map +1 -1
  41. package/dist/query/query-utils.d.ts +45 -0
  42. package/dist/query/query-utils.d.ts.map +1 -0
  43. package/dist/query/query-utils.js +103 -0
  44. package/dist/query/query-utils.js.map +1 -0
  45. package/dist/query/sql-utils.d.ts +83 -0
  46. package/dist/query/sql-utils.d.ts.map +1 -0
  47. package/dist/query/sql-utils.js +218 -0
  48. package/dist/query/sql-utils.js.map +1 -0
  49. package/dist/query/strategies/cte-collection-strategy.d.ts +85 -0
  50. package/dist/query/strategies/cte-collection-strategy.d.ts.map +1 -0
  51. package/dist/query/strategies/cte-collection-strategy.js +338 -0
  52. package/dist/query/strategies/cte-collection-strategy.js.map +1 -0
  53. package/dist/query/strategies/lateral-collection-strategy.d.ts +59 -0
  54. package/dist/query/strategies/lateral-collection-strategy.d.ts.map +1 -0
  55. package/dist/query/strategies/lateral-collection-strategy.js +243 -0
  56. package/dist/query/strategies/lateral-collection-strategy.js.map +1 -0
  57. package/dist/query/strategies/temptable-collection-strategy.d.ts +21 -0
  58. package/dist/query/strategies/temptable-collection-strategy.d.ts.map +1 -1
  59. package/dist/query/strategies/temptable-collection-strategy.js +160 -38
  60. package/dist/query/strategies/temptable-collection-strategy.js.map +1 -1
  61. package/dist/query/subquery.d.ts +24 -1
  62. package/dist/query/subquery.d.ts.map +1 -1
  63. package/dist/query/subquery.js +38 -2
  64. package/dist/query/subquery.js.map +1 -1
  65. package/dist/schema/table-builder.d.ts +16 -0
  66. package/dist/schema/table-builder.d.ts.map +1 -1
  67. package/dist/schema/table-builder.js +23 -1
  68. package/dist/schema/table-builder.js.map +1 -1
  69. package/package.json +1 -1
  70. package/dist/query/strategies/jsonb-collection-strategy.d.ts +0 -51
  71. package/dist/query/strategies/jsonb-collection-strategy.d.ts.map +0 -1
  72. package/dist/query/strategies/jsonb-collection-strategy.js +0 -210
  73. package/dist/query/strategies/jsonb-collection-strategy.js.map +0 -1
@@ -3,15 +3,34 @@ import { TableBuilder, TableSchema, InferTableType } from '../schema/table-build
3
3
  import { UnwrapDbColumns, InsertData, ExtractDbColumns } from './db-column';
4
4
  import { DbEntity, EntityConstructor } from './entity-base';
5
5
  import { DbModelConfig } from './model-config';
6
- import { Condition, SqlFragment } from '../query/conditions';
6
+ import { Condition, SqlFragment, UnwrapSelection, FieldRef } from '../query/conditions';
7
7
  import { ResolveCollectionResults, SelectQueryBuilder, QueryBuilder } from '../query/query-builder';
8
8
  import { InferRowType } from '../schema/row-type';
9
9
  import { DbSchemaManager } from '../migration/db-schema-manager';
10
10
  import { DbSequence, SequenceConfig } from '../schema/sequence-builder';
11
+ import type { DbCte } from '../query/cte-builder';
11
12
  /**
12
13
  * Collection aggregation strategy type
13
14
  */
14
- export type CollectionStrategyType = 'jsonb' | 'temptable';
15
+ export type CollectionStrategyType = 'cte' | 'temptable' | 'lateral';
16
+ /**
17
+ * Order direction for orderBy clauses
18
+ */
19
+ export type OrderDirection = 'ASC' | 'DESC';
20
+ /**
21
+ * A single field that can be used in orderBy.
22
+ * At runtime, this is analyzed to extract the column reference.
23
+ * The type is intentionally broad to support various usage patterns.
24
+ */
25
+ export type OrderableField<T = unknown> = T;
26
+ /**
27
+ * Order by specification with direction - a tuple of [field, direction]
28
+ */
29
+ export type OrderByTuple<T = unknown> = [T, OrderDirection];
30
+ /**
31
+ * Order by selector result - can be a single field, array of fields, or array of [field, direction] tuples
32
+ */
33
+ export type OrderByResult<T = unknown> = T | T[] | Array<OrderByTuple<T>>;
15
34
  /**
16
35
  * Query execution options
17
36
  */
@@ -24,7 +43,7 @@ export interface QueryOptions {
24
43
  logExecutionTime?: boolean;
25
44
  /** Log query parameters */
26
45
  logParameters?: boolean;
27
- /** Collection aggregation strategy (default: 'jsonb') */
46
+ /** Collection aggregation strategy (default: 'lateral') */
28
47
  collectionStrategy?: CollectionStrategyType;
29
48
  /**
30
49
  * Disable automatic mapper transformations (fromDriver/toDriver).
@@ -125,6 +144,79 @@ export interface UpsertConfig {
125
144
  */
126
145
  updateColumnFilter?: (columnName: string) => boolean;
127
146
  }
147
+ /**
148
+ * Returning clause configuration
149
+ * - undefined: no RETURNING clause (returns void)
150
+ * - true: return all columns
151
+ * - selector function: return selected columns
152
+ */
153
+ export type ReturningConfig<TEntity, TResult = unknown> = undefined | true | ((entity: TEntity) => TResult);
154
+ /**
155
+ * Helper type to infer the result type based on ReturningConfig
156
+ * Note: Uses conditional types to properly infer return types
157
+ */
158
+ export type ReturningResult<TEntity, TReturning> = TReturning extends undefined ? void : TReturning extends true ? TEntity : TReturning extends (entity: TEntity) => infer R ? R : TReturning extends (...args: any[]) => infer R ? R : never;
159
+ /**
160
+ * Base type for returning option - used in method signatures
161
+ */
162
+ export type ReturningOption<TEntity> = undefined | true | ((entity: TEntity) => any);
163
+ /**
164
+ * Fluent insert operation that can be awaited directly or chained with .returning()
165
+ *
166
+ * @example
167
+ * ```typescript
168
+ * // No returning (default) - returns void
169
+ * await db.users.insert({ username: 'alice' });
170
+ *
171
+ * // With returning() - returns full entity
172
+ * const user = await db.users.insert({ username: 'alice' }).returning();
173
+ *
174
+ * // With returning(selector) - returns selected columns
175
+ * const { id } = await db.users.insert({ username: 'alice' }).returning(u => ({ id: u.id }));
176
+ * ```
177
+ */
178
+ export interface FluentInsert<TEntity extends DbEntity> extends PromiseLike<void> {
179
+ /** Return all columns from the inserted row */
180
+ returning(): PromiseLike<UnwrapDbColumns<TEntity>>;
181
+ /** Return selected columns from the inserted row */
182
+ returning<TResult>(selector: (entity: EntityQuery<TEntity>) => TResult): PromiseLike<UnwrapDbColumns<TResult>>;
183
+ }
184
+ /**
185
+ * Fluent insert many operation
186
+ */
187
+ export interface FluentInsertMany<TEntity extends DbEntity> extends PromiseLike<void> {
188
+ /** Return all columns from the inserted rows */
189
+ returning(): PromiseLike<UnwrapDbColumns<TEntity>[]>;
190
+ /** Return selected columns from the inserted rows */
191
+ returning<TResult>(selector: (entity: EntityQuery<TEntity>) => TResult): PromiseLike<UnwrapDbColumns<TResult>[]>;
192
+ }
193
+ /**
194
+ * Fluent update operation
195
+ */
196
+ export interface FluentUpdate<TEntity extends DbEntity> extends PromiseLike<void> {
197
+ /** Return all columns from the updated rows */
198
+ returning(): PromiseLike<UnwrapDbColumns<TEntity>[]>;
199
+ /** Return selected columns from the updated rows */
200
+ returning<TResult>(selector: (entity: EntityQuery<TEntity>) => TResult): PromiseLike<UnwrapDbColumns<TResult>[]>;
201
+ }
202
+ /**
203
+ * Fluent bulk update operation
204
+ */
205
+ export interface FluentBulkUpdate<TEntity extends DbEntity> extends PromiseLike<void> {
206
+ /** Return all columns from the updated rows */
207
+ returning(): PromiseLike<UnwrapDbColumns<TEntity>[]>;
208
+ /** Return selected columns from the updated rows */
209
+ returning<TResult>(selector: (entity: EntityQuery<TEntity>) => TResult): PromiseLike<UnwrapDbColumns<TResult>[]>;
210
+ }
211
+ /**
212
+ * Fluent upsert operation
213
+ */
214
+ export interface FluentUpsert<TEntity extends DbEntity> extends PromiseLike<void> {
215
+ /** Return all columns from the upserted rows */
216
+ returning(): PromiseLike<UnwrapDbColumns<TEntity>[]>;
217
+ /** Return selected columns from the upserted rows */
218
+ returning<TResult>(selector: (entity: EntityQuery<TEntity>) => TResult): PromiseLike<UnwrapDbColumns<TResult>[]>;
219
+ }
128
220
  /**
129
221
  * Insert builder for upsert operations
130
222
  */
@@ -141,10 +233,6 @@ export declare class InsertBuilder<TSchema extends TableSchema> {
141
233
  private setWhereClause?;
142
234
  private overridingSystemValue;
143
235
  constructor(schema: TSchema, client: DatabaseClient, executor?: QueryExecutor | undefined);
144
- /**
145
- * Get qualified table name with schema prefix if specified
146
- */
147
- private getQualifiedTableName;
148
236
  /**
149
237
  * Set the values to insert (single row or multiple rows)
150
238
  */
@@ -205,24 +293,29 @@ export declare class TableAccessor<TBuilder extends TableBuilder<any>> {
205
293
  withQueryOptions(options: QueryOptions): TableAccessor<TBuilder>;
206
294
  /**
207
295
  * Start a select query with automatic type inference
296
+ * UnwrapSelection extracts the value types from SqlFragment<T> expressions
208
297
  */
209
- select<TSelection>(selector: (row: InferRowType<TBuilder>) => TSelection): SelectQueryBuilder<TSelection>;
298
+ select<TSelection>(selector: (row: InferRowType<TBuilder>) => TSelection): SelectQueryBuilder<UnwrapSelection<TSelection>>;
210
299
  /**
211
300
  * Add WHERE condition before select
212
301
  */
213
302
  where(condition: (row: InferRowType<TBuilder>) => Condition): QueryBuilder<TableSchema, InferRowType<TBuilder>>;
303
+ /**
304
+ * Add CTEs (Common Table Expressions) to the query
305
+ */
306
+ with(...ctes: DbCte<any>[]): SelectQueryBuilder<InferRowType<TBuilder>>;
214
307
  /**
215
308
  * Left join with another table and selector
216
309
  */
217
310
  leftJoin<TRight, TSelection>(rightTable: {
218
311
  _getSchema: () => TableSchema;
219
- } | import('../query/subquery').Subquery<TRight, 'table'>, condition: (left: InferRowType<TBuilder>, right: TRight) => Condition, selector: (left: InferRowType<TBuilder>, right: TRight) => TSelection, alias?: string): SelectQueryBuilder<TSelection>;
312
+ } | import('../query/subquery').Subquery<TRight, 'table'>, condition: (left: InferRowType<TBuilder>, right: TRight) => Condition, selector: (left: InferRowType<TBuilder>, right: TRight) => TSelection, alias?: string): SelectQueryBuilder<UnwrapSelection<TSelection>>;
220
313
  /**
221
314
  * Inner join with another table or subquery and selector
222
315
  */
223
316
  innerJoin<TRight, TSelection>(rightTable: {
224
317
  _getSchema: () => TableSchema;
225
- } | import('../query/subquery').Subquery<TRight, 'table'>, condition: (left: InferRowType<TBuilder>, right: TRight) => Condition, selector: (left: InferRowType<TBuilder>, right: TRight) => TSelection, alias?: string): SelectQueryBuilder<TSelection>;
318
+ } | import('../query/subquery').Subquery<TRight, 'table'>, condition: (left: InferRowType<TBuilder>, right: TRight) => Condition, selector: (left: InferRowType<TBuilder>, right: TRight) => TSelection, alias?: string): SelectQueryBuilder<UnwrapSelection<TSelection>>;
226
319
  /**
227
320
  * Get table schema (internal use for joins)
228
321
  */
@@ -235,10 +328,6 @@ export declare class TableAccessor<TBuilder extends TableBuilder<any>> {
235
328
  * Get table name
236
329
  */
237
330
  getTableName(): string;
238
- /**
239
- * Get qualified table name with schema prefix if specified
240
- */
241
- private getQualifiedTableName;
242
331
  /**
243
332
  * Insert a row
244
333
  */
@@ -365,11 +454,52 @@ export type EntityUpsertConfig<TEntity extends DbEntity> = {
365
454
  */
366
455
  updateColumnFilter?: (columnName: string) => boolean;
367
456
  };
457
+ /**
458
+ * Type helper to detect if a type is a class instance (has prototype methods)
459
+ * vs a plain data object. Used to prevent Date, Map, Set, etc. from being
460
+ * treated as DbEntity.
461
+ * Excludes DbColumn and SqlFragment which have valueOf but are not value types.
462
+ */
463
+ type IsClassInstance<T> = T extends {
464
+ __isDbColumn: true;
465
+ } ? false : T extends SqlFragment<any> ? false : T extends {
466
+ valueOf(): infer V;
467
+ } ? V extends T ? true : V extends number | string | boolean | bigint | symbol ? true : false : false;
468
+ /**
469
+ * Check for types with known class method signatures
470
+ */
471
+ type HasClassMethods<T> = T extends {
472
+ getTime(): number;
473
+ } ? true : T extends {
474
+ size: number;
475
+ has(value: any): boolean;
476
+ } ? true : T extends {
477
+ byteLength: number;
478
+ } ? true : T extends {
479
+ then(onfulfilled?: any): any;
480
+ } ? true : T extends {
481
+ message: string;
482
+ name: string;
483
+ } ? true : T extends {
484
+ exec(string: string): any;
485
+ } ? true : false;
486
+ /**
487
+ * Combined check for value types that should not be treated as DbEntity
488
+ */
489
+ type IsValueType<T> = IsClassInstance<T> extends true ? true : HasClassMethods<T> extends true ? true : false;
490
+ /**
491
+ * Type helper to convert plain object values to FieldRefs for use in conditions
492
+ * This is used when TSelection is not a DbEntity but needs to be used in where/join conditions
493
+ */
494
+ type ToFieldRefs<T> = T extends object ? IsValueType<T> extends true ? FieldRef<string, T> : {
495
+ [K in keyof T]: FieldRef<string, T[K]>;
496
+ } : FieldRef<string, T>;
368
497
  /**
369
498
  * Type helper to build entity query type with navigation support
499
+ * Preserves class instances (Date, Map, Set, etc.) as-is without recursively mapping them
370
500
  */
371
501
  export type EntityQuery<TEntity extends DbEntity> = {
372
- [K in keyof TEntity]: TEntity[K] extends (infer U)[] | undefined ? U extends DbEntity ? EntityCollectionQuery<U> : TEntity[K] : TEntity[K] extends DbEntity | undefined ? EntityQuery<NonNullable<TEntity[K]>> : TEntity[K];
502
+ [K in keyof TEntity]: TEntity[K] extends (infer U)[] | undefined ? U extends DbEntity ? EntityCollectionQuery<U> : TEntity[K] : IsValueType<NonNullable<TEntity[K]>> extends true ? TEntity[K] : TEntity[K] extends DbEntity | undefined ? EntityQuery<NonNullable<TEntity[K]>> : TEntity[K];
373
503
  };
374
504
  /**
375
505
  * Collection query builder type for navigation collections
@@ -377,10 +507,10 @@ export type EntityQuery<TEntity extends DbEntity> = {
377
507
  export interface EntityCollectionQuery<TEntity extends DbEntity> {
378
508
  select<TSelection>(selector: (item: EntityQuery<TEntity>) => TSelection): EntityCollectionQueryWithSelect<TEntity, TSelection>;
379
509
  selectDistinct<TSelection>(selector: (item: EntityQuery<TEntity>) => TSelection): EntityCollectionQueryWithSelect<TEntity, TSelection>;
380
- where(condition: (item: EntityQuery<TEntity>) => any): this;
381
- orderBy(selector: (item: EntityQuery<TEntity>) => any): this;
382
- orderBy(selector: (item: EntityQuery<TEntity>) => any[]): this;
383
- orderBy(selector: (item: EntityQuery<TEntity>) => Array<[any, 'ASC' | 'DESC']>): this;
510
+ where(condition: (item: EntityQuery<TEntity>) => Condition): this;
511
+ orderBy<T>(selector: (item: EntityQuery<TEntity>) => T): this;
512
+ orderBy<T>(selector: (item: EntityQuery<TEntity>) => T[]): this;
513
+ orderBy<T>(selector: (item: EntityQuery<TEntity>) => Array<[T, OrderDirection]>): this;
384
514
  limit(count: number): this;
385
515
  offset(count: number): this;
386
516
  min<TSelection>(selector: (item: EntityQuery<TEntity>) => TSelection): SqlFragment<number | null>;
@@ -392,10 +522,10 @@ export interface EntityCollectionQuery<TEntity extends DbEntity> {
392
522
  toList(asName: string): TEntity[];
393
523
  }
394
524
  export interface EntityCollectionQueryWithSelect<TEntity extends DbEntity, TSelection> {
395
- where(condition: (item: EntityQuery<TEntity>) => any): this;
396
- orderBy(selector: (item: TSelection) => any): this;
397
- orderBy(selector: (item: TSelection) => any[]): this;
398
- orderBy(selector: (item: TSelection) => Array<[any, 'ASC' | 'DESC']>): this;
525
+ where(condition: (item: EntityQuery<TEntity>) => Condition): this;
526
+ orderBy<T>(selector: (item: TSelection) => T): this;
527
+ orderBy<T>(selector: (item: TSelection) => T[]): this;
528
+ orderBy<T>(selector: (item: TSelection) => Array<[T, OrderDirection]>): this;
399
529
  limit(count: number): this;
400
530
  offset(count: number): this;
401
531
  min(): Promise<TSelection | null>;
@@ -406,25 +536,101 @@ export interface EntityCollectionQueryWithSelect<TEntity extends DbEntity, TSele
406
536
  toStringList(asName?: string): string[];
407
537
  toList(asName: string): TSelection[];
408
538
  }
539
+ /**
540
+ * Interface for queryable entity collections that can be filtered with .where()
541
+ * Use this type when you need to store a query in a variable and add more .where() conditions.
542
+ *
543
+ * @example
544
+ * ```typescript
545
+ * let query: IEntityQueryable<User> = db.users;
546
+ * if (onlyActive) {
547
+ * query = query.where(u => eq(u.isActive, true));
548
+ * }
549
+ * if (minAge) {
550
+ * query = query.where(u => gte(u.age, minAge));
551
+ * }
552
+ * const results = await query.toList();
553
+ * ```
554
+ */
555
+ export interface IEntityQueryable<TEntity extends DbEntity> {
556
+ /**
557
+ * Add a WHERE condition. Multiple where() calls are chained with AND logic.
558
+ */
559
+ where(condition: (entity: EntityQuery<TEntity>) => Condition): IEntityQueryable<TEntity>;
560
+ /**
561
+ * Select specific fields from the entity
562
+ */
563
+ select<TSelection>(selector: (entity: EntityQuery<TEntity>) => TSelection): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TSelection>>;
564
+ /**
565
+ * Order by field(s)
566
+ */
567
+ orderBy<T>(selector: (row: EntityQuery<TEntity>) => T): IEntityQueryable<TEntity>;
568
+ orderBy<T>(selector: (row: EntityQuery<TEntity>) => T[]): IEntityQueryable<TEntity>;
569
+ orderBy<T>(selector: (row: EntityQuery<TEntity>) => Array<[T, OrderDirection]>): IEntityQueryable<TEntity>;
570
+ /**
571
+ * Limit results
572
+ */
573
+ limit(count: number): IEntityQueryable<TEntity>;
574
+ /**
575
+ * Offset results
576
+ */
577
+ offset(count: number): IEntityQueryable<TEntity>;
578
+ /**
579
+ * Add CTEs (Common Table Expressions) to the query
580
+ */
581
+ with(...ctes: import('../query/cte-builder').DbCte<any>[]): IEntityQueryable<TEntity>;
582
+ /**
583
+ * Left join with another table, CTE, or subquery
584
+ */
585
+ leftJoin<TRight extends DbEntity, TSelection>(rightTable: DbEntityTable<TRight>, condition: (left: EntityQuery<TEntity>, right: EntityQuery<TRight>) => Condition, selector: (left: EntityQuery<TEntity>, right: EntityQuery<TRight>) => TSelection, alias?: string): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TSelection>>;
586
+ leftJoin<TRight extends Record<string, any>, TSelection>(rightTable: import('../query/subquery').Subquery<TRight, 'table'>, condition: (left: EntityQuery<TEntity>, right: TRight) => Condition, selector: (left: EntityQuery<TEntity>, right: TRight) => TSelection, alias: string): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TSelection>>;
587
+ leftJoin<TRight extends Record<string, any>, TSelection>(rightTable: import('../query/cte-builder').DbCte<TRight>, condition: (left: EntityQuery<TEntity>, right: ToFieldRefs<TRight>) => Condition, selector: (left: EntityQuery<TEntity>, right: TRight) => TSelection): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TSelection>>;
588
+ /**
589
+ * Inner join with another table, CTE, or subquery
590
+ */
591
+ innerJoin<TRight extends DbEntity, TSelection>(rightTable: DbEntityTable<TRight>, condition: (left: EntityQuery<TEntity>, right: EntityQuery<TRight>) => Condition, selector: (left: EntityQuery<TEntity>, right: EntityQuery<TRight>) => TSelection, alias?: string): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TSelection>>;
592
+ innerJoin<TRight extends Record<string, any>, TSelection>(rightTable: import('../query/subquery').Subquery<TRight, 'table'>, condition: (left: EntityQuery<TEntity>, right: TRight) => Condition, selector: (left: EntityQuery<TEntity>, right: TRight) => TSelection, alias: string): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TSelection>>;
593
+ innerJoin<TRight extends Record<string, any>, TSelection>(rightTable: import('../query/cte-builder').DbCte<TRight>, condition: (left: EntityQuery<TEntity>, right: ToFieldRefs<TRight>) => Condition, selector: (left: EntityQuery<TEntity>, right: TRight) => TSelection): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TSelection>>;
594
+ /**
595
+ * Execute query and return all results
596
+ */
597
+ toList(): Promise<UnwrapDbColumns<TEntity>[]>;
598
+ /**
599
+ * Execute query and return first result
600
+ */
601
+ first(): Promise<UnwrapDbColumns<TEntity>>;
602
+ /**
603
+ * Execute query and return first result or null if not found
604
+ */
605
+ firstOrDefault(): Promise<UnwrapDbColumns<TEntity> | null>;
606
+ /**
607
+ * Count matching records
608
+ */
609
+ count(): Promise<number>;
610
+ }
409
611
  /**
410
612
  * Strongly-typed query builder for entities
411
- * Results automatically unwrap DbColumn<T> to T
613
+ * Results automatically unwrap DbColumn<T> to T and SqlFragment<T> to T
412
614
  */
413
615
  export interface EntitySelectQueryBuilder<TEntity extends DbEntity, TSelection> {
414
- select<TNewSelection>(selector: (entity: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection) => TNewSelection): EntitySelectQueryBuilder<TEntity, TNewSelection>;
415
- selectDistinct<TNewSelection>(selector: (entity: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection) => TNewSelection): EntitySelectQueryBuilder<TEntity, TNewSelection>;
416
- where(condition: (entity: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection) => any): EntitySelectQueryBuilder<TEntity, TSelection>;
417
- orderBy(selector: (row: TSelection) => any): EntitySelectQueryBuilder<TEntity, TSelection>;
418
- orderBy(selector: (row: TSelection) => any[]): EntitySelectQueryBuilder<TEntity, TSelection>;
419
- orderBy(selector: (row: TSelection) => Array<[any, 'ASC' | 'DESC']>): EntitySelectQueryBuilder<TEntity, TSelection>;
616
+ select<TNewSelection>(selector: (entity: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection) => TNewSelection): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TNewSelection>>;
617
+ selectDistinct<TNewSelection>(selector: (entity: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection) => TNewSelection): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TNewSelection>>;
618
+ where(condition: (entity: TSelection extends DbEntity ? EntityQuery<TSelection> : ToFieldRefs<TSelection>) => Condition): EntitySelectQueryBuilder<TEntity, TSelection>;
619
+ orderBy<T>(selector: (row: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection) => T): EntitySelectQueryBuilder<TEntity, TSelection>;
620
+ orderBy<T>(selector: (row: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection) => T[]): EntitySelectQueryBuilder<TEntity, TSelection>;
621
+ orderBy<T>(selector: (row: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection) => Array<[T, OrderDirection]>): EntitySelectQueryBuilder<TEntity, TSelection>;
420
622
  limit(count: number): EntitySelectQueryBuilder<TEntity, TSelection>;
421
623
  offset(count: number): EntitySelectQueryBuilder<TEntity, TSelection>;
422
624
  count(): Promise<number>;
423
625
  first(): Promise<ResolveCollectionResults<TSelection>>;
424
626
  firstOrDefault(): Promise<ResolveCollectionResults<TSelection> | null>;
425
627
  firstOrThrow(): Promise<ResolveCollectionResults<TSelection>>;
426
- leftJoin<TRight extends DbEntity | Record<string, any>, TNewSelection>(rightTable: DbEntityTable<TRight extends DbEntity ? TRight : never> | import('../query/subquery').Subquery<TRight, 'table'> | import('../query/cte-builder').DbCte<TRight>, condition: (left: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection, right: TRight extends DbEntity ? (EntityQuery<TRight> | TRight) : TRight) => Condition, selector: (left: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection, right: TRight extends DbEntity ? (EntityQuery<TRight> | TRight) : TRight) => TNewSelection, alias?: string): EntitySelectQueryBuilder<TEntity, TNewSelection>;
427
- innerJoin<TRight extends DbEntity | Record<string, any>, TNewSelection>(rightTable: DbEntityTable<TRight extends DbEntity ? TRight : never> | import('../query/subquery').Subquery<TRight, 'table'> | import('../query/cte-builder').DbCte<TRight>, condition: (left: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection, right: TRight extends DbEntity ? (EntityQuery<TRight> | TRight) : TRight) => Condition, selector: (left: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection, right: TRight extends DbEntity ? (EntityQuery<TRight> | TRight) : TRight) => TNewSelection, alias?: string): EntitySelectQueryBuilder<TEntity, TNewSelection>;
628
+ leftJoin<TRight extends Record<string, any>, TNewSelection>(rightTable: import('../query/cte-builder').DbCte<TRight>, condition: (left: TSelection extends DbEntity ? EntityQuery<TSelection> : ToFieldRefs<TSelection>, right: ToFieldRefs<TRight>) => Condition, selector: (left: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection, right: TRight) => TNewSelection): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TNewSelection>>;
629
+ leftJoin<TRight extends Record<string, any>, TNewSelection>(rightTable: import('../query/subquery').Subquery<TRight, 'table'>, condition: (left: TSelection extends DbEntity ? EntityQuery<TSelection> : ToFieldRefs<TSelection>, right: ToFieldRefs<TRight>) => Condition, selector: (left: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection, right: TRight) => TNewSelection, alias: string): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TNewSelection>>;
630
+ leftJoin<TRight extends DbEntity, TNewSelection>(rightTable: DbEntityTable<TRight>, condition: (left: TSelection extends DbEntity ? EntityQuery<TSelection> : ToFieldRefs<TSelection>, right: EntityQuery<TRight>) => Condition, selector: (left: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection, right: EntityQuery<TRight>) => TNewSelection, alias?: string): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TNewSelection>>;
631
+ innerJoin<TRight extends Record<string, any>, TNewSelection>(rightTable: import('../query/cte-builder').DbCte<TRight>, condition: (left: TSelection extends DbEntity ? EntityQuery<TSelection> : ToFieldRefs<TSelection>, right: ToFieldRefs<TRight>) => Condition, selector: (left: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection, right: TRight) => TNewSelection): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TNewSelection>>;
632
+ innerJoin<TRight extends Record<string, any>, TNewSelection>(rightTable: import('../query/subquery').Subquery<TRight, 'table'>, condition: (left: TSelection extends DbEntity ? EntityQuery<TSelection> : ToFieldRefs<TSelection>, right: ToFieldRefs<TRight>) => Condition, selector: (left: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection, right: TRight) => TNewSelection, alias: string): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TNewSelection>>;
633
+ innerJoin<TRight extends DbEntity, TNewSelection>(rightTable: DbEntityTable<TRight>, condition: (left: TSelection extends DbEntity ? EntityQuery<TSelection> : ToFieldRefs<TSelection>, right: EntityQuery<TRight>) => Condition, selector: (left: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection, right: EntityQuery<TRight>) => TNewSelection, alias?: string): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TNewSelection>>;
428
634
  groupBy<TGroupingKey>(selector: (entity: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection) => TGroupingKey): import('../query/grouped-query').GroupedQueryBuilder<TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection, TGroupingKey>;
429
635
  min<TResult = TSelection>(selector?: (entity: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection) => TResult): Promise<TResult | null>;
430
636
  max<TResult = TSelection>(selector?: (entity: TSelection extends DbEntity ? EntityQuery<TSelection> : TSelection) => TResult): Promise<TResult | null>;
@@ -514,6 +720,15 @@ export declare class DbEntityTable<TEntity extends DbEntity> {
514
720
  * Select all records - returns full entities with unwrapped DbColumns
515
721
  */
516
722
  toList(): Promise<UnwrapDbColumns<TEntity>[]>;
723
+ /**
724
+ * Get first record
725
+ * @throws Error if no records exist
726
+ */
727
+ first(): Promise<UnwrapDbColumns<TEntity>>;
728
+ /**
729
+ * Get first record or null if none exist
730
+ */
731
+ firstOrDefault(): Promise<UnwrapDbColumns<TEntity> | null>;
517
732
  /**
518
733
  * Count all records
519
734
  */
@@ -521,21 +736,22 @@ export declare class DbEntityTable<TEntity extends DbEntity> {
521
736
  /**
522
737
  * Order by field(s)
523
738
  */
524
- orderBy(selector: (row: TEntity) => any): EntitySelectQueryBuilder<TEntity, TEntity>;
525
- orderBy(selector: (row: TEntity) => any[]): EntitySelectQueryBuilder<TEntity, TEntity>;
526
- orderBy(selector: (row: TEntity) => Array<[any, 'ASC' | 'DESC']>): EntitySelectQueryBuilder<TEntity, TEntity>;
739
+ orderBy<T>(selector: (row: EntityQuery<TEntity>) => T): IEntityQueryable<TEntity>;
740
+ orderBy<T>(selector: (row: EntityQuery<TEntity>) => T[]): IEntityQueryable<TEntity>;
741
+ orderBy<T>(selector: (row: EntityQuery<TEntity>) => Array<[T, OrderDirection]>): IEntityQueryable<TEntity>;
527
742
  /**
528
743
  * Limit results
529
744
  */
530
- limit(count: number): EntitySelectQueryBuilder<TEntity, TEntity>;
745
+ limit(count: number): IEntityQueryable<TEntity>;
531
746
  /**
532
747
  * Offset results
533
748
  */
534
- offset(count: number): EntitySelectQueryBuilder<TEntity, TEntity>;
749
+ offset(count: number): IEntityQueryable<TEntity>;
535
750
  /**
536
751
  * Select query
752
+ * UnwrapSelection extracts the value types from SqlFragment<T> expressions
537
753
  */
538
- select<TSelection>(selector: (entity: EntityQuery<TEntity>) => TSelection): EntitySelectQueryBuilder<TEntity, TSelection>;
754
+ select<TSelection>(selector: (entity: EntityQuery<TEntity>) => TSelection): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TSelection>>;
539
755
  /**
540
756
  * Select distinct
541
757
  */
@@ -543,37 +759,133 @@ export declare class DbEntityTable<TEntity extends DbEntity> {
543
759
  /**
544
760
  * Where query - returns all columns by default
545
761
  */
546
- where(condition: (entity: EntityQuery<TEntity>) => any): EntitySelectQueryBuilder<TEntity, TEntity>;
762
+ where(condition: (entity: EntityQuery<TEntity>) => Condition): IEntityQueryable<TEntity>;
547
763
  /**
548
- * Left join with another table or subquery and selector
764
+ * Add CTEs (Common Table Expressions) to the query
549
765
  */
550
- leftJoin<TRight extends DbEntity, TSelection>(rightTable: DbEntityTable<TRight> | import('../query/subquery').Subquery<TRight, 'table'>, condition: (left: EntityQuery<TEntity>, right: EntityQuery<TRight> | TRight) => Condition, selector: (left: EntityQuery<TEntity>, right: EntityQuery<TRight> | TRight) => TSelection, alias?: string): EntitySelectQueryBuilder<TEntity, TSelection>;
766
+ with(...ctes: DbCte<any>[]): IEntityQueryable<TEntity>;
551
767
  /**
552
- * Inner join with another table or subquery and selector
768
+ * Left join with another table (DbEntity)
769
+ */
770
+ leftJoin<TRight extends DbEntity, TSelection>(rightTable: DbEntityTable<TRight>, condition: (left: EntityQuery<TEntity>, right: EntityQuery<TRight>) => Condition, selector: (left: EntityQuery<TEntity>, right: EntityQuery<TRight>) => TSelection, alias?: string): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TSelection>>;
771
+ /**
772
+ * Left join with a subquery (plain object result, not DbEntity)
773
+ */
774
+ leftJoin<TRight extends Record<string, any>, TSelection>(rightTable: import('../query/subquery').Subquery<TRight, 'table'>, condition: (left: EntityQuery<TEntity>, right: TRight) => Condition, selector: (left: EntityQuery<TEntity>, right: TRight) => TSelection, alias: string): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TSelection>>;
775
+ /**
776
+ * Left join with a CTE
777
+ */
778
+ leftJoin<TRight extends Record<string, any>, TSelection>(rightTable: import('../query/cte-builder').DbCte<TRight>, condition: (left: EntityQuery<TEntity>, right: ToFieldRefs<TRight>) => Condition, selector: (left: EntityQuery<TEntity>, right: TRight) => TSelection): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TSelection>>;
779
+ /**
780
+ * Inner join with another table (DbEntity)
553
781
  */
554
- innerJoin<TRight extends DbEntity, TSelection>(rightTable: DbEntityTable<TRight> | import('../query/subquery').Subquery<TRight, 'table'>, condition: (left: EntityQuery<TEntity>, right: EntityQuery<TRight> | TRight) => Condition, selector: (left: EntityQuery<TEntity>, right: EntityQuery<TRight> | TRight) => TSelection, alias?: string): EntitySelectQueryBuilder<TEntity, TSelection>;
782
+ innerJoin<TRight extends DbEntity, TSelection>(rightTable: DbEntityTable<TRight>, condition: (left: EntityQuery<TEntity>, right: EntityQuery<TRight>) => Condition, selector: (left: EntityQuery<TEntity>, right: EntityQuery<TRight>) => TSelection, alias?: string): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TSelection>>;
783
+ /**
784
+ * Inner join with a subquery (plain object result, not DbEntity)
785
+ */
786
+ innerJoin<TRight extends Record<string, any>, TSelection>(rightTable: import('../query/subquery').Subquery<TRight, 'table'>, condition: (left: EntityQuery<TEntity>, right: TRight) => Condition, selector: (left: EntityQuery<TEntity>, right: TRight) => TSelection, alias: string): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TSelection>>;
787
+ /**
788
+ * Inner join with a CTE
789
+ */
790
+ innerJoin<TRight extends Record<string, any>, TSelection>(rightTable: import('../query/cte-builder').DbCte<TRight>, condition: (left: EntityQuery<TEntity>, right: ToFieldRefs<TRight>) => Condition, selector: (left: EntityQuery<TEntity>, right: TRight) => TSelection): EntitySelectQueryBuilder<TEntity, UnwrapSelection<TSelection>>;
555
791
  /**
556
792
  * Insert - accepts only DbColumn properties (excludes navigation properties)
793
+ * Returns a fluent builder that can be awaited directly or chained with .returning()
794
+ *
795
+ * @example
796
+ * ```typescript
797
+ * // No returning (default) - returns void
798
+ * await db.users.insert({ username: 'alice', email: 'alice@test.com' });
799
+ *
800
+ * // With returning() - returns full entity
801
+ * const user = await db.users.insert({ username: 'alice' }).returning();
802
+ *
803
+ * // With returning(selector) - returns selected columns
804
+ * const { id } = await db.users.insert({ username: 'alice' }).returning(u => ({ id: u.id }));
805
+ * ```
557
806
  */
558
- insert(data: InsertData<TEntity>): Promise<UnwrapDbColumns<TEntity>>;
807
+ insert(data: InsertData<TEntity>): FluentInsert<TEntity>;
559
808
  /**
560
809
  * Insert multiple records
810
+ * Returns a fluent builder that can be awaited directly or chained with .returning()
811
+ *
812
+ * @example
813
+ * ```typescript
814
+ * // No returning (default) - returns void
815
+ * await db.users.insertMany([{ username: 'alice' }, { username: 'bob' }]);
816
+ *
817
+ * // With returning() - returns full entities
818
+ * const users = await db.users.insertMany([{ username: 'alice' }]).returning();
819
+ *
820
+ * // With returning(selector) - returns selected columns
821
+ * const results = await db.users.insertMany([{ username: 'alice' }]).returning(u => ({ id: u.id }));
822
+ * ```
561
823
  */
562
- insertMany(data: InsertData<TEntity>[]): Promise<UnwrapDbColumns<TEntity>[]>;
824
+ insertMany(data: InsertData<TEntity>[]): FluentInsertMany<TEntity>;
563
825
  /**
564
826
  * Upsert (insert or update on conflict)
827
+ * Returns a fluent builder that can be awaited directly or chained with .returning()
828
+ *
829
+ * @example
830
+ * ```typescript
831
+ * // No returning (default) - returns void
832
+ * await db.users.upsert([{ username: 'alice' }], { primaryKey: 'username' });
833
+ *
834
+ * // With returning() - returns full entities
835
+ * const users = await db.users.upsert([{ username: 'alice' }], { primaryKey: 'username' }).returning();
836
+ * ```
565
837
  */
566
- upsert(data: InsertData<TEntity>[], config?: EntityUpsertConfig<TEntity>): Promise<UnwrapDbColumns<TEntity>[]>;
838
+ upsert(data: InsertData<TEntity>[], config?: EntityUpsertConfig<TEntity>): FluentUpsert<TEntity>;
567
839
  /**
568
840
  * Bulk insert with advanced configuration
569
841
  * Supports automatic chunking for large datasets
842
+ * Returns a fluent builder that can be awaited directly or chained with .returning()
843
+ *
844
+ * @example
845
+ * ```typescript
846
+ * // No returning (default) - returns void
847
+ * await db.users.insertBulk([{ username: 'alice' }]);
848
+ *
849
+ * // With returning() - returns full entities
850
+ * const users = await db.users.insertBulk([{ username: 'alice' }]).returning();
851
+ *
852
+ * // With returning(selector) - returns selected columns
853
+ * const results = await db.users.insertBulk([{ username: 'alice' }]).returning(u => ({ id: u.id }));
854
+ *
855
+ * // With options
856
+ * await db.users.insertBulk([{ username: 'alice' }], { chunkSize: 100 });
857
+ * ```
570
858
  */
571
- insertBulk(value: InsertData<TEntity> | InsertData<TEntity>[], insertConfig?: InsertConfig): Promise<UnwrapDbColumns<TEntity>[]>;
859
+ insertBulk(value: InsertData<TEntity> | InsertData<TEntity>[], options?: InsertConfig): FluentInsertMany<TEntity>;
860
+ /**
861
+ * Execute a single bulk insert batch
862
+ * @internal
863
+ */
864
+ private insertBulkSingle;
572
865
  /**
573
866
  * Upsert with advanced configuration
574
867
  * Auto-detects primary keys and supports chunking
868
+ * Returns a fluent builder that can be awaited directly or chained with .returning()
869
+ *
870
+ * @example
871
+ * ```typescript
872
+ * // No returning (default) - returns void
873
+ * await db.users.upsertBulk([{ id: 1, username: 'alice' }], { primaryKey: 'id' });
874
+ *
875
+ * // With returning() - returns full entities
876
+ * const users = await db.users.upsertBulk([{ id: 1, username: 'alice' }]).returning();
877
+ *
878
+ * // With returning(selector) - returns selected columns
879
+ * const results = await db.users.upsertBulk([{ id: 1, username: 'alice' }])
880
+ * .returning(u => ({ id: u.id }));
881
+ * ```
575
882
  */
576
- upsertBulk(values: InsertData<TEntity>[], config?: EntityUpsertConfig<TEntity>): Promise<UnwrapDbColumns<TEntity>[]>;
883
+ upsertBulk(values: InsertData<TEntity>[], config?: EntityUpsertConfig<TEntity>): FluentUpsert<TEntity>;
884
+ /**
885
+ * Execute a single upsert batch
886
+ * @internal
887
+ */
888
+ private upsertBulkSingle;
577
889
  /**
578
890
  * Map database column names back to property names
579
891
  */
@@ -592,9 +904,65 @@ export declare class DbEntityTable<TEntity extends DbEntity> {
592
904
  values(data: InsertData<TEntity> | InsertData<TEntity>[]): EntityInsertBuilder<TEntity>;
593
905
  /**
594
906
  * Update records matching condition
595
- * Usage: db.users.update({ age: 30 }, u => eq(u.id, 1))
907
+ * Returns a fluent builder that can be awaited directly or chained with .returning()
908
+ *
909
+ * @example
910
+ * ```typescript
911
+ * // No returning (default) - returns void
912
+ * await db.users.update({ age: 30 }, u => eq(u.id, 1));
913
+ *
914
+ * // With returning() - returns full entities
915
+ * const users = await db.users.update({ age: 30 }, u => eq(u.id, 1)).returning();
916
+ *
917
+ * // With returning(selector) - returns selected columns
918
+ * const results = await db.users.update({ age: 30 }, u => eq(u.id, 1))
919
+ * .returning(u => ({ id: u.id, age: u.age }));
920
+ * ```
596
921
  */
597
- update(data: Partial<InsertData<TEntity>>, condition: (entity: EntityQuery<TEntity>) => Condition): Promise<UnwrapDbColumns<TEntity>[]>;
922
+ update(data: Partial<InsertData<TEntity>>, condition: (entity: EntityQuery<TEntity>) => Condition): FluentUpdate<TEntity>;
923
+ /**
924
+ * Bulk update multiple records efficiently using PostgreSQL VALUES clause
925
+ * Updates records matching primary key(s) with provided data
926
+ * Returns a fluent builder that can be awaited directly or chained with .returning()
927
+ *
928
+ * @param data Array of objects with primary key(s) and columns to update
929
+ * @param config Optional configuration for the bulk update
930
+ *
931
+ * @example
932
+ * ```typescript
933
+ * // No returning (default) - returns void
934
+ * await db.users.bulkUpdate([
935
+ * { id: 1, age: 30 },
936
+ * { id: 2, age: 25 },
937
+ * ]);
938
+ *
939
+ * // With returning() - returns full entities
940
+ * const updated = await db.users.bulkUpdate([{ id: 1, age: 30 }]).returning();
941
+ *
942
+ * // With returning(selector) - returns selected columns
943
+ * const results = await db.users.bulkUpdate([{ id: 1, age: 30 }])
944
+ * .returning(u => ({ id: u.id, age: u.age }));
945
+ *
946
+ * // With custom primary key
947
+ * await db.users.bulkUpdate(
948
+ * [{ username: 'alice', age: 31 }],
949
+ * { primaryKey: 'username' }
950
+ * );
951
+ * ```
952
+ */
953
+ bulkUpdate(data: Array<Partial<InsertData<TEntity>> & Record<string, any>>, config?: {
954
+ /** Primary key column(s) to match records. Auto-detected if not specified */
955
+ primaryKey?: string | string[];
956
+ /** Chunk size for large batches. Auto-calculated if not specified */
957
+ chunkSize?: number;
958
+ }): FluentBulkUpdate<TEntity>;
959
+ /** Static type map for PostgreSQL type casting - computed once */
960
+ private static readonly PG_TYPE_MAP;
961
+ /**
962
+ * Execute a single bulk update batch
963
+ * @internal
964
+ */
965
+ private bulkUpdateSingle;
598
966
  /**
599
967
  * Delete records matching condition
600
968
  * Usage: db.users.delete(u => eq(u.id, 1))
@@ -604,6 +972,16 @@ export declare class DbEntityTable<TEntity extends DbEntity> {
604
972
  * Create a mock entity for type inference in lambdas
605
973
  */
606
974
  private createMockEntity;
975
+ /**
976
+ * Build RETURNING clause SQL based on config
977
+ * @internal
978
+ */
979
+ private buildReturningClause;
980
+ /**
981
+ * Map row results based on returning config
982
+ * @internal
983
+ */
984
+ private mapReturningResults;
607
985
  }
608
986
  /**
609
987
  * Base database context with entity-first approach
@@ -680,4 +1058,5 @@ export declare abstract class DatabaseContext extends DataContext {
680
1058
  */
681
1059
  protected table<TEntity extends DbEntity>(entityClass: EntityConstructor<TEntity>): DbEntityTable<TEntity>;
682
1060
  }
1061
+ export {};
683
1062
  //# sourceMappingURL=db-context.d.ts.map