@mikro-orm/sql 7.0.2-dev.9 → 7.0.2

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 (87) hide show
  1. package/AbstractSqlConnection.d.ts +95 -47
  2. package/AbstractSqlConnection.js +240 -232
  3. package/AbstractSqlDriver.d.ts +412 -155
  4. package/AbstractSqlDriver.js +2062 -1937
  5. package/AbstractSqlPlatform.d.ts +84 -73
  6. package/AbstractSqlPlatform.js +163 -158
  7. package/PivotCollectionPersister.d.ts +33 -15
  8. package/PivotCollectionPersister.js +158 -160
  9. package/README.md +128 -294
  10. package/SqlEntityManager.d.ts +68 -20
  11. package/SqlEntityManager.js +54 -37
  12. package/SqlEntityRepository.d.ts +15 -14
  13. package/SqlEntityRepository.js +24 -23
  14. package/dialects/mssql/MsSqlNativeQueryBuilder.d.ts +12 -12
  15. package/dialects/mssql/MsSqlNativeQueryBuilder.js +192 -194
  16. package/dialects/mysql/BaseMySqlPlatform.d.ts +64 -45
  17. package/dialects/mysql/BaseMySqlPlatform.js +134 -131
  18. package/dialects/mysql/MySqlExceptionConverter.d.ts +6 -6
  19. package/dialects/mysql/MySqlExceptionConverter.js +91 -77
  20. package/dialects/mysql/MySqlNativeQueryBuilder.d.ts +3 -3
  21. package/dialects/mysql/MySqlNativeQueryBuilder.js +66 -69
  22. package/dialects/mysql/MySqlSchemaHelper.d.ts +39 -39
  23. package/dialects/mysql/MySqlSchemaHelper.js +327 -319
  24. package/dialects/oracledb/OracleDialect.d.ts +81 -52
  25. package/dialects/oracledb/OracleDialect.js +155 -149
  26. package/dialects/oracledb/OracleNativeQueryBuilder.d.ts +12 -12
  27. package/dialects/oracledb/OracleNativeQueryBuilder.js +232 -236
  28. package/dialects/postgresql/BasePostgreSqlPlatform.d.ts +108 -105
  29. package/dialects/postgresql/BasePostgreSqlPlatform.js +351 -350
  30. package/dialects/postgresql/FullTextType.d.ts +10 -6
  31. package/dialects/postgresql/FullTextType.js +51 -51
  32. package/dialects/postgresql/PostgreSqlExceptionConverter.d.ts +5 -5
  33. package/dialects/postgresql/PostgreSqlExceptionConverter.js +55 -43
  34. package/dialects/postgresql/PostgreSqlNativeQueryBuilder.d.ts +1 -1
  35. package/dialects/postgresql/PostgreSqlNativeQueryBuilder.js +4 -4
  36. package/dialects/postgresql/PostgreSqlSchemaHelper.d.ts +102 -82
  37. package/dialects/postgresql/PostgreSqlSchemaHelper.js +711 -683
  38. package/dialects/sqlite/BaseSqliteConnection.d.ts +3 -5
  39. package/dialects/sqlite/BaseSqliteConnection.js +21 -19
  40. package/dialects/sqlite/NodeSqliteDialect.d.ts +1 -1
  41. package/dialects/sqlite/NodeSqliteDialect.js +23 -23
  42. package/dialects/sqlite/SqliteDriver.d.ts +1 -1
  43. package/dialects/sqlite/SqliteDriver.js +3 -3
  44. package/dialects/sqlite/SqliteExceptionConverter.d.ts +6 -6
  45. package/dialects/sqlite/SqliteExceptionConverter.js +67 -51
  46. package/dialects/sqlite/SqliteNativeQueryBuilder.d.ts +2 -2
  47. package/dialects/sqlite/SqliteNativeQueryBuilder.js +7 -7
  48. package/dialects/sqlite/SqlitePlatform.d.ts +63 -72
  49. package/dialects/sqlite/SqlitePlatform.js +139 -139
  50. package/dialects/sqlite/SqliteSchemaHelper.d.ts +70 -60
  51. package/dialects/sqlite/SqliteSchemaHelper.js +533 -520
  52. package/package.json +4 -4
  53. package/plugin/index.d.ts +44 -35
  54. package/plugin/index.js +44 -36
  55. package/plugin/transformer.d.ts +117 -94
  56. package/plugin/transformer.js +890 -881
  57. package/query/ArrayCriteriaNode.d.ts +4 -4
  58. package/query/ArrayCriteriaNode.js +18 -18
  59. package/query/CriteriaNode.d.ts +35 -25
  60. package/query/CriteriaNode.js +133 -123
  61. package/query/CriteriaNodeFactory.d.ts +49 -6
  62. package/query/CriteriaNodeFactory.js +97 -94
  63. package/query/NativeQueryBuilder.d.ts +120 -117
  64. package/query/NativeQueryBuilder.js +484 -480
  65. package/query/ObjectCriteriaNode.d.ts +12 -12
  66. package/query/ObjectCriteriaNode.js +298 -282
  67. package/query/QueryBuilder.d.ts +1546 -904
  68. package/query/QueryBuilder.js +2270 -2145
  69. package/query/QueryBuilderHelper.d.ts +153 -72
  70. package/query/QueryBuilderHelper.js +1079 -1028
  71. package/query/ScalarCriteriaNode.d.ts +3 -3
  72. package/query/ScalarCriteriaNode.js +53 -46
  73. package/query/enums.d.ts +16 -14
  74. package/query/enums.js +16 -14
  75. package/query/raw.d.ts +16 -6
  76. package/query/raw.js +10 -10
  77. package/schema/DatabaseSchema.d.ts +73 -50
  78. package/schema/DatabaseSchema.js +331 -307
  79. package/schema/DatabaseTable.d.ts +96 -73
  80. package/schema/DatabaseTable.js +1012 -927
  81. package/schema/SchemaComparator.d.ts +58 -54
  82. package/schema/SchemaComparator.js +745 -719
  83. package/schema/SchemaHelper.d.ts +110 -80
  84. package/schema/SchemaHelper.js +676 -645
  85. package/schema/SqlSchemaGenerator.d.ts +79 -58
  86. package/schema/SqlSchemaGenerator.js +536 -501
  87. package/typings.d.ts +380 -266
@@ -1,4 +1,44 @@
1
- import { type AnyEntity, type AutoPath, type Collection, type ConnectionType, type Dictionary, type EntityData, type EntityDTOFlat, type EntityDTOProp, type EntityKey, type EntityManager, EntityMetadata, type EntityName, type EntityProperty, type ExpandProperty, type FilterObject, type FilterOptions, type FilterValue, type FlushMode, type GroupOperator, type Loaded, LockMode, type LoggingOptions, type MetadataStorage, type PrimaryProperty, type ObjectQuery, PopulateHint, type PopulateOptions, type PopulatePath, QueryFlag, type QueryOrderKeysFlat, type QueryOrderMap, type QueryResult, RawQueryFragment, type Raw, type RequiredEntityData, type Scalar, type SerializeDTO, type Subquery, type Transaction } from '@mikro-orm/core';
1
+ import {
2
+ type AnyEntity,
3
+ type AutoPath,
4
+ type Collection,
5
+ type ConnectionType,
6
+ type Dictionary,
7
+ type EntityData,
8
+ type EntityDTOFlat,
9
+ type EntityDTOProp,
10
+ type EntityKey,
11
+ type EntityManager,
12
+ EntityMetadata,
13
+ type EntityName,
14
+ type EntityProperty,
15
+ type ExpandProperty,
16
+ type FilterObject,
17
+ type FilterOptions,
18
+ type FilterValue,
19
+ type FlushMode,
20
+ type GroupOperator,
21
+ type Loaded,
22
+ LockMode,
23
+ type LoggingOptions,
24
+ type MetadataStorage,
25
+ type PrimaryProperty,
26
+ type ObjectQuery,
27
+ PopulateHint,
28
+ type PopulateOptions,
29
+ type PopulatePath,
30
+ QueryFlag,
31
+ type QueryOrderKeysFlat,
32
+ type QueryOrderMap,
33
+ type QueryResult,
34
+ RawQueryFragment,
35
+ type Raw,
36
+ type RequiredEntityData,
37
+ type Scalar,
38
+ type SerializeDTO,
39
+ type Subquery,
40
+ type Transaction,
41
+ } from '@mikro-orm/core';
2
42
  import { JoinType, QueryType } from './enums.js';
3
43
  import type { AbstractSqlDriver } from '../AbstractSqlDriver.js';
4
44
  import { type Alias, type OnConflictClause, QueryBuilderHelper } from './QueryBuilderHelper.js';
@@ -7,32 +47,32 @@ import type { ICriteriaNodeProcessOptions, InternalField, JoinOptions } from '..
7
47
  import type { AbstractSqlPlatform } from '../AbstractSqlPlatform.js';
8
48
  import { type CteOptions, NativeQueryBuilder } from './NativeQueryBuilder.js';
9
49
  export interface ExecuteOptions {
10
- mapResults?: boolean;
11
- mergeResults?: boolean;
50
+ mapResults?: boolean;
51
+ mergeResults?: boolean;
12
52
  }
13
53
  export interface QBStreamOptions {
14
- /**
15
- * Results are mapped to entities, if you set `mapResults: false` you will get POJOs instead.
16
- *
17
- * @default true
18
- */
19
- mapResults?: boolean;
20
- /**
21
- * When populating to-many relations, the ORM streams fully merged entities instead of yielding every row.
22
- * You can opt out of this behavior by specifying `mergeResults: false`. This will yield every row from
23
- * the SQL result, but still mapped to entities, meaning that to-many collections will contain at most
24
- * one item, and you will get duplicate root entities when they have multiple items in the populated
25
- * collection.
26
- *
27
- * @default true
28
- */
29
- mergeResults?: boolean;
30
- /**
31
- * When enabled, the driver will return the raw database results without renaming the fields to match the entity property names.
32
- *
33
- * @default false
34
- */
35
- rawResults?: boolean;
54
+ /**
55
+ * Results are mapped to entities, if you set `mapResults: false` you will get POJOs instead.
56
+ *
57
+ * @default true
58
+ */
59
+ mapResults?: boolean;
60
+ /**
61
+ * When populating to-many relations, the ORM streams fully merged entities instead of yielding every row.
62
+ * You can opt out of this behavior by specifying `mergeResults: false`. This will yield every row from
63
+ * the SQL result, but still mapped to entities, meaning that to-many collections will contain at most
64
+ * one item, and you will get duplicate root entities when they have multiple items in the populated
65
+ * collection.
66
+ *
67
+ * @default true
68
+ */
69
+ mergeResults?: boolean;
70
+ /**
71
+ * When enabled, the driver will return the raw database results without renaming the fields to match the entity property names.
72
+ *
73
+ * @default false
74
+ */
75
+ rawResults?: boolean;
36
76
  }
37
77
  type IsNever<T, True = true, False = false> = [T] extends [never] ? True : False;
38
78
  type GetAlias<T extends string> = T extends `${infer A}.${string}` ? A : never;
@@ -49,146 +89,315 @@ type AppendToHint<Parent extends string, Child extends string> = `${Parent}.${Ch
49
89
  * { b: ['books', 'b', Book, false] }
50
90
  */
51
91
  type AddToContext<Type extends object, Context, Field extends string, Alias extends string, Select extends boolean> = {
52
- [K in Alias]: [GetPath<Context, Field>, K, ExpandProperty<Type[GetPropName<Field> & keyof Type]>, Select];
92
+ [K in Alias]: [GetPath<Context, Field>, K, ExpandProperty<Type[GetPropName<Field> & keyof Type]>, Select];
53
93
  };
54
- type GetPath<Context, Field extends string> = GetAlias<Field> extends infer Alias ? IsNever<Alias> extends true ? GetPropName<Field> : Alias extends keyof Context ? Context[Alias] extends [infer Path, ...any[]] ? AppendToHint<Path & string, GetPropName<Field>> : GetPropName<Field> : GetPropName<Field> : GetPropName<Field>;
55
- type GetType<Type extends object, Context, Field extends string> = GetAlias<Field> extends infer Alias ? IsNever<Alias> extends true ? Type : [Context] extends [never] ? Type : Alias extends keyof Context ? Context[Alias] extends [string, string, infer PropType, any] ? PropType & object : Type : Type : Type;
56
- type AddToHint<RootAlias, Context, Field extends string, Select extends boolean = false> = Select extends true ? GetAlias<Field> extends infer Alias ? IsNever<Alias> extends true ? GetPropName<Field> : Alias extends RootAlias ? GetPropName<Field> : Alias extends keyof Context ? Context[Alias] extends [infer Path, ...any[]] ? AppendToHint<Path & string, GetPropName<Field>> : GetPropName<Field> : GetPropName<Field> : GetPropName<Field> : never;
57
- export type ModifyHint<RootAlias, Context, Hint extends string, Field extends string, Select extends boolean = false> = Hint | AddToHint<RootAlias, Context, Field, Select>;
58
- export type ModifyContext<Entity extends object, Context, Field extends string, Alias extends string, Select extends boolean = false> = IsNever<Context> extends true ? AddToContext<GetType<Entity, object, Field>, object, Field, Alias, Select> : Context & AddToContext<GetType<Entity, Context, Field>, Context, Field, Alias, Select>;
59
- type StripRootAlias<F extends string, RootAlias extends string, Context = never> = F extends `${RootAlias}.${infer Field}` ? Field : F extends `${infer Alias}.${string}` ? Alias extends AliasNames<Context> ? never : F : F;
94
+ type GetPath<Context, Field extends string> =
95
+ GetAlias<Field> extends infer Alias
96
+ ? IsNever<Alias> extends true
97
+ ? GetPropName<Field>
98
+ : Alias extends keyof Context
99
+ ? Context[Alias] extends [infer Path, ...any[]]
100
+ ? AppendToHint<Path & string, GetPropName<Field>>
101
+ : GetPropName<Field>
102
+ : GetPropName<Field>
103
+ : GetPropName<Field>;
104
+ type GetType<Type extends object, Context, Field extends string> =
105
+ GetAlias<Field> extends infer Alias
106
+ ? IsNever<Alias> extends true
107
+ ? Type
108
+ : [Context] extends [never]
109
+ ? Type
110
+ : Alias extends keyof Context
111
+ ? Context[Alias] extends [string, string, infer PropType, any]
112
+ ? PropType & object
113
+ : Type
114
+ : Type
115
+ : Type;
116
+ type AddToHint<RootAlias, Context, Field extends string, Select extends boolean = false> = Select extends true
117
+ ? GetAlias<Field> extends infer Alias
118
+ ? IsNever<Alias> extends true
119
+ ? GetPropName<Field>
120
+ : Alias extends RootAlias
121
+ ? GetPropName<Field>
122
+ : Alias extends keyof Context
123
+ ? Context[Alias] extends [infer Path, ...any[]]
124
+ ? AppendToHint<Path & string, GetPropName<Field>>
125
+ : GetPropName<Field>
126
+ : GetPropName<Field>
127
+ : GetPropName<Field>
128
+ : never;
129
+ export type ModifyHint<RootAlias, Context, Hint extends string, Field extends string, Select extends boolean = false> =
130
+ | Hint
131
+ | AddToHint<RootAlias, Context, Field, Select>;
132
+ export type ModifyContext<
133
+ Entity extends object,
134
+ Context,
135
+ Field extends string,
136
+ Alias extends string,
137
+ Select extends boolean = false,
138
+ > =
139
+ IsNever<Context> extends true
140
+ ? AddToContext<GetType<Entity, object, Field>, object, Field, Alias, Select>
141
+ : Context & AddToContext<GetType<Entity, Context, Field>, Context, Field, Alias, Select>;
142
+ type StripRootAlias<
143
+ F extends string,
144
+ RootAlias extends string,
145
+ Context = never,
146
+ > = F extends `${RootAlias}.${infer Field}`
147
+ ? Field
148
+ : F extends `${infer Alias}.${string}`
149
+ ? Alias extends AliasNames<Context>
150
+ ? never
151
+ : F
152
+ : F;
60
153
  type StripFieldAlias<F extends string> = F extends `${infer Path} as ${string}` ? Path : F;
61
- type ExtractRootFields<Fields, RootAlias extends string, Context = never> = [Fields] extends ['*'] ? '*' : Fields extends `${RootAlias}.*` ? '*' : Fields extends string ? StripRootAlias<StripFieldAlias<Fields>, RootAlias, Context> : never;
154
+ type ExtractRootFields<Fields, RootAlias extends string, Context = never> = [Fields] extends ['*']
155
+ ? '*'
156
+ : Fields extends `${RootAlias}.*`
157
+ ? '*'
158
+ : Fields extends string
159
+ ? StripRootAlias<StripFieldAlias<Fields>, RootAlias, Context>
160
+ : never;
62
161
  type PrefixWithPath<Path extends string, Field extends string> = `${Path}.${Field}`;
63
162
  type StripJoinAlias<F extends string, Alias extends string> = F extends `${Alias}.${infer Field}` ? Field : F;
64
- export type JoinSelectField<JoinedEntity, Alias extends string> = (keyof JoinedEntity & string) | `${Alias}.${keyof JoinedEntity & string}`;
65
- type AddJoinFields<RootAlias, Context, Field extends string, Alias extends string, JoinFields extends readonly string[]> = JoinFields extends readonly (infer F)[] ? F extends string ? PrefixWithPath<AddToHint<RootAlias, Context, Field, true> & string, StripJoinAlias<F, Alias>> : never : never;
66
- export type ModifyFields<CurrentFields extends string, RootAlias, Context, Field extends string, Alias extends string, JoinFields extends readonly string[] | undefined> = JoinFields extends readonly string[] ? CurrentFields | AddJoinFields<RootAlias, Context, Field, Alias, JoinFields> : CurrentFields;
163
+ export type JoinSelectField<JoinedEntity, Alias extends string> =
164
+ | (keyof JoinedEntity & string)
165
+ | `${Alias}.${keyof JoinedEntity & string}`;
166
+ type AddJoinFields<
167
+ RootAlias,
168
+ Context,
169
+ Field extends string,
170
+ Alias extends string,
171
+ JoinFields extends readonly string[],
172
+ > = JoinFields extends readonly (infer F)[]
173
+ ? F extends string
174
+ ? PrefixWithPath<AddToHint<RootAlias, Context, Field, true> & string, StripJoinAlias<F, Alias>>
175
+ : never
176
+ : never;
177
+ export type ModifyFields<
178
+ CurrentFields extends string,
179
+ RootAlias,
180
+ Context,
181
+ Field extends string,
182
+ Alias extends string,
183
+ JoinFields extends readonly string[] | undefined,
184
+ > = JoinFields extends readonly string[]
185
+ ? CurrentFields | AddJoinFields<RootAlias, Context, Field, Alias, JoinFields>
186
+ : CurrentFields;
67
187
  type EntityRelations<T> = EntityKey<T, true>;
68
- type JoinedEntityType<Entity extends object, Context, Field extends string> = ExpandProperty<GetType<Entity, Context, Field>[GetPropName<Field> & keyof GetType<Entity, Context, Field>]>;
69
- type AliasNames<Context> = Context[keyof Context] extends infer Join ? Join extends any ? Join extends [string, infer Alias, any, any] ? Alias & string : never : never : never;
70
- type ContextRelationKeys<Context> = Context[keyof Context] extends infer Join ? Join extends any ? Join extends [string, infer Alias, infer Type, any] ? `${Alias & string}.${EntityRelations<Type & object>}` : never : never : never;
71
- export type QBField<Entity, RootAlias extends string, Context> = EntityRelations<Entity> | `${RootAlias}.${EntityRelations<Entity>}` | ([Context] extends [never] ? never : ContextRelationKeys<Context>);
72
- type ContextFieldKeys<Context> = Context[keyof Context] extends infer Join ? Join extends any ? Join extends [string, infer Alias, infer Type, any] ? `${Alias & string}.${keyof Type & string}` : never : never : never;
188
+ type JoinedEntityType<Entity extends object, Context, Field extends string> = ExpandProperty<
189
+ GetType<Entity, Context, Field>[GetPropName<Field> & keyof GetType<Entity, Context, Field>]
190
+ >;
191
+ type AliasNames<Context> = Context[keyof Context] extends infer Join
192
+ ? Join extends any
193
+ ? Join extends [string, infer Alias, any, any]
194
+ ? Alias & string
195
+ : never
196
+ : never
197
+ : never;
198
+ type ContextRelationKeys<Context> = Context[keyof Context] extends infer Join
199
+ ? Join extends any
200
+ ? Join extends [string, infer Alias, infer Type, any]
201
+ ? `${Alias & string}.${EntityRelations<Type & object>}`
202
+ : never
203
+ : never
204
+ : never;
205
+ export type QBField<Entity, RootAlias extends string, Context> =
206
+ | EntityRelations<Entity>
207
+ | `${RootAlias}.${EntityRelations<Entity>}`
208
+ | ([Context] extends [never] ? never : ContextRelationKeys<Context>);
209
+ type ContextFieldKeys<Context> = Context[keyof Context] extends infer Join
210
+ ? Join extends any
211
+ ? Join extends [string, infer Alias, infer Type, any]
212
+ ? `${Alias & string}.${keyof Type & string}`
213
+ : never
214
+ : never
215
+ : never;
73
216
  type WithAlias<T extends string> = T | `${T} as ${string}`;
74
- export type Field<Entity, RootAlias extends string = never, Context = never> = WithAlias<EntityKey<Entity>> | (IsNever<RootAlias> extends true ? never : WithAlias<`${RootAlias}.${EntityKey<Entity>}`> | `${RootAlias}.*`) | ([Context] extends [never] ? never : WithAlias<ContextFieldKeys<Context>> | `${AliasNames<Context>}.*`) | '*' | QueryBuilder<any> | NativeQueryBuilder | RawQueryFragment<any> | (RawQueryFragment & symbol);
217
+ export type Field<Entity, RootAlias extends string = never, Context = never> =
218
+ | WithAlias<EntityKey<Entity>>
219
+ | (IsNever<RootAlias> extends true ? never : WithAlias<`${RootAlias}.${EntityKey<Entity>}`> | `${RootAlias}.*`)
220
+ | ([Context] extends [never] ? never : WithAlias<ContextFieldKeys<Context>> | `${AliasNames<Context>}.*`)
221
+ | '*'
222
+ | QueryBuilder<any>
223
+ | NativeQueryBuilder
224
+ | RawQueryFragment<any>
225
+ | (RawQueryFragment & symbol);
75
226
  type RootAliasOrderKeys<RootAlias extends string, Entity> = {
76
- [K in `${RootAlias}.${EntityKey<Entity>}`]?: QueryOrderKeysFlat;
227
+ [K in `${RootAlias}.${EntityKey<Entity>}`]?: QueryOrderKeysFlat;
77
228
  };
78
229
  type ContextOrderKeys<Context> = {
79
- [K in ContextFieldKeys<Context>]?: QueryOrderKeysFlat;
230
+ [K in ContextFieldKeys<Context>]?: QueryOrderKeysFlat;
80
231
  };
81
232
  type RawOrderKeys<RawAliases extends string> = {
82
- [K in RawAliases]?: QueryOrderKeysFlat;
233
+ [K in RawAliases]?: QueryOrderKeysFlat;
83
234
  };
84
- export type ContextOrderByMap<Entity, RootAlias extends string = never, Context = never, RawAliases extends string = never> = QueryOrderMap<Entity> | ((IsNever<RootAlias> extends true ? {} : RootAliasOrderKeys<RootAlias, Entity>) & ([Context] extends [never] ? {} : ContextOrderKeys<Context>) & (IsNever<RawAliases> extends true ? {} : string extends RawAliases ? {} : RawOrderKeys<RawAliases>));
85
- type AliasedPath<Alias extends string, Type, P extends string> = P extends `${Alias}.*` ? P : P extends `${Alias}.${infer Rest}` ? `${Alias}.${AutoPath<Type & object, Rest, `${PopulatePath.ALL}`>}` : never;
86
- type ContextAliasedPath<Context, P extends string> = Context[keyof Context] extends infer Join ? Join extends any ? Join extends [string, infer Alias, infer Type, any] ? AliasedPath<Alias & string, Type, P> : never : never : never;
87
- type NestedAutoPath<Entity, RootAlias extends string, Context, P extends string> = P extends `${string}:ref` ? never : P extends `${infer Path} as ${string}` ? AliasedPath<RootAlias, Entity, Path> | ContextAliasedPath<Context, Path> | AutoPath<Entity, Path, `${PopulatePath.ALL}`> extends never ? never : P : AliasedPath<RootAlias, Entity, P> | ContextAliasedPath<Context, P> | AutoPath<Entity, P, `${PopulatePath.ALL}`>;
235
+ export type ContextOrderByMap<
236
+ Entity,
237
+ RootAlias extends string = never,
238
+ Context = never,
239
+ RawAliases extends string = never,
240
+ > =
241
+ | QueryOrderMap<Entity>
242
+ | ((IsNever<RootAlias> extends true ? {} : RootAliasOrderKeys<RootAlias, Entity>) &
243
+ ([Context] extends [never] ? {} : ContextOrderKeys<Context>) &
244
+ (IsNever<RawAliases> extends true ? {} : string extends RawAliases ? {} : RawOrderKeys<RawAliases>));
245
+ type AliasedPath<Alias extends string, Type, P extends string> = P extends `${Alias}.*`
246
+ ? P
247
+ : P extends `${Alias}.${infer Rest}`
248
+ ? `${Alias}.${AutoPath<Type & object, Rest, `${PopulatePath.ALL}`>}`
249
+ : never;
250
+ type ContextAliasedPath<Context, P extends string> = Context[keyof Context] extends infer Join
251
+ ? Join extends any
252
+ ? Join extends [string, infer Alias, infer Type, any]
253
+ ? AliasedPath<Alias & string, Type, P>
254
+ : never
255
+ : never
256
+ : never;
257
+ type NestedAutoPath<Entity, RootAlias extends string, Context, P extends string> = P extends `${string}:ref`
258
+ ? never
259
+ : P extends `${infer Path} as ${string}`
260
+ ?
261
+ | AliasedPath<RootAlias, Entity, Path>
262
+ | ContextAliasedPath<Context, Path>
263
+ | AutoPath<Entity, Path, `${PopulatePath.ALL}`> extends never
264
+ ? never
265
+ : P
266
+ : AliasedPath<RootAlias, Entity, P> | ContextAliasedPath<Context, P> | AutoPath<Entity, P, `${PopulatePath.ALL}`>;
88
267
  type AliasedObjectQuery<Entity extends object, Alias extends string> = {
89
- [K in EntityKey<Entity> as `${Alias}.${K}`]?: ObjectQuery<Entity>[K];
268
+ [K in EntityKey<Entity> as `${Alias}.${K}`]?: ObjectQuery<Entity>[K];
90
269
  };
91
- type JoinCondition<JoinedEntity extends object, Alias extends string> = (ObjectQuery<JoinedEntity> | AliasedObjectQuery<JoinedEntity, Alias>) & {
92
- $not?: JoinCondition<JoinedEntity, Alias>;
93
- $or?: JoinCondition<JoinedEntity, Alias>[];
94
- $and?: JoinCondition<JoinedEntity, Alias>[];
270
+ type JoinCondition<JoinedEntity extends object, Alias extends string> = (
271
+ | ObjectQuery<JoinedEntity>
272
+ | AliasedObjectQuery<JoinedEntity, Alias>
273
+ ) & {
274
+ $not?: JoinCondition<JoinedEntity, Alias>;
275
+ $or?: JoinCondition<JoinedEntity, Alias>[];
276
+ $and?: JoinCondition<JoinedEntity, Alias>[];
95
277
  };
96
278
  type RawJoinCondition = {
97
- [key: string]: FilterValue<Scalar> | RawQueryFragment;
279
+ [key: string]: FilterValue<Scalar> | RawQueryFragment;
98
280
  };
99
- type ExtractRawAliasFromField<F> = F extends RawQueryFragment<infer A> ? A extends string ? A : never : F extends `${string} as ${infer A}` ? A : never;
100
- type ExtractRawAliasesFromTuple<T extends readonly unknown[]> = T extends readonly [infer Head, ...infer Tail] ? ExtractRawAliasFromField<Head> | ExtractRawAliasesFromTuple<Tail> : never;
101
- type ExtractRawAliases<Fields> = Fields extends readonly unknown[] ? ExtractRawAliasesFromTuple<Fields> : ExtractRawAliasFromField<Fields>;
281
+ type ExtractRawAliasFromField<F> =
282
+ F extends RawQueryFragment<infer A>
283
+ ? A extends string
284
+ ? A
285
+ : never
286
+ : F extends `${string} as ${infer A}`
287
+ ? A
288
+ : never;
289
+ type ExtractRawAliasesFromTuple<T extends readonly unknown[]> = T extends readonly [infer Head, ...infer Tail]
290
+ ? ExtractRawAliasFromField<Head> | ExtractRawAliasesFromTuple<Tail>
291
+ : never;
292
+ type ExtractRawAliases<Fields> = Fields extends readonly unknown[]
293
+ ? ExtractRawAliasesFromTuple<Fields>
294
+ : ExtractRawAliasFromField<Fields>;
102
295
  type FlatOperatorMap = {
103
- $eq?: Scalar | readonly Scalar[] | Subquery | null;
104
- $ne?: Scalar | readonly Scalar[] | Subquery | null;
105
- $in?: readonly Scalar[] | Raw | Subquery;
106
- $nin?: readonly Scalar[] | Raw | Subquery;
107
- $gt?: Scalar | Subquery;
108
- $gte?: Scalar | Subquery;
109
- $lt?: Scalar | Subquery;
110
- $lte?: Scalar | Subquery;
111
- $like?: string;
112
- $re?: string;
113
- $ilike?: string;
114
- $fulltext?: string;
115
- $overlap?: readonly string[] | string | object;
116
- $contains?: readonly string[] | string | object;
117
- $contained?: readonly string[] | string | object;
118
- $exists?: boolean;
119
- $hasKey?: string;
120
- $hasKeys?: readonly string[];
121
- $hasSomeKeys?: readonly string[];
296
+ $eq?: Scalar | readonly Scalar[] | Subquery | null;
297
+ $ne?: Scalar | readonly Scalar[] | Subquery | null;
298
+ $in?: readonly Scalar[] | Raw | Subquery;
299
+ $nin?: readonly Scalar[] | Raw | Subquery;
300
+ $gt?: Scalar | Subquery;
301
+ $gte?: Scalar | Subquery;
302
+ $lt?: Scalar | Subquery;
303
+ $lte?: Scalar | Subquery;
304
+ $like?: string;
305
+ $re?: string;
306
+ $ilike?: string;
307
+ $fulltext?: string;
308
+ $overlap?: readonly string[] | string | object;
309
+ $contains?: readonly string[] | string | object;
310
+ $contained?: readonly string[] | string | object;
311
+ $exists?: boolean;
312
+ $hasKey?: string;
313
+ $hasKeys?: readonly string[];
314
+ $hasSomeKeys?: readonly string[];
122
315
  };
123
316
  type AliasedFilterValue = Scalar | FlatOperatorMap | readonly Scalar[] | null | QueryBuilder<any> | NativeQueryBuilder;
124
317
  type TypedAliasedFilterValue<T> = FilterValue<ExpandProperty<T>> | QueryBuilder<any> | NativeQueryBuilder;
125
318
  type RootAliasFilterKeys<RootAlias extends string, Entity> = {
126
- [K in EntityKey<Entity> as `${RootAlias}.${K}`]?: TypedAliasedFilterValue<Entity[K]>;
319
+ [K in EntityKey<Entity> as `${RootAlias}.${K}`]?: TypedAliasedFilterValue<Entity[K]>;
127
320
  };
128
321
  type ContextFilterKeys<Context> = {
129
- [K in ContextFieldKeys<Context>]?: AliasedFilterValue;
322
+ [K in ContextFieldKeys<Context>]?: AliasedFilterValue;
130
323
  };
131
324
  type RawFilterKeys<RawAliases extends string> = {
132
- [K in RawAliases]?: AliasedFilterValue;
325
+ [K in RawAliases]?: AliasedFilterValue;
133
326
  };
134
- type NestedFilterCondition<Entity, RootAlias extends string, Context, RawAliases extends string> = ObjectQuery<Entity> & (IsNever<RootAlias> extends true ? {} : string extends RootAlias ? {} : RootAliasFilterKeys<RootAlias, Entity>) & ([Context] extends [never] ? {} : ContextFilterKeys<Context>) & (IsNever<RawAliases> extends true ? {} : string extends RawAliases ? {} : RawFilterKeys<RawAliases>);
327
+ type NestedFilterCondition<Entity, RootAlias extends string, Context, RawAliases extends string> = ObjectQuery<Entity> &
328
+ (IsNever<RootAlias> extends true ? {} : string extends RootAlias ? {} : RootAliasFilterKeys<RootAlias, Entity>) &
329
+ ([Context] extends [never] ? {} : ContextFilterKeys<Context>) &
330
+ (IsNever<RawAliases> extends true ? {} : string extends RawAliases ? {} : RawFilterKeys<RawAliases>);
135
331
  type GroupOperators<RootAlias extends string, Context, Entity, RawAliases extends string> = {
136
- $and?: NestedFilterCondition<Entity, RootAlias, Context, RawAliases>[];
137
- $or?: NestedFilterCondition<Entity, RootAlias, Context, RawAliases>[];
138
- $not?: NestedFilterCondition<Entity, RootAlias, Context, RawAliases>;
332
+ $and?: NestedFilterCondition<Entity, RootAlias, Context, RawAliases>[];
333
+ $or?: NestedFilterCondition<Entity, RootAlias, Context, RawAliases>[];
334
+ $not?: NestedFilterCondition<Entity, RootAlias, Context, RawAliases>;
139
335
  };
140
- export type AliasedFilterCondition<RootAlias extends string, Context, Entity, RawAliases extends string = never> = (IsNever<RootAlias> extends true ? {} : string extends RootAlias ? {} : RootAliasFilterKeys<RootAlias, Entity>) & ([Context] extends [never] ? {} : ContextFilterKeys<Context>) & (IsNever<RawAliases> extends true ? {} : string extends RawAliases ? {} : RawFilterKeys<RawAliases>) & GroupOperators<RootAlias, Context, Entity, RawAliases>;
141
- export type QBFilterQuery<Entity, RootAlias extends string = never, Context = never, RawAliases extends string = never> = FilterObject<Entity> & AliasedFilterCondition<RootAlias, Context, Entity, RawAliases>;
336
+ export type AliasedFilterCondition<
337
+ RootAlias extends string,
338
+ Context,
339
+ Entity,
340
+ RawAliases extends string = never,
341
+ > = (IsNever<RootAlias> extends true ? {} : string extends RootAlias ? {} : RootAliasFilterKeys<RootAlias, Entity>) &
342
+ ([Context] extends [never] ? {} : ContextFilterKeys<Context>) &
343
+ (IsNever<RawAliases> extends true ? {} : string extends RawAliases ? {} : RawFilterKeys<RawAliases>) &
344
+ GroupOperators<RootAlias, Context, Entity, RawAliases>;
345
+ export type QBFilterQuery<
346
+ Entity,
347
+ RootAlias extends string = never,
348
+ Context = never,
349
+ RawAliases extends string = never,
350
+ > = FilterObject<Entity> & AliasedFilterCondition<RootAlias, Context, Entity, RawAliases>;
142
351
  /** @internal */
143
352
  export interface QBState<Entity extends object> {
144
- type?: QueryType;
145
- fields?: InternalField<Entity>[];
146
- populate: PopulateOptions<Entity>[];
147
- populateWhere?: ObjectQuery<Entity> | PopulateHint | `${PopulateHint}`;
148
- populateFilter?: ObjectQuery<Entity> | PopulateHint | `${PopulateHint}`;
149
- resolvedPopulateWhere?: ObjectQuery<Entity> | PopulateHint | `${PopulateHint}`;
150
- populateMap: Dictionary<string>;
151
- aliasCounter: number;
152
- flags: Set<QueryFlag>;
153
- finalized: boolean;
154
- populateHintFinalized: boolean;
155
- joins: Dictionary<JoinOptions>;
156
- explicitAlias: boolean;
157
- schema?: string;
158
- cond: Dictionary;
159
- data?: Dictionary;
160
- orderBy: QueryOrderMap<Entity>[];
161
- groupBy: InternalField<Entity>[];
162
- having: Dictionary;
163
- returning?: InternalField<Entity>[];
164
- onConflict?: OnConflictClause<Entity>[];
165
- limit?: number;
166
- offset?: number;
167
- distinctOn?: string[];
168
- joinedProps: Map<string, PopulateOptions<any>>;
169
- cache?: boolean | number | [string, number];
170
- indexHint?: string;
171
- collation?: string;
172
- comments: string[];
173
- hintComments: string[];
174
- flushMode?: FlushMode;
175
- lockMode?: LockMode;
176
- lockTables?: string[];
177
- subQueries: Dictionary<string>;
178
- mainAlias?: Alias<Entity>;
179
- aliases: Dictionary<Alias<any>>;
180
- tptAlias: Dictionary<string>;
181
- unionQuery?: {
182
- sql: string;
183
- params: readonly unknown[];
184
- };
185
- ctes: (CteOptions & {
186
- name: string;
187
- query: NativeQueryBuilder | RawQueryFragment;
188
- recursive?: boolean;
189
- })[];
190
- tptJoinsApplied: boolean;
191
- autoJoinedPaths: string[];
353
+ type?: QueryType;
354
+ fields?: InternalField<Entity>[];
355
+ populate: PopulateOptions<Entity>[];
356
+ populateWhere?: ObjectQuery<Entity> | PopulateHint | `${PopulateHint}`;
357
+ populateFilter?: ObjectQuery<Entity> | PopulateHint | `${PopulateHint}`;
358
+ resolvedPopulateWhere?: ObjectQuery<Entity> | PopulateHint | `${PopulateHint}`;
359
+ populateMap: Dictionary<string>;
360
+ aliasCounter: number;
361
+ flags: Set<QueryFlag>;
362
+ finalized: boolean;
363
+ populateHintFinalized: boolean;
364
+ joins: Dictionary<JoinOptions>;
365
+ explicitAlias: boolean;
366
+ schema?: string;
367
+ cond: Dictionary;
368
+ data?: Dictionary;
369
+ orderBy: QueryOrderMap<Entity>[];
370
+ groupBy: InternalField<Entity>[];
371
+ having: Dictionary;
372
+ returning?: InternalField<Entity>[];
373
+ onConflict?: OnConflictClause<Entity>[];
374
+ limit?: number;
375
+ offset?: number;
376
+ distinctOn?: string[];
377
+ joinedProps: Map<string, PopulateOptions<any>>;
378
+ cache?: boolean | number | [string, number];
379
+ indexHint?: string;
380
+ collation?: string;
381
+ comments: string[];
382
+ hintComments: string[];
383
+ flushMode?: FlushMode;
384
+ lockMode?: LockMode;
385
+ lockTables?: string[];
386
+ subQueries: Dictionary<string>;
387
+ mainAlias?: Alias<Entity>;
388
+ aliases: Dictionary<Alias<any>>;
389
+ tptAlias: Dictionary<string>;
390
+ unionQuery?: {
391
+ sql: string;
392
+ params: readonly unknown[];
393
+ };
394
+ ctes: (CteOptions & {
395
+ name: string;
396
+ query: NativeQueryBuilder | RawQueryFragment;
397
+ recursive?: boolean;
398
+ })[];
399
+ tptJoinsApplied: boolean;
400
+ autoJoinedPaths: string[];
192
401
  }
193
402
  /**
194
403
  * SQL query builder with fluent interface.
@@ -209,743 +418,1110 @@ export interface QBState<Entity extends object> {
209
418
  * const publisher = await qb.getSingleResult();
210
419
  * ```
211
420
  */
212
- export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias extends string = never, Hint extends string = never, Context extends object = never, RawAliases extends string = never, Fields extends string = '*', CTEs extends Record<string, object> = {}> implements Subquery {
213
- #private;
214
- protected readonly metadata: MetadataStorage;
215
- protected readonly driver: AbstractSqlDriver;
216
- protected readonly context?: Transaction | undefined;
217
- protected connectionType?: ConnectionType | undefined;
218
- protected em?: SqlEntityManager | undefined;
219
- protected loggerContext?: (LoggingOptions & Dictionary) | undefined;
220
- readonly __subquery: true;
221
- /** @internal */
222
- static createDefaultState<T extends object>(): QBState<T>;
223
- get mainAlias(): Alias<Entity>;
224
- get alias(): string;
225
- get helper(): QueryBuilderHelper;
226
- get type(): QueryType;
227
- /** @internal */
228
- get state(): QBState<Entity>;
229
- protected readonly platform: AbstractSqlPlatform;
230
- /**
231
- * @internal
232
- */
233
- constructor(entityName: EntityName<Entity> | QueryBuilder<Entity, any, any, any>, metadata: MetadataStorage, driver: AbstractSqlDriver, context?: Transaction | undefined, alias?: string, connectionType?: ConnectionType | undefined, em?: SqlEntityManager | undefined, loggerContext?: (LoggingOptions & Dictionary) | undefined);
234
- /**
235
- * Creates a SELECT query, specifying the fields to retrieve.
236
- *
237
- * @example
238
- * ```ts
239
- * // Select specific fields
240
- * const qb = em.createQueryBuilder(User, 'u');
241
- * qb.select(['u.id', 'u.name', 'u.email']);
242
- *
243
- * // Select with raw expressions
244
- * qb.select([raw('count(*) as total')]);
245
- *
246
- * // Select with aliases (works for regular and formula properties)
247
- * qb.select(['id', 'fullName as displayName']);
248
- * qb.select(['id', sql.ref('fullName').as('displayName')]);
249
- *
250
- * // Select with distinct
251
- * qb.select('*', true);
252
- * ```
253
- */
254
- select<const F extends readonly Field<Entity, RootAlias, Context>[]>(fields: F, distinct?: boolean): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases | ExtractRawAliases<F>, ExtractRootFields<F[number] & string, RootAlias, Context>, CTEs>;
255
- /**
256
- * Creates a SELECT query, specifying the fields to retrieve.
257
- *
258
- * @example
259
- * ```ts
260
- * // Select specific fields
261
- * const qb = em.createQueryBuilder(User, 'u');
262
- * qb.select(['u.id', 'u.name', 'u.email']);
263
- *
264
- * // Select with raw expressions
265
- * qb.select([raw('count(*) as total')]);
266
- *
267
- * // Select with distinct
268
- * qb.select('*', true);
269
- * ```
270
- */
271
- select<const P extends string>(fields: readonly NestedAutoPath<Entity, RootAlias, Context, P>[], distinct?: boolean): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, ExtractRootFields<P, RootAlias, Context>, CTEs>;
272
- /**
273
- * Creates a SELECT query, specifying the fields to retrieve.
274
- *
275
- * @example
276
- * ```ts
277
- * // Select specific fields with nested paths (e.g., for embedded properties)
278
- * const qb = em.createQueryBuilder(User, 'u');
279
- * qb.select('address.city');
280
- * ```
281
- */
282
- select<const P extends string>(fields: NestedAutoPath<Entity, RootAlias, Context, P>, distinct?: boolean): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, ExtractRootFields<P, RootAlias, Context>, CTEs>;
283
- /**
284
- * Creates a SELECT query, specifying the fields to retrieve.
285
- *
286
- * @example
287
- * ```ts
288
- * // Select specific fields
289
- * const qb = em.createQueryBuilder(User, 'u');
290
- * qb.select(['u.id', 'u.name', 'u.email']);
291
- *
292
- * // Select with raw expressions
293
- * qb.select([raw('count(*) as total')]);
294
- *
295
- * // Select with distinct
296
- * qb.select('*', true);
297
- * ```
298
- */
299
- select<const F extends Field<Entity, RootAlias, Context>>(fields: F, distinct?: boolean): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases | ExtractRawAliases<readonly [F]>, ExtractRootFields<F & string, RootAlias, Context>, CTEs>;
300
- /**
301
- * Adds fields to an existing SELECT query.
302
- */
303
- addSelect<const F extends Field<Entity, RootAlias, Context> | readonly Field<Entity, RootAlias, Context>[]>(fields: F): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases | ExtractRawAliases<F extends readonly unknown[] ? F : [F]>, Fields | ExtractRootFields<F extends readonly (infer U)[] ? U & string : F & string, RootAlias, Context>, CTEs>;
304
- distinct(): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
305
- /** postgres only */
306
- distinctOn<const F extends readonly Field<Entity, RootAlias, Context>[]>(fields: F): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
307
- /** postgres only */
308
- distinctOn<F extends Field<Entity, RootAlias, Context>>(fields: F): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
309
- /**
310
- * Creates an INSERT query with the given data.
311
- *
312
- * @example
313
- * ```ts
314
- * await em.createQueryBuilder(User)
315
- * .insert({ name: 'John', email: 'john@example.com' })
316
- * .execute();
317
- *
318
- * // Bulk insert
319
- * await em.createQueryBuilder(User)
320
- * .insert([{ name: 'John' }, { name: 'Jane' }])
321
- * .execute();
322
- * ```
323
- */
324
- insert(data: RequiredEntityData<Entity> | RequiredEntityData<Entity>[]): InsertQueryBuilder<Entity, RootAlias, Context>;
325
- /**
326
- * Creates an UPDATE query with the given data.
327
- * Use `where()` to specify which rows to update.
328
- *
329
- * @example
330
- * ```ts
331
- * await em.createQueryBuilder(User)
332
- * .update({ name: 'John Doe' })
333
- * .where({ id: 1 })
334
- * .execute();
335
- * ```
336
- */
337
- update(data: EntityData<Entity>): UpdateQueryBuilder<Entity, RootAlias, Context>;
338
- /**
339
- * Creates a DELETE query.
340
- * Use `where()` to specify which rows to delete.
341
- *
342
- * @example
343
- * ```ts
344
- * await em.createQueryBuilder(User)
345
- * .delete()
346
- * .where({ id: 1 })
347
- * .execute();
348
- *
349
- * // Or pass the condition directly
350
- * await em.createQueryBuilder(User)
351
- * .delete({ isActive: false })
352
- * .execute();
353
- * ```
354
- */
355
- delete(cond?: QBFilterQuery<Entity, RootAlias, Context, RawAliases>): DeleteQueryBuilder<Entity, RootAlias, Context>;
356
- /**
357
- * Creates a TRUNCATE query to remove all rows from the table.
358
- */
359
- truncate(): TruncateQueryBuilder<Entity>;
360
- /**
361
- * Creates a COUNT query to count matching rows.
362
- *
363
- * @example
364
- * ```ts
365
- * const count = await em.createQueryBuilder(User)
366
- * .count()
367
- * .where({ isActive: true })
368
- * .execute('get');
369
- * ```
370
- */
371
- count<F extends Field<Entity, RootAlias, Context>>(field?: F | F[], distinct?: boolean): CountQueryBuilder<Entity>;
372
- /**
373
- * Adds a JOIN clause to the query for an entity relation.
374
- *
375
- * @example
376
- * ```ts
377
- * const qb = em.createQueryBuilder(Book, 'b');
378
- * qb.select('*')
379
- * .join('b.author', 'a')
380
- * .where({ 'a.name': 'John' });
381
- * ```
382
- */
383
- join<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field, alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, type?: JoinType, path?: string, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field> & {}, ModifyContext<Entity, Context, Field, Alias>, RawAliases, '*', CTEs>;
384
- /**
385
- * Adds a JOIN clause to the query for a subquery.
386
- */
387
- join<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, type?: JoinType, path?: string, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
388
- /**
389
- * Adds an INNER JOIN clause to the query for an entity relation.
390
- */
391
- innerJoin<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field, alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field> & {}, ModifyContext<Entity, Context, Field, Alias>, RawAliases, '*', CTEs>;
392
- /**
393
- * Adds an INNER JOIN clause to the query for a subquery.
394
- */
395
- innerJoin<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
396
- innerJoinLateral<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
397
- /**
398
- * Adds a LEFT JOIN clause to the query for an entity relation.
399
- */
400
- leftJoin<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(field: Field, alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field> & {}, ModifyContext<Entity, Context, Field, Alias>, RawAliases, '*', CTEs>;
401
- /**
402
- * Adds a LEFT JOIN clause to the query for a subquery.
403
- */
404
- leftJoin<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
405
- leftJoinLateral<Alias extends string>(field: RawQueryFragment | QueryBuilder<any>, alias: Alias, cond?: RawJoinCondition, schema?: string): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
406
- /**
407
- * Adds a JOIN clause and automatically selects the joined entity's fields.
408
- * This is useful for eager loading related entities.
409
- *
410
- * @example
411
- * ```ts
412
- * const qb = em.createQueryBuilder(Book, 'b');
413
- * qb.select('*')
414
- * .joinAndSelect('b.author', 'a')
415
- * .where({ 'a.name': 'John' });
416
- * ```
417
- */
418
- joinAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string, const JoinFields extends readonly [
419
- JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>,
420
- ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[]
421
- ] | undefined = undefined>(field: Field | [Field, RawQueryFragment | QueryBuilder<any>], alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, type?: JoinType, path?: string, fields?: JoinFields, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>, RawAliases, ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>, CTEs>;
422
- leftJoinAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string, const JoinFields extends readonly [
423
- JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>,
424
- ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[]
425
- ] | undefined = undefined>(field: Field | [Field, RawQueryFragment | QueryBuilder<any>], alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, fields?: JoinFields, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>, RawAliases, ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>, CTEs>;
426
- leftJoinLateralAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string, const JoinFields extends readonly [
427
- JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>,
428
- ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[]
429
- ] | undefined = undefined>(field: [Field, RawQueryFragment | QueryBuilder<any>], alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, fields?: JoinFields, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>, RawAliases, ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>, CTEs>;
430
- innerJoinAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string, const JoinFields extends readonly [
431
- JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>,
432
- ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[]
433
- ] | undefined = undefined>(field: Field | [Field, RawQueryFragment | QueryBuilder<any>], alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, fields?: JoinFields, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>, RawAliases, ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>, CTEs>;
434
- innerJoinLateralAndSelect<Field extends QBField<Entity, RootAlias, Context>, Alias extends string, const JoinFields extends readonly [
435
- JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>,
436
- ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[]
437
- ] | undefined = undefined>(field: [Field, RawQueryFragment | QueryBuilder<any>], alias: Alias, cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>, fields?: JoinFields, schema?: string): SelectQueryBuilder<Entity, RootAlias, ModifyHint<RootAlias, Context, Hint, Field, true> & {}, ModifyContext<Entity, Context, Field, Alias, true>, RawAliases, ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>, CTEs>;
438
- protected getFieldsForJoinedLoad(prop: EntityProperty<Entity>, alias: string, explicitFields?: readonly string[]): InternalField<Entity>[];
439
- /**
440
- * Apply filters to the QB where condition.
441
- */
442
- applyFilters(filterOptions?: FilterOptions): Promise<void>;
443
- /**
444
- * @internal
445
- */
446
- scheduleFilterCheck(path: string): void;
447
- /**
448
- * @internal
449
- */
450
- applyJoinedFilters(em: EntityManager, filterOptions: FilterOptions | undefined): Promise<void>;
451
- withSubQuery(subQuery: RawQueryFragment | NativeQueryBuilder, alias: string): this;
452
- /**
453
- * Adds a WHERE clause to the query using an object condition.
454
- *
455
- * Supports filtering by:
456
- * - Direct entity properties: `{ name: 'John' }`
457
- * - Nested relations/embedded: `{ author: { name: 'John' } }`
458
- * - Aliased properties after joins: `{ 'a.name': 'John' }` or `{ 'b.title': 'test' }`
459
- * - Filter operators: `{ age: { $gte: 18 } }`
460
- * - Logical operators: `{ $or: [{ name: 'John' }, { name: 'Jane' }] }`
461
- *
462
- * @example
463
- * ```ts
464
- * // Filter by entity properties
465
- * qb.where({ name: 'John', age: { $gte: 18 } });
466
- *
467
- * // Filter by nested relation
468
- * qb.where({ author: { name: 'John' } });
469
- *
470
- * // Filter by aliased properties after join
471
- * qb.leftJoin('a.books', 'b').where({ 'b.title': 'test' });
472
- *
473
- * // Combine with logical operators
474
- * qb.where({ $or: [{ status: 'active' }, { role: 'admin' }] });
475
- * ```
476
- */
477
- where(cond: QBFilterQuery<Entity, RootAlias, Context, RawAliases>, operator?: keyof typeof GroupOperator): this;
478
- /**
479
- * Adds a WHERE clause to the query using a raw SQL string or fragment.
480
- *
481
- * @example
482
- * ```ts
483
- * // Raw SQL with parameters
484
- * qb.where('name = ? AND age >= ?', ['John', 18]);
485
- *
486
- * // Using raw() helper
487
- * qb.where(raw('lower(name) = ?', ['john']));
488
- * ```
489
- */
490
- where(cond: string | RawQueryFragment, params?: any[], operator?: keyof typeof GroupOperator): this;
491
- /**
492
- * Adds an AND WHERE clause to the query using an object condition.
493
- *
494
- * @example
495
- * ```ts
496
- * qb.where({ status: 'active' }).andWhere({ role: 'admin' });
497
- * qb.where({ name: 'John' }).andWhere({ 'b.title': 'test' });
498
- * ```
499
- */
500
- andWhere(cond: QBFilterQuery<Entity, RootAlias, Context, RawAliases>): this;
501
- /**
502
- * Adds an AND WHERE clause to the query using a raw SQL string or fragment.
503
- *
504
- * @example
505
- * ```ts
506
- * qb.where({ status: 'active' }).andWhere('age >= ?', [18]);
507
- * ```
508
- */
509
- andWhere(cond: string | RawQueryFragment, params?: any[]): this;
510
- /**
511
- * Adds an OR WHERE clause to the query using an object condition.
512
- *
513
- * @example
514
- * ```ts
515
- * qb.where({ status: 'active' }).orWhere({ role: 'admin' });
516
- * qb.where({ name: 'John' }).orWhere({ name: 'Jane' });
517
- * ```
518
- */
519
- orWhere(cond: QBFilterQuery<Entity, RootAlias, Context, RawAliases>): this;
520
- /**
521
- * Adds an OR WHERE clause to the query using a raw SQL string or fragment.
522
- *
523
- * @example
524
- * ```ts
525
- * qb.where({ status: 'active' }).orWhere('role = ?', ['admin']);
526
- * ```
527
- */
528
- orWhere(cond: string | RawQueryFragment, params?: any[]): this;
529
- /**
530
- * Adds an ORDER BY clause to the query, replacing any existing order.
531
- *
532
- * @example
533
- * ```ts
534
- * qb.orderBy({ name: 'asc', createdAt: 'desc' });
535
- * qb.orderBy([{ name: 'asc' }, { createdAt: 'desc' }]);
536
- * qb.orderBy({ profile: { bio: 'asc' } }); // nested via object
537
- * qb.orderBy({ 'profile.bio': 'asc' }); // nested via dot notation
538
- * ```
539
- */
540
- orderBy(orderBy: ContextOrderByMap<Entity, RootAlias, Context, RawAliases> | ContextOrderByMap<Entity, RootAlias, Context, RawAliases>[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
541
- /**
542
- * Adds an ORDER BY clause to the query, replacing any existing order.
543
- *
544
- * @example
545
- * ```ts
546
- * qb.orderBy({ name: 'asc', createdAt: 'desc' });
547
- * qb.orderBy([{ name: 'asc' }, { createdAt: 'desc' }]);
548
- * qb.orderBy({ profile: { bio: 'asc' } }); // nested via object
549
- * qb.orderBy({ 'profile.bio': 'asc' }); // nested via dot notation
550
- * ```
551
- */
552
- orderBy<const T extends Record<string, QueryOrderKeysFlat>>(orderBy: T & {
553
- [K in keyof T]: K extends NestedAutoPath<Entity, RootAlias, Context, K & string> ? T[K] : K extends RawAliases ? T[K] : never;
554
- }): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
555
- /**
556
- * Adds additional ORDER BY clause without replacing existing order.
557
- */
558
- andOrderBy(orderBy: ContextOrderByMap<Entity, RootAlias, Context, RawAliases> | ContextOrderByMap<Entity, RootAlias, Context, RawAliases>[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
559
- /**
560
- * Adds additional ORDER BY clause without replacing existing order.
561
- */
562
- andOrderBy<const T extends Record<string, QueryOrderKeysFlat>>(orderBy: T & {
563
- [K in keyof T]: K extends NestedAutoPath<Entity, RootAlias, Context, K & string> ? T[K] : K extends RawAliases ? T[K] : never;
564
- }): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
565
- private processOrderBy;
566
- /** Collect custom aliases from select fields (stored as 'resolved as alias' strings by select()). */
567
- private getSelectAliases;
568
- /**
569
- * Adds a GROUP BY clause to the query.
570
- *
571
- * @example
572
- * ```ts
573
- * qb.select([raw('count(*) as count'), 'status'])
574
- * .groupBy('status');
575
- * ```
576
- */
577
- groupBy<const F extends readonly Field<Entity, RootAlias, Context>[]>(fields: F): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
578
- /**
579
- * Adds a GROUP BY clause to the query.
580
- *
581
- * @example
582
- * ```ts
583
- * qb.select([raw('count(*) as count'), 'status'])
584
- * .groupBy('status');
585
- * ```
586
- */
587
- groupBy<F extends Field<Entity, RootAlias, Context>>(fields: F): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
588
- /**
589
- * Adds a GROUP BY clause to the query.
590
- *
591
- * @example
592
- * ```ts
593
- * qb.select([raw('count(*) as count'), 'status'])
594
- * .groupBy('status');
595
- * ```
596
- */
597
- groupBy<const P extends string>(fields: NestedAutoPath<Entity, RootAlias, Context, P> | readonly NestedAutoPath<Entity, RootAlias, Context, P>[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
598
- /**
599
- * Adds a HAVING clause to the query, typically used with GROUP BY.
600
- *
601
- * @example
602
- * ```ts
603
- * qb.select([raw('count(*) as count'), 'status'])
604
- * .groupBy('status')
605
- * .having({ count: { $gt: 5 } });
606
- * ```
607
- */
608
- having(cond?: QBFilterQuery<Entity, RootAlias, Context, RawAliases> | string, params?: any[], operator?: keyof typeof GroupOperator): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
609
- andHaving(cond?: QBFilterQuery<Entity, RootAlias, Context, RawAliases> | string, params?: any[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
610
- orHaving(cond?: QBFilterQuery<Entity, RootAlias, Context, RawAliases> | string, params?: any[]): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
611
- onConflict<F extends Field<Entity, RootAlias, Context>>(fields?: F | F[] | RawQueryFragment): InsertQueryBuilder<Entity, RootAlias, Context>;
612
- ignore(): this;
613
- merge<const P extends string>(data: readonly NestedAutoPath<Entity, RootAlias, Context, P>[]): this;
614
- merge<F extends Field<Entity, RootAlias, Context>>(data?: EntityData<Entity> | F[]): this;
615
- returning<F extends Field<Entity, RootAlias, Context>>(fields?: F | F[]): this;
616
- /**
617
- * @internal
618
- */
619
- populate(populate: PopulateOptions<Entity>[], populateWhere?: ObjectQuery<Entity> | PopulateHint | `${PopulateHint}`, populateFilter?: ObjectQuery<Entity> | PopulateHint | `${PopulateHint}`): this;
620
- /**
621
- * Sets a LIMIT clause to restrict the number of results.
622
- *
623
- * @example
624
- * ```ts
625
- * qb.select('*').limit(10); // First 10 results
626
- * qb.select('*').limit(10, 20); // 10 results starting from offset 20
627
- * ```
628
- */
629
- limit(limit?: number, offset?: number): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
630
- /**
631
- * Sets an OFFSET clause to skip a number of results.
632
- *
633
- * @example
634
- * ```ts
635
- * qb.select('*').limit(10).offset(20); // Results 21-30
636
- * ```
637
- */
638
- offset(offset?: number): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
639
- withSchema(schema?: string): this;
640
- setLockMode(mode?: LockMode, tables?: string[]): this;
641
- setFlushMode(flushMode?: FlushMode): this;
642
- setFlag(flag: QueryFlag): this;
643
- unsetFlag(flag: QueryFlag): this;
644
- hasFlag(flag: QueryFlag): boolean;
645
- cache(config?: boolean | number | [string, number]): this;
646
- /**
647
- * Adds index hint to the FROM clause.
648
- */
649
- indexHint(sql: string | undefined): this;
650
- /**
651
- * Adds COLLATE clause to ORDER BY expressions.
652
- */
653
- collation(collation: string | undefined): this;
654
- /**
655
- * Prepend comment to the sql query using the syntax `/* ... *&#8205;/`. Some characters are forbidden such as `/*, *&#8205;/` and `?`.
656
- */
657
- comment(comment: string | string[] | undefined): this;
658
- /**
659
- * Add hints to the query using comment-like syntax `/*+ ... *&#8205;/`. MySQL and Oracle use this syntax for optimizer hints.
660
- * Also various DB proxies and routers use this syntax to pass hints to alter their behavior. In other dialects the hints
661
- * are ignored as simple comments.
662
- */
663
- hintComment(comment: string | string[] | undefined): this;
664
- /**
665
- * Specifies FROM which entity's table select/update/delete will be executed, removing all previously set FROM-s.
666
- * Allows setting a main string alias of the selection data.
667
- */
668
- from<Entity extends object>(target: QueryBuilder<Entity>, aliasName?: string): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
669
- /**
670
- * Specifies FROM which entity's table select/update/delete will be executed, removing all previously set FROM-s.
671
- * Allows setting a main string alias of the selection data.
672
- */
673
- from<Entity extends object>(target: EntityName<Entity>): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
674
- /**
675
- * Specifies a CTE name as the FROM source, with full type safety.
676
- * The entity type is inferred from the CTE definition passed to `.with()`.
677
- */
678
- from<Name extends string & keyof CTEs, Alias extends string = Name>(target: Name, aliasName?: Alias): SelectQueryBuilder<CTEs[Name], Alias, never, never, never, '*', CTEs>;
679
- getNativeQuery(processVirtualEntity?: boolean): NativeQueryBuilder;
680
- protected processReturningStatement(qb: NativeQueryBuilder, meta?: EntityMetadata, data?: Dictionary, returning?: Field<any>[]): void;
681
- /**
682
- * Returns the query with parameters as wildcards.
683
- */
684
- getQuery(): string;
685
- /**
686
- * Returns raw fragment representation of this QueryBuilder.
687
- */
688
- toRaw(): RawQueryFragment;
689
- toQuery(): {
690
- sql: string;
691
- params: readonly unknown[];
692
- };
693
- /**
694
- * Returns the list of all parameters for this query.
695
- */
696
- getParams(): readonly unknown[];
697
- /**
698
- * Returns raw interpolated query string with all the parameters inlined.
699
- */
700
- getFormattedQuery(): string;
701
- /**
702
- * @internal
703
- */
704
- getAliasForJoinPath(path?: string | JoinOptions, options?: ICriteriaNodeProcessOptions): string | undefined;
705
- /**
706
- * @internal
707
- */
708
- getJoinForPath(path: string, options?: ICriteriaNodeProcessOptions): JoinOptions | undefined;
709
- /**
710
- * @internal
711
- */
712
- getNextAlias(entityName?: string | EntityName): string;
713
- /**
714
- * Registers a join for a specific polymorphic target type.
715
- * Used by the driver to create per-target LEFT JOINs for JOINED loading.
716
- * @internal
717
- */
718
- addPolymorphicJoin(prop: EntityProperty, targetMeta: EntityMetadata, ownerAlias: string, alias: string, type: JoinType, path: string, schema?: string): void;
719
- /**
720
- * @internal
721
- */
722
- getAliasMap(): Dictionary<EntityName>;
723
- /**
724
- * Executes this QB and returns the raw results, mapped to the property names (unless disabled via last parameter).
725
- * Use `method` to specify what kind of result you want to get (array/single/meta).
726
- */
727
- execute<U = any>(method?: 'all' | 'get' | 'run', options?: ExecuteOptions | boolean): Promise<U>;
728
- private getConnection;
729
- /**
730
- * Executes the query and returns an async iterable (async generator) that yields results one by one.
731
- * By default, the results are merged and mapped to entity instances, without adding them to the identity map.
732
- * You can disable merging and mapping by passing the options `{ mergeResults: false, mapResults: false }`.
733
- * This is useful for processing large datasets without loading everything into memory at once.
734
- *
735
- * ```ts
736
- * const qb = em.createQueryBuilder(Book, 'b');
737
- * qb.select('*').where({ title: '1984' }).leftJoinAndSelect('b.author', 'a');
738
- *
739
- * for await (const book of qb.stream()) {
740
- * // book is an instance of Book entity
741
- * console.log(book.title, book.author.name);
742
- * }
743
- * ```
744
- */
745
- stream(options?: QBStreamOptions): AsyncIterableIterator<Loaded<Entity, Hint, Fields>>;
746
- /**
747
- * Alias for `qb.getResultList()`
748
- */
749
- getResult(): Promise<Loaded<Entity, Hint, Fields>[]>;
750
- /**
751
- * Executes the query, returning array of results mapped to entity instances.
752
- */
753
- getResultList(limit?: number): Promise<Loaded<Entity, Hint, Fields>[]>;
754
- private propagatePopulateHint;
755
- private mapResult;
756
- private mapResults;
757
- /**
758
- * Executes the query, returning the first result or null
759
- */
760
- getSingleResult(): Promise<Loaded<Entity, Hint, Fields> | null>;
761
- /**
762
- * Executes count query (without offset and limit), returning total count of results
763
- */
764
- getCount<F extends Field<Entity, RootAlias, Context>>(field?: F | F[], distinct?: boolean): Promise<number>;
765
- /**
766
- * Executes the query, returning both array of results and total count query (without offset and limit).
767
- */
768
- getResultAndCount(): Promise<[Loaded<Entity, Hint, Fields>[], number]>;
769
- /**
770
- * Returns native query builder instance with sub-query aliased with given alias.
771
- */
772
- as(alias: string): NativeQueryBuilder;
773
- /**
774
- * Returns native query builder instance with sub-query aliased with given alias.
775
- * You can provide the target entity name as the first parameter and use the second parameter to point to an existing property to infer its field name.
776
- */
777
- as<T>(targetEntity: EntityName<T>, alias: EntityKey<T>): NativeQueryBuilder;
778
- /**
779
- * Combines the current query with one or more other queries using `UNION ALL`.
780
- * All queries must select the same columns. Returns a `QueryBuilder` that
781
- * can be used with `$in`, passed to `qb.from()`, or converted via `.getQuery()`,
782
- * `.getParams()`, `.toQuery()`, `.toRaw()`, etc.
783
- *
784
- * ```ts
785
- * const qb1 = em.createQueryBuilder(Employee).select('id').where(condition1);
786
- * const qb2 = em.createQueryBuilder(Employee).select('id').where(condition2);
787
- * const qb3 = em.createQueryBuilder(Employee).select('id').where(condition3);
788
- * const subquery = qb1.unionAll(qb2, qb3);
789
- *
790
- * const results = await em.find(Employee, { id: { $in: subquery } });
791
- * ```
792
- */
793
- unionAll(...others: (QueryBuilder<any> | NativeQueryBuilder)[]): QueryBuilder<Entity>;
794
- /**
795
- * Combines the current query with one or more other queries using `UNION` (with deduplication).
796
- * All queries must select the same columns. Returns a `QueryBuilder` that
797
- * can be used with `$in`, passed to `qb.from()`, or converted via `.getQuery()`,
798
- * `.getParams()`, `.toQuery()`, `.toRaw()`, etc.
799
- *
800
- * ```ts
801
- * const qb1 = em.createQueryBuilder(Employee).select('id').where(condition1);
802
- * const qb2 = em.createQueryBuilder(Employee).select('id').where(condition2);
803
- * const subquery = qb1.union(qb2);
804
- *
805
- * const results = await em.find(Employee, { id: { $in: subquery } });
806
- * ```
807
- */
808
- union(...others: (QueryBuilder<any> | NativeQueryBuilder)[]): QueryBuilder<Entity>;
809
- private buildUnionQuery;
810
- /**
811
- * Adds a Common Table Expression (CTE) to the query.
812
- * When a `QueryBuilder` is passed, its entity type is tracked for type-safe `from()`.
813
- *
814
- * @example
815
- * ```ts
816
- * const recentBooks = em.createQueryBuilder(Book, 'b').select('*').where({ ... });
817
- * const qb = em.createQueryBuilder(Author, 'a')
818
- * .with('recent_books', recentBooks)
819
- * .select('*')
820
- * .from('recent_books', 'rb'); // entity type inferred as Book
821
- * ```
822
- */
823
- with<Name extends string, Q extends QueryBuilder<any>>(name: Name, query: Q, options?: CteOptions): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs & Record<Name, Q extends QueryBuilder<infer T> ? T : object>>;
824
- /**
825
- * Adds a Common Table Expression (CTE) to the query using a `NativeQueryBuilder` or raw SQL fragment.
826
- * The CTE name is tracked but without entity type inference — use `from()` to query from it.
827
- */
828
- with<Name extends string>(name: Name, query: NativeQueryBuilder | RawQueryFragment, options?: CteOptions): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs & Record<Name, object>>;
829
- /**
830
- * Adds a recursive Common Table Expression (CTE) to the query.
831
- * When a `QueryBuilder` is passed, its entity type is tracked for type-safe `from()`.
832
- *
833
- * @example
834
- * ```ts
835
- * const base = em.createQueryBuilder(Category).select('*').where({ parent: null });
836
- * const rec = em.createQueryBuilder(Category, 'c').select('c.*')
837
- * .leftJoin('c.parent', 'ct', { id: sql.ref('c.parentId') });
838
- * const qb = em.createQueryBuilder(Category)
839
- * .withRecursive('category_tree', base.unionAll(rec))
840
- * .select('*')
841
- * .from('category_tree', 'ct'); // entity type inferred as Category
842
- * ```
843
- */
844
- withRecursive<Name extends string, Q extends QueryBuilder<any>>(name: Name, query: Q, options?: CteOptions): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs & Record<Name, Q extends QueryBuilder<infer T> ? T : object>>;
845
- /**
846
- * Adds a recursive Common Table Expression (CTE) to the query using a `NativeQueryBuilder` or raw SQL fragment.
847
- * The CTE name is tracked but without entity type inference — use `from()` to query from it.
848
- */
849
- withRecursive<Name extends string>(name: Name, query: NativeQueryBuilder | RawQueryFragment, options?: CteOptions): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs & Record<Name, object>>;
850
- private addCte;
851
- clone(reset?: boolean | (keyof QBState<Entity>)[], preserve?: (keyof QBState<Entity>)[]): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
852
- /**
853
- * Sets logger context for this query builder.
854
- */
855
- setLoggerContext(context: LoggingOptions & Dictionary): void;
856
- /**
857
- * Gets logger context for this query builder.
858
- */
859
- getLoggerContext<T extends Dictionary & LoggingOptions = Dictionary>(): T;
860
- private fromVirtual;
861
- /**
862
- * Adds a join from a property object. Used internally for TPT joins where the property
863
- * is synthetic (not in entity.properties) but defined on metadata (e.g., tptParentProp).
864
- * The caller must create the alias first via createAlias().
865
- * @internal
866
- */
867
- addPropertyJoin(prop: EntityProperty, ownerAlias: string, alias: string, type: JoinType, path: string, schema?: string): string;
868
- private joinReference;
869
- protected prepareFields<T>(fields: InternalField<T>[], type?: 'where' | 'groupBy' | 'sub-query', schema?: string): (string | RawQueryFragment)[];
870
- /**
871
- * Resolves nested paths like `a.books.title` to their actual field references.
872
- * Auto-joins relations as needed and returns `{alias}.{field}`.
873
- * For embeddeds: navigates into flattened embeddeds to return the correct field name.
874
- */
875
- protected resolveNestedPath(field: string): string | string[];
876
- protected init(type: QueryType, data?: any, cond?: any): this;
877
- private getQueryBase;
878
- private applyDiscriminatorCondition;
879
- /**
880
- * Ensures TPT joins are applied. Can be called early before finalize() to populate
881
- * the _tptAlias map for use in join resolution. Safe to call multiple times.
882
- * @internal
883
- */
884
- ensureTPTJoins(): void;
885
- /**
886
- * For TPT (Table-Per-Type) inheritance: INNER JOINs parent tables.
887
- * When querying a child entity, we need to join all parent tables.
888
- * Field selection is handled separately in addTPTParentFields().
889
- */
890
- private applyTPTJoins;
891
- /**
892
- * For TPT inheritance: adds field selections from parent tables.
893
- */
894
- private addTPTParentFields;
895
- /**
896
- * For TPT polymorphic queries: LEFT JOINs all child tables when querying a TPT base class.
897
- * Adds discriminator and child fields to determine and load the concrete type.
898
- */
899
- private applyTPTPolymorphicJoins;
900
- private finalize;
901
- /** @internal */
902
- processPopulateHint(): void;
903
- private processPopulateWhere;
904
- private mergeOnConditions;
905
- /**
906
- * When adding an inner join on a left joined relation, we need to nest them,
907
- * otherwise the inner join could discard rows of the root table.
908
- */
909
- private processNestedJoins;
910
- private hasToManyJoins;
911
- protected wrapPaginateSubQuery(meta: EntityMetadata): void;
912
- /**
913
- * Computes the set of populate paths from the _populate hints.
914
- */
915
- protected getPopulatePaths(): Set<string>;
916
- protected normalizeJoinPath(join: JoinOptions, meta: EntityMetadata): string;
917
- /**
918
- * Transfers WHERE conditions to ORDER BY joins that are not used for population.
919
- * This ensures the outer query's ORDER BY uses the same filtered rows as the subquery.
920
- * GH #6160
921
- */
922
- protected transferConditionsForOrderByJoins(meta: EntityMetadata, cond: Dictionary | undefined, populatePaths: Set<string>): void;
923
- /**
924
- * Removes joins that are not used for population or ordering to improve performance.
925
- */
926
- protected pruneJoinsForPagination(meta: EntityMetadata, populatePaths: Set<string>): void;
927
- /**
928
- * Transfers WHERE conditions that reference a join alias to the join's ON clause.
929
- * This is needed when a join is kept for ORDER BY after pagination wrapping,
930
- * so the outer query orders by the same filtered rows as the subquery.
931
- * @internal
932
- */
933
- protected transferConditionsToJoin(cond: Dictionary, join: JoinOptions, path?: string): void;
934
- private wrapModifySubQuery;
935
- private getSchema;
936
- /** @internal */
937
- createAlias<U = unknown>(entityName: EntityName<U>, aliasName: string, subQuery?: NativeQueryBuilder | RawQueryFragment): Alias<U>;
938
- private createMainAlias;
939
- private fromSubQuery;
940
- private fromEntityName;
941
- private fromRawTable;
942
- private createQueryBuilderHelper;
943
- private ensureFromClause;
944
- private ensureNotFinalized;
421
+ export declare class QueryBuilder<
422
+ Entity extends object = AnyEntity,
423
+ RootAlias extends string = never,
424
+ Hint extends string = never,
425
+ Context extends object = never,
426
+ RawAliases extends string = never,
427
+ Fields extends string = '*',
428
+ CTEs extends Record<string, object> = {},
429
+ > implements Subquery {
430
+ #private;
431
+ protected readonly metadata: MetadataStorage;
432
+ protected readonly driver: AbstractSqlDriver;
433
+ protected readonly context?: Transaction | undefined;
434
+ protected connectionType?: ConnectionType | undefined;
435
+ protected em?: SqlEntityManager | undefined;
436
+ protected loggerContext?: (LoggingOptions & Dictionary) | undefined;
437
+ readonly __subquery: true;
438
+ /** @internal */
439
+ static createDefaultState<T extends object>(): QBState<T>;
440
+ get mainAlias(): Alias<Entity>;
441
+ get alias(): string;
442
+ get helper(): QueryBuilderHelper;
443
+ get type(): QueryType;
444
+ /** @internal */
445
+ get state(): QBState<Entity>;
446
+ protected readonly platform: AbstractSqlPlatform;
447
+ /**
448
+ * @internal
449
+ */
450
+ constructor(
451
+ entityName: EntityName<Entity> | QueryBuilder<Entity, any, any, any>,
452
+ metadata: MetadataStorage,
453
+ driver: AbstractSqlDriver,
454
+ context?: Transaction | undefined,
455
+ alias?: string,
456
+ connectionType?: ConnectionType | undefined,
457
+ em?: SqlEntityManager | undefined,
458
+ loggerContext?: (LoggingOptions & Dictionary) | undefined,
459
+ );
460
+ /**
461
+ * Creates a SELECT query, specifying the fields to retrieve.
462
+ *
463
+ * @example
464
+ * ```ts
465
+ * // Select specific fields
466
+ * const qb = em.createQueryBuilder(User, 'u');
467
+ * qb.select(['u.id', 'u.name', 'u.email']);
468
+ *
469
+ * // Select with raw expressions
470
+ * qb.select([raw('count(*) as total')]);
471
+ *
472
+ * // Select with aliases (works for regular and formula properties)
473
+ * qb.select(['id', 'fullName as displayName']);
474
+ * qb.select(['id', sql.ref('fullName').as('displayName')]);
475
+ *
476
+ * // Select with distinct
477
+ * qb.select('*', true);
478
+ * ```
479
+ */
480
+ select<const F extends readonly Field<Entity, RootAlias, Context>[]>(
481
+ fields: F,
482
+ distinct?: boolean,
483
+ ): SelectQueryBuilder<
484
+ Entity,
485
+ RootAlias,
486
+ Hint,
487
+ Context,
488
+ RawAliases | ExtractRawAliases<F>,
489
+ ExtractRootFields<F[number] & string, RootAlias, Context>,
490
+ CTEs
491
+ >;
492
+ /**
493
+ * Creates a SELECT query, specifying the fields to retrieve.
494
+ *
495
+ * @example
496
+ * ```ts
497
+ * // Select specific fields
498
+ * const qb = em.createQueryBuilder(User, 'u');
499
+ * qb.select(['u.id', 'u.name', 'u.email']);
500
+ *
501
+ * // Select with raw expressions
502
+ * qb.select([raw('count(*) as total')]);
503
+ *
504
+ * // Select with distinct
505
+ * qb.select('*', true);
506
+ * ```
507
+ */
508
+ select<const P extends string>(
509
+ fields: readonly NestedAutoPath<Entity, RootAlias, Context, P>[],
510
+ distinct?: boolean,
511
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, ExtractRootFields<P, RootAlias, Context>, CTEs>;
512
+ /**
513
+ * Creates a SELECT query, specifying the fields to retrieve.
514
+ *
515
+ * @example
516
+ * ```ts
517
+ * // Select specific fields with nested paths (e.g., for embedded properties)
518
+ * const qb = em.createQueryBuilder(User, 'u');
519
+ * qb.select('address.city');
520
+ * ```
521
+ */
522
+ select<const P extends string>(
523
+ fields: NestedAutoPath<Entity, RootAlias, Context, P>,
524
+ distinct?: boolean,
525
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, ExtractRootFields<P, RootAlias, Context>, CTEs>;
526
+ /**
527
+ * Creates a SELECT query, specifying the fields to retrieve.
528
+ *
529
+ * @example
530
+ * ```ts
531
+ * // Select specific fields
532
+ * const qb = em.createQueryBuilder(User, 'u');
533
+ * qb.select(['u.id', 'u.name', 'u.email']);
534
+ *
535
+ * // Select with raw expressions
536
+ * qb.select([raw('count(*) as total')]);
537
+ *
538
+ * // Select with distinct
539
+ * qb.select('*', true);
540
+ * ```
541
+ */
542
+ select<const F extends Field<Entity, RootAlias, Context>>(
543
+ fields: F,
544
+ distinct?: boolean,
545
+ ): SelectQueryBuilder<
546
+ Entity,
547
+ RootAlias,
548
+ Hint,
549
+ Context,
550
+ RawAliases | ExtractRawAliases<readonly [F]>,
551
+ ExtractRootFields<F & string, RootAlias, Context>,
552
+ CTEs
553
+ >;
554
+ /**
555
+ * Adds fields to an existing SELECT query.
556
+ */
557
+ addSelect<const F extends Field<Entity, RootAlias, Context> | readonly Field<Entity, RootAlias, Context>[]>(
558
+ fields: F,
559
+ ): SelectQueryBuilder<
560
+ Entity,
561
+ RootAlias,
562
+ Hint,
563
+ Context,
564
+ RawAliases | ExtractRawAliases<F extends readonly unknown[] ? F : [F]>,
565
+ Fields | ExtractRootFields<F extends readonly (infer U)[] ? U & string : F & string, RootAlias, Context>,
566
+ CTEs
567
+ >;
568
+ distinct(): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
569
+ /** postgres only */
570
+ distinctOn<const F extends readonly Field<Entity, RootAlias, Context>[]>(
571
+ fields: F,
572
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
573
+ /** postgres only */
574
+ distinctOn<F extends Field<Entity, RootAlias, Context>>(
575
+ fields: F,
576
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
577
+ /**
578
+ * Creates an INSERT query with the given data.
579
+ *
580
+ * @example
581
+ * ```ts
582
+ * await em.createQueryBuilder(User)
583
+ * .insert({ name: 'John', email: 'john@example.com' })
584
+ * .execute();
585
+ *
586
+ * // Bulk insert
587
+ * await em.createQueryBuilder(User)
588
+ * .insert([{ name: 'John' }, { name: 'Jane' }])
589
+ * .execute();
590
+ * ```
591
+ */
592
+ insert(
593
+ data: RequiredEntityData<Entity> | RequiredEntityData<Entity>[],
594
+ ): InsertQueryBuilder<Entity, RootAlias, Context>;
595
+ /**
596
+ * Creates an UPDATE query with the given data.
597
+ * Use `where()` to specify which rows to update.
598
+ *
599
+ * @example
600
+ * ```ts
601
+ * await em.createQueryBuilder(User)
602
+ * .update({ name: 'John Doe' })
603
+ * .where({ id: 1 })
604
+ * .execute();
605
+ * ```
606
+ */
607
+ update(data: EntityData<Entity>): UpdateQueryBuilder<Entity, RootAlias, Context>;
608
+ /**
609
+ * Creates a DELETE query.
610
+ * Use `where()` to specify which rows to delete.
611
+ *
612
+ * @example
613
+ * ```ts
614
+ * await em.createQueryBuilder(User)
615
+ * .delete()
616
+ * .where({ id: 1 })
617
+ * .execute();
618
+ *
619
+ * // Or pass the condition directly
620
+ * await em.createQueryBuilder(User)
621
+ * .delete({ isActive: false })
622
+ * .execute();
623
+ * ```
624
+ */
625
+ delete(cond?: QBFilterQuery<Entity, RootAlias, Context, RawAliases>): DeleteQueryBuilder<Entity, RootAlias, Context>;
626
+ /**
627
+ * Creates a TRUNCATE query to remove all rows from the table.
628
+ */
629
+ truncate(): TruncateQueryBuilder<Entity>;
630
+ /**
631
+ * Creates a COUNT query to count matching rows.
632
+ *
633
+ * @example
634
+ * ```ts
635
+ * const count = await em.createQueryBuilder(User)
636
+ * .count()
637
+ * .where({ isActive: true })
638
+ * .execute('get');
639
+ * ```
640
+ */
641
+ count<F extends Field<Entity, RootAlias, Context>>(field?: F | F[], distinct?: boolean): CountQueryBuilder<Entity>;
642
+ /**
643
+ * Adds a JOIN clause to the query for an entity relation.
644
+ *
645
+ * @example
646
+ * ```ts
647
+ * const qb = em.createQueryBuilder(Book, 'b');
648
+ * qb.select('*')
649
+ * .join('b.author', 'a')
650
+ * .where({ 'a.name': 'John' });
651
+ * ```
652
+ */
653
+ join<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(
654
+ field: Field,
655
+ alias: Alias,
656
+ cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>,
657
+ type?: JoinType,
658
+ path?: string,
659
+ schema?: string,
660
+ ): SelectQueryBuilder<
661
+ Entity,
662
+ RootAlias,
663
+ ModifyHint<RootAlias, Context, Hint, Field> & {},
664
+ ModifyContext<Entity, Context, Field, Alias>,
665
+ RawAliases,
666
+ '*',
667
+ CTEs
668
+ >;
669
+ /**
670
+ * Adds a JOIN clause to the query for a subquery.
671
+ */
672
+ join<Alias extends string>(
673
+ field: RawQueryFragment | QueryBuilder<any>,
674
+ alias: Alias,
675
+ cond?: RawJoinCondition,
676
+ type?: JoinType,
677
+ path?: string,
678
+ schema?: string,
679
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
680
+ /**
681
+ * Adds an INNER JOIN clause to the query for an entity relation.
682
+ */
683
+ innerJoin<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(
684
+ field: Field,
685
+ alias: Alias,
686
+ cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>,
687
+ schema?: string,
688
+ ): SelectQueryBuilder<
689
+ Entity,
690
+ RootAlias,
691
+ ModifyHint<RootAlias, Context, Hint, Field> & {},
692
+ ModifyContext<Entity, Context, Field, Alias>,
693
+ RawAliases,
694
+ '*',
695
+ CTEs
696
+ >;
697
+ /**
698
+ * Adds an INNER JOIN clause to the query for a subquery.
699
+ */
700
+ innerJoin<Alias extends string>(
701
+ field: RawQueryFragment | QueryBuilder<any>,
702
+ alias: Alias,
703
+ cond?: RawJoinCondition,
704
+ schema?: string,
705
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
706
+ innerJoinLateral<Alias extends string>(
707
+ field: RawQueryFragment | QueryBuilder<any>,
708
+ alias: Alias,
709
+ cond?: RawJoinCondition,
710
+ schema?: string,
711
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
712
+ /**
713
+ * Adds a LEFT JOIN clause to the query for an entity relation.
714
+ */
715
+ leftJoin<Field extends QBField<Entity, RootAlias, Context>, Alias extends string>(
716
+ field: Field,
717
+ alias: Alias,
718
+ cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>,
719
+ schema?: string,
720
+ ): SelectQueryBuilder<
721
+ Entity,
722
+ RootAlias,
723
+ ModifyHint<RootAlias, Context, Hint, Field> & {},
724
+ ModifyContext<Entity, Context, Field, Alias>,
725
+ RawAliases,
726
+ '*',
727
+ CTEs
728
+ >;
729
+ /**
730
+ * Adds a LEFT JOIN clause to the query for a subquery.
731
+ */
732
+ leftJoin<Alias extends string>(
733
+ field: RawQueryFragment | QueryBuilder<any>,
734
+ alias: Alias,
735
+ cond?: RawJoinCondition,
736
+ schema?: string,
737
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
738
+ leftJoinLateral<Alias extends string>(
739
+ field: RawQueryFragment | QueryBuilder<any>,
740
+ alias: Alias,
741
+ cond?: RawJoinCondition,
742
+ schema?: string,
743
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, ModifyContext<Entity, Context, string, Alias>, RawAliases, '*', CTEs>;
744
+ /**
745
+ * Adds a JOIN clause and automatically selects the joined entity's fields.
746
+ * This is useful for eager loading related entities.
747
+ *
748
+ * @example
749
+ * ```ts
750
+ * const qb = em.createQueryBuilder(Book, 'b');
751
+ * qb.select('*')
752
+ * .joinAndSelect('b.author', 'a')
753
+ * .where({ 'a.name': 'John' });
754
+ * ```
755
+ */
756
+ joinAndSelect<
757
+ Field extends QBField<Entity, RootAlias, Context>,
758
+ Alias extends string,
759
+ const JoinFields extends
760
+ | readonly [
761
+ JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>,
762
+ ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[],
763
+ ]
764
+ | undefined = undefined,
765
+ >(
766
+ field: Field | [Field, RawQueryFragment | QueryBuilder<any>],
767
+ alias: Alias,
768
+ cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>,
769
+ type?: JoinType,
770
+ path?: string,
771
+ fields?: JoinFields,
772
+ schema?: string,
773
+ ): SelectQueryBuilder<
774
+ Entity,
775
+ RootAlias,
776
+ ModifyHint<RootAlias, Context, Hint, Field, true> & {},
777
+ ModifyContext<Entity, Context, Field, Alias, true>,
778
+ RawAliases,
779
+ ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>,
780
+ CTEs
781
+ >;
782
+ leftJoinAndSelect<
783
+ Field extends QBField<Entity, RootAlias, Context>,
784
+ Alias extends string,
785
+ const JoinFields extends
786
+ | readonly [
787
+ JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>,
788
+ ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[],
789
+ ]
790
+ | undefined = undefined,
791
+ >(
792
+ field: Field | [Field, RawQueryFragment | QueryBuilder<any>],
793
+ alias: Alias,
794
+ cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>,
795
+ fields?: JoinFields,
796
+ schema?: string,
797
+ ): SelectQueryBuilder<
798
+ Entity,
799
+ RootAlias,
800
+ ModifyHint<RootAlias, Context, Hint, Field, true> & {},
801
+ ModifyContext<Entity, Context, Field, Alias, true>,
802
+ RawAliases,
803
+ ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>,
804
+ CTEs
805
+ >;
806
+ leftJoinLateralAndSelect<
807
+ Field extends QBField<Entity, RootAlias, Context>,
808
+ Alias extends string,
809
+ const JoinFields extends
810
+ | readonly [
811
+ JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>,
812
+ ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[],
813
+ ]
814
+ | undefined = undefined,
815
+ >(
816
+ field: [Field, RawQueryFragment | QueryBuilder<any>],
817
+ alias: Alias,
818
+ cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>,
819
+ fields?: JoinFields,
820
+ schema?: string,
821
+ ): SelectQueryBuilder<
822
+ Entity,
823
+ RootAlias,
824
+ ModifyHint<RootAlias, Context, Hint, Field, true> & {},
825
+ ModifyContext<Entity, Context, Field, Alias, true>,
826
+ RawAliases,
827
+ ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>,
828
+ CTEs
829
+ >;
830
+ innerJoinAndSelect<
831
+ Field extends QBField<Entity, RootAlias, Context>,
832
+ Alias extends string,
833
+ const JoinFields extends
834
+ | readonly [
835
+ JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>,
836
+ ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[],
837
+ ]
838
+ | undefined = undefined,
839
+ >(
840
+ field: Field | [Field, RawQueryFragment | QueryBuilder<any>],
841
+ alias: Alias,
842
+ cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>,
843
+ fields?: JoinFields,
844
+ schema?: string,
845
+ ): SelectQueryBuilder<
846
+ Entity,
847
+ RootAlias,
848
+ ModifyHint<RootAlias, Context, Hint, Field, true> & {},
849
+ ModifyContext<Entity, Context, Field, Alias, true>,
850
+ RawAliases,
851
+ ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>,
852
+ CTEs
853
+ >;
854
+ innerJoinLateralAndSelect<
855
+ Field extends QBField<Entity, RootAlias, Context>,
856
+ Alias extends string,
857
+ const JoinFields extends
858
+ | readonly [
859
+ JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>,
860
+ ...JoinSelectField<JoinedEntityType<Entity, Context, Field & string>, Alias>[],
861
+ ]
862
+ | undefined = undefined,
863
+ >(
864
+ field: [Field, RawQueryFragment | QueryBuilder<any>],
865
+ alias: Alias,
866
+ cond?: JoinCondition<JoinedEntityType<Entity, Context, Field & string>, Alias>,
867
+ fields?: JoinFields,
868
+ schema?: string,
869
+ ): SelectQueryBuilder<
870
+ Entity,
871
+ RootAlias,
872
+ ModifyHint<RootAlias, Context, Hint, Field, true> & {},
873
+ ModifyContext<Entity, Context, Field, Alias, true>,
874
+ RawAliases,
875
+ ModifyFields<Fields, RootAlias, Context, Field, Alias, JoinFields>,
876
+ CTEs
877
+ >;
878
+ protected getFieldsForJoinedLoad(
879
+ prop: EntityProperty<Entity>,
880
+ alias: string,
881
+ explicitFields?: readonly string[],
882
+ ): InternalField<Entity>[];
883
+ /**
884
+ * Apply filters to the QB where condition.
885
+ */
886
+ applyFilters(filterOptions?: FilterOptions): Promise<void>;
887
+ /**
888
+ * @internal
889
+ */
890
+ scheduleFilterCheck(path: string): void;
891
+ /**
892
+ * @internal
893
+ */
894
+ applyJoinedFilters(em: EntityManager, filterOptions: FilterOptions | undefined): Promise<void>;
895
+ withSubQuery(subQuery: RawQueryFragment | NativeQueryBuilder, alias: string): this;
896
+ /**
897
+ * Adds a WHERE clause to the query using an object condition.
898
+ *
899
+ * Supports filtering by:
900
+ * - Direct entity properties: `{ name: 'John' }`
901
+ * - Nested relations/embedded: `{ author: { name: 'John' } }`
902
+ * - Aliased properties after joins: `{ 'a.name': 'John' }` or `{ 'b.title': 'test' }`
903
+ * - Filter operators: `{ age: { $gte: 18 } }`
904
+ * - Logical operators: `{ $or: [{ name: 'John' }, { name: 'Jane' }] }`
905
+ *
906
+ * @example
907
+ * ```ts
908
+ * // Filter by entity properties
909
+ * qb.where({ name: 'John', age: { $gte: 18 } });
910
+ *
911
+ * // Filter by nested relation
912
+ * qb.where({ author: { name: 'John' } });
913
+ *
914
+ * // Filter by aliased properties after join
915
+ * qb.leftJoin('a.books', 'b').where({ 'b.title': 'test' });
916
+ *
917
+ * // Combine with logical operators
918
+ * qb.where({ $or: [{ status: 'active' }, { role: 'admin' }] });
919
+ * ```
920
+ */
921
+ where(cond: QBFilterQuery<Entity, RootAlias, Context, RawAliases>, operator?: keyof typeof GroupOperator): this;
922
+ /**
923
+ * Adds a WHERE clause to the query using a raw SQL string or fragment.
924
+ *
925
+ * @example
926
+ * ```ts
927
+ * // Raw SQL with parameters
928
+ * qb.where('name = ? AND age >= ?', ['John', 18]);
929
+ *
930
+ * // Using raw() helper
931
+ * qb.where(raw('lower(name) = ?', ['john']));
932
+ * ```
933
+ */
934
+ where(cond: string | RawQueryFragment, params?: any[], operator?: keyof typeof GroupOperator): this;
935
+ /**
936
+ * Adds an AND WHERE clause to the query using an object condition.
937
+ *
938
+ * @example
939
+ * ```ts
940
+ * qb.where({ status: 'active' }).andWhere({ role: 'admin' });
941
+ * qb.where({ name: 'John' }).andWhere({ 'b.title': 'test' });
942
+ * ```
943
+ */
944
+ andWhere(cond: QBFilterQuery<Entity, RootAlias, Context, RawAliases>): this;
945
+ /**
946
+ * Adds an AND WHERE clause to the query using a raw SQL string or fragment.
947
+ *
948
+ * @example
949
+ * ```ts
950
+ * qb.where({ status: 'active' }).andWhere('age >= ?', [18]);
951
+ * ```
952
+ */
953
+ andWhere(cond: string | RawQueryFragment, params?: any[]): this;
954
+ /**
955
+ * Adds an OR WHERE clause to the query using an object condition.
956
+ *
957
+ * @example
958
+ * ```ts
959
+ * qb.where({ status: 'active' }).orWhere({ role: 'admin' });
960
+ * qb.where({ name: 'John' }).orWhere({ name: 'Jane' });
961
+ * ```
962
+ */
963
+ orWhere(cond: QBFilterQuery<Entity, RootAlias, Context, RawAliases>): this;
964
+ /**
965
+ * Adds an OR WHERE clause to the query using a raw SQL string or fragment.
966
+ *
967
+ * @example
968
+ * ```ts
969
+ * qb.where({ status: 'active' }).orWhere('role = ?', ['admin']);
970
+ * ```
971
+ */
972
+ orWhere(cond: string | RawQueryFragment, params?: any[]): this;
973
+ /**
974
+ * Adds an ORDER BY clause to the query, replacing any existing order.
975
+ *
976
+ * @example
977
+ * ```ts
978
+ * qb.orderBy({ name: 'asc', createdAt: 'desc' });
979
+ * qb.orderBy([{ name: 'asc' }, { createdAt: 'desc' }]);
980
+ * qb.orderBy({ profile: { bio: 'asc' } }); // nested via object
981
+ * qb.orderBy({ 'profile.bio': 'asc' }); // nested via dot notation
982
+ * ```
983
+ */
984
+ orderBy(
985
+ orderBy:
986
+ | ContextOrderByMap<Entity, RootAlias, Context, RawAliases>
987
+ | ContextOrderByMap<Entity, RootAlias, Context, RawAliases>[],
988
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
989
+ /**
990
+ * Adds an ORDER BY clause to the query, replacing any existing order.
991
+ *
992
+ * @example
993
+ * ```ts
994
+ * qb.orderBy({ name: 'asc', createdAt: 'desc' });
995
+ * qb.orderBy([{ name: 'asc' }, { createdAt: 'desc' }]);
996
+ * qb.orderBy({ profile: { bio: 'asc' } }); // nested via object
997
+ * qb.orderBy({ 'profile.bio': 'asc' }); // nested via dot notation
998
+ * ```
999
+ */
1000
+ orderBy<const T extends Record<string, QueryOrderKeysFlat>>(
1001
+ orderBy: T & {
1002
+ [K in keyof T]: K extends NestedAutoPath<Entity, RootAlias, Context, K & string>
1003
+ ? T[K]
1004
+ : K extends RawAliases
1005
+ ? T[K]
1006
+ : never;
1007
+ },
1008
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
1009
+ /**
1010
+ * Adds additional ORDER BY clause without replacing existing order.
1011
+ */
1012
+ andOrderBy(
1013
+ orderBy:
1014
+ | ContextOrderByMap<Entity, RootAlias, Context, RawAliases>
1015
+ | ContextOrderByMap<Entity, RootAlias, Context, RawAliases>[],
1016
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
1017
+ /**
1018
+ * Adds additional ORDER BY clause without replacing existing order.
1019
+ */
1020
+ andOrderBy<const T extends Record<string, QueryOrderKeysFlat>>(
1021
+ orderBy: T & {
1022
+ [K in keyof T]: K extends NestedAutoPath<Entity, RootAlias, Context, K & string>
1023
+ ? T[K]
1024
+ : K extends RawAliases
1025
+ ? T[K]
1026
+ : never;
1027
+ },
1028
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
1029
+ private processOrderBy;
1030
+ /** Collect custom aliases from select fields (stored as 'resolved as alias' strings by select()). */
1031
+ private getSelectAliases;
1032
+ /**
1033
+ * Adds a GROUP BY clause to the query.
1034
+ *
1035
+ * @example
1036
+ * ```ts
1037
+ * qb.select([raw('count(*) as count'), 'status'])
1038
+ * .groupBy('status');
1039
+ * ```
1040
+ */
1041
+ groupBy<const F extends readonly Field<Entity, RootAlias, Context>[]>(
1042
+ fields: F,
1043
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
1044
+ /**
1045
+ * Adds a GROUP BY clause to the query.
1046
+ *
1047
+ * @example
1048
+ * ```ts
1049
+ * qb.select([raw('count(*) as count'), 'status'])
1050
+ * .groupBy('status');
1051
+ * ```
1052
+ */
1053
+ groupBy<F extends Field<Entity, RootAlias, Context>>(
1054
+ fields: F,
1055
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
1056
+ /**
1057
+ * Adds a GROUP BY clause to the query.
1058
+ *
1059
+ * @example
1060
+ * ```ts
1061
+ * qb.select([raw('count(*) as count'), 'status'])
1062
+ * .groupBy('status');
1063
+ * ```
1064
+ */
1065
+ groupBy<const P extends string>(
1066
+ fields: NestedAutoPath<Entity, RootAlias, Context, P> | readonly NestedAutoPath<Entity, RootAlias, Context, P>[],
1067
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
1068
+ /**
1069
+ * Adds a HAVING clause to the query, typically used with GROUP BY.
1070
+ *
1071
+ * @example
1072
+ * ```ts
1073
+ * qb.select([raw('count(*) as count'), 'status'])
1074
+ * .groupBy('status')
1075
+ * .having({ count: { $gt: 5 } });
1076
+ * ```
1077
+ */
1078
+ having(
1079
+ cond?: QBFilterQuery<Entity, RootAlias, Context, RawAliases> | string,
1080
+ params?: any[],
1081
+ operator?: keyof typeof GroupOperator,
1082
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
1083
+ andHaving(
1084
+ cond?: QBFilterQuery<Entity, RootAlias, Context, RawAliases> | string,
1085
+ params?: any[],
1086
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
1087
+ orHaving(
1088
+ cond?: QBFilterQuery<Entity, RootAlias, Context, RawAliases> | string,
1089
+ params?: any[],
1090
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
1091
+ onConflict<F extends Field<Entity, RootAlias, Context>>(
1092
+ fields?: F | F[] | RawQueryFragment,
1093
+ ): InsertQueryBuilder<Entity, RootAlias, Context>;
1094
+ ignore(): this;
1095
+ merge<const P extends string>(data: readonly NestedAutoPath<Entity, RootAlias, Context, P>[]): this;
1096
+ merge<F extends Field<Entity, RootAlias, Context>>(data?: EntityData<Entity> | F[]): this;
1097
+ returning<F extends Field<Entity, RootAlias, Context>>(fields?: F | F[]): this;
1098
+ /**
1099
+ * @internal
1100
+ */
1101
+ populate(
1102
+ populate: PopulateOptions<Entity>[],
1103
+ populateWhere?: ObjectQuery<Entity> | PopulateHint | `${PopulateHint}`,
1104
+ populateFilter?: ObjectQuery<Entity> | PopulateHint | `${PopulateHint}`,
1105
+ ): this;
1106
+ /**
1107
+ * Sets a LIMIT clause to restrict the number of results.
1108
+ *
1109
+ * @example
1110
+ * ```ts
1111
+ * qb.select('*').limit(10); // First 10 results
1112
+ * qb.select('*').limit(10, 20); // 10 results starting from offset 20
1113
+ * ```
1114
+ */
1115
+ limit(
1116
+ limit?: number,
1117
+ offset?: number,
1118
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
1119
+ /**
1120
+ * Sets an OFFSET clause to skip a number of results.
1121
+ *
1122
+ * @example
1123
+ * ```ts
1124
+ * qb.select('*').limit(10).offset(20); // Results 21-30
1125
+ * ```
1126
+ */
1127
+ offset(offset?: number): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
1128
+ withSchema(schema?: string): this;
1129
+ setLockMode(mode?: LockMode, tables?: string[]): this;
1130
+ setFlushMode(flushMode?: FlushMode): this;
1131
+ setFlag(flag: QueryFlag): this;
1132
+ unsetFlag(flag: QueryFlag): this;
1133
+ hasFlag(flag: QueryFlag): boolean;
1134
+ cache(config?: boolean | number | [string, number]): this;
1135
+ /**
1136
+ * Adds index hint to the FROM clause.
1137
+ */
1138
+ indexHint(sql: string | undefined): this;
1139
+ /**
1140
+ * Adds COLLATE clause to ORDER BY expressions.
1141
+ */
1142
+ collation(collation: string | undefined): this;
1143
+ /**
1144
+ * Prepend comment to the sql query using the syntax `/* ... *&#8205;/`. Some characters are forbidden such as `/*, *&#8205;/` and `?`.
1145
+ */
1146
+ comment(comment: string | string[] | undefined): this;
1147
+ /**
1148
+ * Add hints to the query using comment-like syntax `/*+ ... *&#8205;/`. MySQL and Oracle use this syntax for optimizer hints.
1149
+ * Also various DB proxies and routers use this syntax to pass hints to alter their behavior. In other dialects the hints
1150
+ * are ignored as simple comments.
1151
+ */
1152
+ hintComment(comment: string | string[] | undefined): this;
1153
+ /**
1154
+ * Specifies FROM which entity's table select/update/delete will be executed, removing all previously set FROM-s.
1155
+ * Allows setting a main string alias of the selection data.
1156
+ */
1157
+ from<Entity extends object>(
1158
+ target: QueryBuilder<Entity>,
1159
+ aliasName?: string,
1160
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
1161
+ /**
1162
+ * Specifies FROM which entity's table select/update/delete will be executed, removing all previously set FROM-s.
1163
+ * Allows setting a main string alias of the selection data.
1164
+ */
1165
+ from<Entity extends object>(
1166
+ target: EntityName<Entity>,
1167
+ ): SelectQueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
1168
+ /**
1169
+ * Specifies a CTE name as the FROM source, with full type safety.
1170
+ * The entity type is inferred from the CTE definition passed to `.with()`.
1171
+ */
1172
+ from<Name extends string & keyof CTEs, Alias extends string = Name>(
1173
+ target: Name,
1174
+ aliasName?: Alias,
1175
+ ): SelectQueryBuilder<CTEs[Name], Alias, never, never, never, '*', CTEs>;
1176
+ getNativeQuery(processVirtualEntity?: boolean): NativeQueryBuilder;
1177
+ protected processReturningStatement(
1178
+ qb: NativeQueryBuilder,
1179
+ meta?: EntityMetadata,
1180
+ data?: Dictionary,
1181
+ returning?: Field<any>[],
1182
+ ): void;
1183
+ /**
1184
+ * Returns the query with parameters as wildcards.
1185
+ */
1186
+ getQuery(): string;
1187
+ /**
1188
+ * Returns raw fragment representation of this QueryBuilder.
1189
+ */
1190
+ toRaw(): RawQueryFragment;
1191
+ toQuery(): {
1192
+ sql: string;
1193
+ params: readonly unknown[];
1194
+ };
1195
+ /**
1196
+ * Returns the list of all parameters for this query.
1197
+ */
1198
+ getParams(): readonly unknown[];
1199
+ /**
1200
+ * Returns raw interpolated query string with all the parameters inlined.
1201
+ */
1202
+ getFormattedQuery(): string;
1203
+ /**
1204
+ * @internal
1205
+ */
1206
+ getAliasForJoinPath(path?: string | JoinOptions, options?: ICriteriaNodeProcessOptions): string | undefined;
1207
+ /**
1208
+ * @internal
1209
+ */
1210
+ getJoinForPath(path: string, options?: ICriteriaNodeProcessOptions): JoinOptions | undefined;
1211
+ /**
1212
+ * @internal
1213
+ */
1214
+ getNextAlias(entityName?: string | EntityName): string;
1215
+ /**
1216
+ * Registers a join for a specific polymorphic target type.
1217
+ * Used by the driver to create per-target LEFT JOINs for JOINED loading.
1218
+ * @internal
1219
+ */
1220
+ addPolymorphicJoin(
1221
+ prop: EntityProperty,
1222
+ targetMeta: EntityMetadata,
1223
+ ownerAlias: string,
1224
+ alias: string,
1225
+ type: JoinType,
1226
+ path: string,
1227
+ schema?: string,
1228
+ ): void;
1229
+ /**
1230
+ * @internal
1231
+ */
1232
+ getAliasMap(): Dictionary<EntityName>;
1233
+ /**
1234
+ * Executes this QB and returns the raw results, mapped to the property names (unless disabled via last parameter).
1235
+ * Use `method` to specify what kind of result you want to get (array/single/meta).
1236
+ */
1237
+ execute<U = any>(method?: 'all' | 'get' | 'run', options?: ExecuteOptions | boolean): Promise<U>;
1238
+ private getConnection;
1239
+ /**
1240
+ * Executes the query and returns an async iterable (async generator) that yields results one by one.
1241
+ * By default, the results are merged and mapped to entity instances, without adding them to the identity map.
1242
+ * You can disable merging and mapping by passing the options `{ mergeResults: false, mapResults: false }`.
1243
+ * This is useful for processing large datasets without loading everything into memory at once.
1244
+ *
1245
+ * ```ts
1246
+ * const qb = em.createQueryBuilder(Book, 'b');
1247
+ * qb.select('*').where({ title: '1984' }).leftJoinAndSelect('b.author', 'a');
1248
+ *
1249
+ * for await (const book of qb.stream()) {
1250
+ * // book is an instance of Book entity
1251
+ * console.log(book.title, book.author.name);
1252
+ * }
1253
+ * ```
1254
+ */
1255
+ stream(options?: QBStreamOptions): AsyncIterableIterator<Loaded<Entity, Hint, Fields>>;
1256
+ /**
1257
+ * Alias for `qb.getResultList()`
1258
+ */
1259
+ getResult(): Promise<Loaded<Entity, Hint, Fields>[]>;
1260
+ /**
1261
+ * Executes the query, returning array of results mapped to entity instances.
1262
+ */
1263
+ getResultList(limit?: number): Promise<Loaded<Entity, Hint, Fields>[]>;
1264
+ private propagatePopulateHint;
1265
+ private mapResult;
1266
+ private mapResults;
1267
+ /**
1268
+ * Executes the query, returning the first result or null
1269
+ */
1270
+ getSingleResult(): Promise<Loaded<Entity, Hint, Fields> | null>;
1271
+ /**
1272
+ * Executes count query (without offset and limit), returning total count of results
1273
+ */
1274
+ getCount<F extends Field<Entity, RootAlias, Context>>(field?: F | F[], distinct?: boolean): Promise<number>;
1275
+ /**
1276
+ * Executes the query, returning both array of results and total count query (without offset and limit).
1277
+ */
1278
+ getResultAndCount(): Promise<[Loaded<Entity, Hint, Fields>[], number]>;
1279
+ /**
1280
+ * Returns native query builder instance with sub-query aliased with given alias.
1281
+ */
1282
+ as(alias: string): NativeQueryBuilder;
1283
+ /**
1284
+ * Returns native query builder instance with sub-query aliased with given alias.
1285
+ * You can provide the target entity name as the first parameter and use the second parameter to point to an existing property to infer its field name.
1286
+ */
1287
+ as<T>(targetEntity: EntityName<T>, alias: EntityKey<T>): NativeQueryBuilder;
1288
+ /**
1289
+ * Combines the current query with one or more other queries using `UNION ALL`.
1290
+ * All queries must select the same columns. Returns a `QueryBuilder` that
1291
+ * can be used with `$in`, passed to `qb.from()`, or converted via `.getQuery()`,
1292
+ * `.getParams()`, `.toQuery()`, `.toRaw()`, etc.
1293
+ *
1294
+ * ```ts
1295
+ * const qb1 = em.createQueryBuilder(Employee).select('id').where(condition1);
1296
+ * const qb2 = em.createQueryBuilder(Employee).select('id').where(condition2);
1297
+ * const qb3 = em.createQueryBuilder(Employee).select('id').where(condition3);
1298
+ * const subquery = qb1.unionAll(qb2, qb3);
1299
+ *
1300
+ * const results = await em.find(Employee, { id: { $in: subquery } });
1301
+ * ```
1302
+ */
1303
+ unionAll(...others: (QueryBuilder<any> | NativeQueryBuilder)[]): QueryBuilder<Entity>;
1304
+ /**
1305
+ * Combines the current query with one or more other queries using `UNION` (with deduplication).
1306
+ * All queries must select the same columns. Returns a `QueryBuilder` that
1307
+ * can be used with `$in`, passed to `qb.from()`, or converted via `.getQuery()`,
1308
+ * `.getParams()`, `.toQuery()`, `.toRaw()`, etc.
1309
+ *
1310
+ * ```ts
1311
+ * const qb1 = em.createQueryBuilder(Employee).select('id').where(condition1);
1312
+ * const qb2 = em.createQueryBuilder(Employee).select('id').where(condition2);
1313
+ * const subquery = qb1.union(qb2);
1314
+ *
1315
+ * const results = await em.find(Employee, { id: { $in: subquery } });
1316
+ * ```
1317
+ */
1318
+ union(...others: (QueryBuilder<any> | NativeQueryBuilder)[]): QueryBuilder<Entity>;
1319
+ private buildUnionQuery;
1320
+ /**
1321
+ * Adds a Common Table Expression (CTE) to the query.
1322
+ * When a `QueryBuilder` is passed, its entity type is tracked for type-safe `from()`.
1323
+ *
1324
+ * @example
1325
+ * ```ts
1326
+ * const recentBooks = em.createQueryBuilder(Book, 'b').select('*').where({ ... });
1327
+ * const qb = em.createQueryBuilder(Author, 'a')
1328
+ * .with('recent_books', recentBooks)
1329
+ * .select('*')
1330
+ * .from('recent_books', 'rb'); // entity type inferred as Book
1331
+ * ```
1332
+ */
1333
+ with<Name extends string, Q extends QueryBuilder<any>>(
1334
+ name: Name,
1335
+ query: Q,
1336
+ options?: CteOptions,
1337
+ ): QueryBuilder<
1338
+ Entity,
1339
+ RootAlias,
1340
+ Hint,
1341
+ Context,
1342
+ RawAliases,
1343
+ Fields,
1344
+ CTEs & Record<Name, Q extends QueryBuilder<infer T> ? T : object>
1345
+ >;
1346
+ /**
1347
+ * Adds a Common Table Expression (CTE) to the query using a `NativeQueryBuilder` or raw SQL fragment.
1348
+ * The CTE name is tracked but without entity type inference — use `from()` to query from it.
1349
+ */
1350
+ with<Name extends string>(
1351
+ name: Name,
1352
+ query: NativeQueryBuilder | RawQueryFragment,
1353
+ options?: CteOptions,
1354
+ ): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs & Record<Name, object>>;
1355
+ /**
1356
+ * Adds a recursive Common Table Expression (CTE) to the query.
1357
+ * When a `QueryBuilder` is passed, its entity type is tracked for type-safe `from()`.
1358
+ *
1359
+ * @example
1360
+ * ```ts
1361
+ * const base = em.createQueryBuilder(Category).select('*').where({ parent: null });
1362
+ * const rec = em.createQueryBuilder(Category, 'c').select('c.*')
1363
+ * .leftJoin('c.parent', 'ct', { id: sql.ref('c.parentId') });
1364
+ * const qb = em.createQueryBuilder(Category)
1365
+ * .withRecursive('category_tree', base.unionAll(rec))
1366
+ * .select('*')
1367
+ * .from('category_tree', 'ct'); // entity type inferred as Category
1368
+ * ```
1369
+ */
1370
+ withRecursive<Name extends string, Q extends QueryBuilder<any>>(
1371
+ name: Name,
1372
+ query: Q,
1373
+ options?: CteOptions,
1374
+ ): QueryBuilder<
1375
+ Entity,
1376
+ RootAlias,
1377
+ Hint,
1378
+ Context,
1379
+ RawAliases,
1380
+ Fields,
1381
+ CTEs & Record<Name, Q extends QueryBuilder<infer T> ? T : object>
1382
+ >;
1383
+ /**
1384
+ * Adds a recursive Common Table Expression (CTE) to the query using a `NativeQueryBuilder` or raw SQL fragment.
1385
+ * The CTE name is tracked but without entity type inference — use `from()` to query from it.
1386
+ */
1387
+ withRecursive<Name extends string>(
1388
+ name: Name,
1389
+ query: NativeQueryBuilder | RawQueryFragment,
1390
+ options?: CteOptions,
1391
+ ): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs & Record<Name, object>>;
1392
+ private addCte;
1393
+ clone(
1394
+ reset?: boolean | (keyof QBState<Entity>)[],
1395
+ preserve?: (keyof QBState<Entity>)[],
1396
+ ): QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs>;
1397
+ /**
1398
+ * Sets logger context for this query builder.
1399
+ */
1400
+ setLoggerContext(context: LoggingOptions & Dictionary): void;
1401
+ /**
1402
+ * Gets logger context for this query builder.
1403
+ */
1404
+ getLoggerContext<T extends Dictionary & LoggingOptions = Dictionary>(): T;
1405
+ private fromVirtual;
1406
+ /**
1407
+ * Adds a join from a property object. Used internally for TPT joins where the property
1408
+ * is synthetic (not in entity.properties) but defined on metadata (e.g., tptParentProp).
1409
+ * The caller must create the alias first via createAlias().
1410
+ * @internal
1411
+ */
1412
+ addPropertyJoin(
1413
+ prop: EntityProperty,
1414
+ ownerAlias: string,
1415
+ alias: string,
1416
+ type: JoinType,
1417
+ path: string,
1418
+ schema?: string,
1419
+ ): string;
1420
+ private joinReference;
1421
+ protected prepareFields<T>(
1422
+ fields: InternalField<T>[],
1423
+ type?: 'where' | 'groupBy' | 'sub-query',
1424
+ schema?: string,
1425
+ ): (string | RawQueryFragment)[];
1426
+ /**
1427
+ * Resolves nested paths like `a.books.title` to their actual field references.
1428
+ * Auto-joins relations as needed and returns `{alias}.{field}`.
1429
+ * For embeddeds: navigates into flattened embeddeds to return the correct field name.
1430
+ */
1431
+ protected resolveNestedPath(field: string): string | string[];
1432
+ protected init(type: QueryType, data?: any, cond?: any): this;
1433
+ private getQueryBase;
1434
+ private applyDiscriminatorCondition;
1435
+ /**
1436
+ * Ensures TPT joins are applied. Can be called early before finalize() to populate
1437
+ * the _tptAlias map for use in join resolution. Safe to call multiple times.
1438
+ * @internal
1439
+ */
1440
+ ensureTPTJoins(): void;
1441
+ /**
1442
+ * For TPT (Table-Per-Type) inheritance: INNER JOINs parent tables.
1443
+ * When querying a child entity, we need to join all parent tables.
1444
+ * Field selection is handled separately in addTPTParentFields().
1445
+ */
1446
+ private applyTPTJoins;
1447
+ /**
1448
+ * For TPT inheritance: adds field selections from parent tables.
1449
+ */
1450
+ private addTPTParentFields;
1451
+ /**
1452
+ * For TPT polymorphic queries: LEFT JOINs all child tables when querying a TPT base class.
1453
+ * Adds discriminator and child fields to determine and load the concrete type.
1454
+ */
1455
+ private applyTPTPolymorphicJoins;
1456
+ private finalize;
1457
+ /** @internal */
1458
+ processPopulateHint(): void;
1459
+ private processPopulateWhere;
1460
+ private mergeOnConditions;
1461
+ /**
1462
+ * When adding an inner join on a left joined relation, we need to nest them,
1463
+ * otherwise the inner join could discard rows of the root table.
1464
+ */
1465
+ private processNestedJoins;
1466
+ private hasToManyJoins;
1467
+ protected wrapPaginateSubQuery(meta: EntityMetadata): void;
1468
+ /**
1469
+ * Computes the set of populate paths from the _populate hints.
1470
+ */
1471
+ protected getPopulatePaths(): Set<string>;
1472
+ protected normalizeJoinPath(join: JoinOptions, meta: EntityMetadata): string;
1473
+ /**
1474
+ * Transfers WHERE conditions to ORDER BY joins that are not used for population.
1475
+ * This ensures the outer query's ORDER BY uses the same filtered rows as the subquery.
1476
+ * GH #6160
1477
+ */
1478
+ protected transferConditionsForOrderByJoins(
1479
+ meta: EntityMetadata,
1480
+ cond: Dictionary | undefined,
1481
+ populatePaths: Set<string>,
1482
+ ): void;
1483
+ /**
1484
+ * Removes joins that are not used for population or ordering to improve performance.
1485
+ */
1486
+ protected pruneJoinsForPagination(meta: EntityMetadata, populatePaths: Set<string>): void;
1487
+ /**
1488
+ * Transfers WHERE conditions that reference a join alias to the join's ON clause.
1489
+ * This is needed when a join is kept for ORDER BY after pagination wrapping,
1490
+ * so the outer query orders by the same filtered rows as the subquery.
1491
+ * @internal
1492
+ */
1493
+ protected transferConditionsToJoin(cond: Dictionary, join: JoinOptions, path?: string): void;
1494
+ private wrapModifySubQuery;
1495
+ private getSchema;
1496
+ /** @internal */
1497
+ createAlias<U = unknown>(
1498
+ entityName: EntityName<U>,
1499
+ aliasName: string,
1500
+ subQuery?: NativeQueryBuilder | RawQueryFragment,
1501
+ ): Alias<U>;
1502
+ private createMainAlias;
1503
+ private fromSubQuery;
1504
+ private fromEntityName;
1505
+ private fromRawTable;
1506
+ private createQueryBuilderHelper;
1507
+ private ensureFromClause;
1508
+ private ensureNotFinalized;
945
1509
  }
946
- export interface RunQueryBuilder<Entity extends object, RootAlias extends string = never, Context extends object = never, RawAliases extends string = never> extends Omit<QueryBuilder<Entity, RootAlias, never, Context, RawAliases, '*'>, 'getResult' | 'getSingleResult' | 'getResultList' | 'where'> {
947
- where(cond: QBFilterQuery<Entity, RootAlias, Context, RawAliases> | string, params?: keyof typeof GroupOperator | any[], operator?: keyof typeof GroupOperator): this;
948
- execute<Result = QueryResult<Entity>>(method?: 'all' | 'get' | 'run', mapResults?: boolean): Promise<Result>;
1510
+ export interface RunQueryBuilder<
1511
+ Entity extends object,
1512
+ RootAlias extends string = never,
1513
+ Context extends object = never,
1514
+ RawAliases extends string = never,
1515
+ > extends Omit<
1516
+ QueryBuilder<Entity, RootAlias, never, Context, RawAliases, '*'>,
1517
+ 'getResult' | 'getSingleResult' | 'getResultList' | 'where'
1518
+ > {
1519
+ where(
1520
+ cond: QBFilterQuery<Entity, RootAlias, Context, RawAliases> | string,
1521
+ params?: keyof typeof GroupOperator | any[],
1522
+ operator?: keyof typeof GroupOperator,
1523
+ ): this;
1524
+ execute<Result = QueryResult<Entity>>(method?: 'all' | 'get' | 'run', mapResults?: boolean): Promise<Result>;
949
1525
  }
950
1526
  /**
951
1527
  * @internal Optimized DTO type for execute().
@@ -960,45 +1536,111 @@ export interface RunQueryBuilder<Entity extends object, RootAlias extends string
960
1536
  * - Fields + nested joins: falls back to EntityDTO<Loaded<T, H, F>>
961
1537
  */
962
1538
  type DirectDTO<T, F extends keyof T> = {
963
- [K in F]: EntityDTOProp<T, NonNullable<T[K]>> | Extract<T[K], null | undefined>;
1539
+ [K in F]: EntityDTOProp<T, NonNullable<T[K]>> | Extract<T[K], null | undefined>;
964
1540
  };
965
- type PopulatedDTO<T, K extends keyof T> = NonNullable<T[K]> extends Collection<infer U> ? EntityDTOFlat<U & object>[] : EntityDTOFlat<ExpandProperty<T[K]>>;
1541
+ type PopulatedDTO<T, K extends keyof T> =
1542
+ NonNullable<T[K]> extends Collection<infer U> ? EntityDTOFlat<U & object>[] : EntityDTOFlat<ExpandProperty<T[K]>>;
966
1543
  type SubFields<F extends string, Rel extends string> = F extends `${Rel}.${infer Sub}` ? Sub : never;
967
- type RootFields<F extends string, H extends string> = F extends `${string}.${string}` ? F extends `${H}.${string}` ? never : F : F;
968
- type JoinDTO<T, K extends keyof T, F extends string> = NonNullable<T[K]> extends Collection<infer U> ? SubFields<F, K & string> extends never ? EntityDTOProp<T, Collection<U>> : DirectDTO<U, (SubFields<F, K & string> | PrimaryProperty<U>) & keyof U>[] : SubFields<F, K & string> extends never ? EntityDTOProp<T, T[K]> : DirectDTO<NonNullable<T[K]>, (SubFields<F, K & string> | PrimaryProperty<NonNullable<T[K]>>) & keyof NonNullable<T[K]>> | Extract<T[K], null | undefined>;
969
- type ExecuteDTO<T, H extends string, F extends string> = [H] extends [never] ? [F] extends ['*'] ? EntityDTOFlat<T> : DirectDTO<T, F & keyof T> : [F] extends ['*'] ? true extends (H extends `${string}.${string}` ? true : false) ? SerializeDTO<T, H> : Omit<EntityDTOFlat<T>, H & keyof EntityDTOFlat<T>> & {
970
- [K in H & keyof T as K & keyof EntityDTOFlat<T>]: PopulatedDTO<T, K> | Extract<T[K], null | undefined>;
971
- } : true extends (H extends `${string}.${string}` ? true : false) ? EntityDTOFlat<Loaded<T, H, F>> : DirectDTO<T, (RootFields<F, H> | PrimaryProperty<T>) & keyof T> & {
972
- [K in H & keyof T]: JoinDTO<T, K, F>;
973
- };
1544
+ type RootFields<F extends string, H extends string> = F extends `${string}.${string}`
1545
+ ? F extends `${H}.${string}`
1546
+ ? never
1547
+ : F
1548
+ : F;
1549
+ type JoinDTO<T, K extends keyof T, F extends string> =
1550
+ NonNullable<T[K]> extends Collection<infer U>
1551
+ ? SubFields<F, K & string> extends never
1552
+ ? EntityDTOProp<T, Collection<U>>
1553
+ : DirectDTO<U, (SubFields<F, K & string> | PrimaryProperty<U>) & keyof U>[]
1554
+ : SubFields<F, K & string> extends never
1555
+ ? EntityDTOProp<T, T[K]>
1556
+ :
1557
+ | DirectDTO<
1558
+ NonNullable<T[K]>,
1559
+ (SubFields<F, K & string> | PrimaryProperty<NonNullable<T[K]>>) & keyof NonNullable<T[K]>
1560
+ >
1561
+ | Extract<T[K], null | undefined>;
1562
+ type ExecuteDTO<T, H extends string, F extends string> = [H] extends [never]
1563
+ ? [F] extends ['*']
1564
+ ? EntityDTOFlat<T>
1565
+ : DirectDTO<T, F & keyof T>
1566
+ : [F] extends ['*']
1567
+ ? true extends (H extends `${string}.${string}` ? true : false)
1568
+ ? SerializeDTO<T, H>
1569
+ : Omit<EntityDTOFlat<T>, H & keyof EntityDTOFlat<T>> & {
1570
+ [K in H & keyof T as K & keyof EntityDTOFlat<T>]: PopulatedDTO<T, K> | Extract<T[K], null | undefined>;
1571
+ }
1572
+ : true extends (H extends `${string}.${string}` ? true : false)
1573
+ ? EntityDTOFlat<Loaded<T, H, F>>
1574
+ : DirectDTO<T, (RootFields<F, H> | PrimaryProperty<T>) & keyof T> & {
1575
+ [K in H & keyof T]: JoinDTO<T, K, F>;
1576
+ };
974
1577
  /** Shorthand for `QueryBuilder` with all generic parameters set to `any`. */
975
1578
  export type AnyQueryBuilder<T extends object = AnyEntity> = QueryBuilder<T, any, any, any, any, any, any>;
976
- export interface SelectQueryBuilder<Entity extends object = AnyEntity, RootAlias extends string = never, Hint extends string = never, Context extends object = never, RawAliases extends string = never, Fields extends string = '*', CTEs extends Record<string, object> = {}> extends QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs> {
977
- execute<Result = ExecuteDTO<Entity, Hint, Fields>[]>(method?: 'all' | 'get' | 'run', mapResults?: boolean): Promise<Result>;
978
- execute<Result = ExecuteDTO<Entity, Hint, Fields>[]>(method: 'all', mapResults?: boolean): Promise<Result>;
979
- execute<Result = ExecuteDTO<Entity, Hint, Fields>>(method: 'get', mapResults?: boolean): Promise<Result>;
980
- execute<Result = QueryResult<Entity>>(method: 'run', mapResults?: boolean): Promise<Result>;
1579
+ export interface SelectQueryBuilder<
1580
+ Entity extends object = AnyEntity,
1581
+ RootAlias extends string = never,
1582
+ Hint extends string = never,
1583
+ Context extends object = never,
1584
+ RawAliases extends string = never,
1585
+ Fields extends string = '*',
1586
+ CTEs extends Record<string, object> = {},
1587
+ > extends QueryBuilder<Entity, RootAlias, Hint, Context, RawAliases, Fields, CTEs> {
1588
+ execute<Result = ExecuteDTO<Entity, Hint, Fields>[]>(
1589
+ method?: 'all' | 'get' | 'run',
1590
+ mapResults?: boolean,
1591
+ ): Promise<Result>;
1592
+ execute<Result = ExecuteDTO<Entity, Hint, Fields>[]>(method: 'all', mapResults?: boolean): Promise<Result>;
1593
+ execute<Result = ExecuteDTO<Entity, Hint, Fields>>(method: 'get', mapResults?: boolean): Promise<Result>;
1594
+ execute<Result = QueryResult<Entity>>(method: 'run', mapResults?: boolean): Promise<Result>;
981
1595
  }
982
1596
  export interface CountQueryBuilder<Entity extends object> extends QueryBuilder<Entity, any, any> {
983
- execute<Result = {
984
- count: number;
985
- }[]>(method?: 'all' | 'get' | 'run', mapResults?: boolean): Promise<Result>;
986
- execute<Result = {
987
- count: number;
988
- }[]>(method: 'all', mapResults?: boolean): Promise<Result>;
989
- execute<Result = {
990
- count: number;
991
- }>(method: 'get', mapResults?: boolean): Promise<Result>;
992
- execute<Result = QueryResult<{
993
- count: number;
994
- }>>(method: 'run', mapResults?: boolean): Promise<Result>;
995
- }
996
- export interface InsertQueryBuilder<T extends object, RootAlias extends string = never, Context extends object = never> extends RunQueryBuilder<T, RootAlias, Context> {
997
- }
998
- export interface UpdateQueryBuilder<T extends object, RootAlias extends string = never, Context extends object = never> extends RunQueryBuilder<T, RootAlias, Context> {
999
- }
1000
- export interface DeleteQueryBuilder<T extends object, RootAlias extends string = never, Context extends object = never> extends RunQueryBuilder<T, RootAlias, Context> {
1001
- }
1002
- export interface TruncateQueryBuilder<T extends object> extends RunQueryBuilder<T> {
1597
+ execute<
1598
+ Result = {
1599
+ count: number;
1600
+ }[],
1601
+ >(
1602
+ method?: 'all' | 'get' | 'run',
1603
+ mapResults?: boolean,
1604
+ ): Promise<Result>;
1605
+ execute<
1606
+ Result = {
1607
+ count: number;
1608
+ }[],
1609
+ >(
1610
+ method: 'all',
1611
+ mapResults?: boolean,
1612
+ ): Promise<Result>;
1613
+ execute<
1614
+ Result = {
1615
+ count: number;
1616
+ },
1617
+ >(
1618
+ method: 'get',
1619
+ mapResults?: boolean,
1620
+ ): Promise<Result>;
1621
+ execute<
1622
+ Result = QueryResult<{
1623
+ count: number;
1624
+ }>,
1625
+ >(
1626
+ method: 'run',
1627
+ mapResults?: boolean,
1628
+ ): Promise<Result>;
1003
1629
  }
1630
+ export interface InsertQueryBuilder<
1631
+ T extends object,
1632
+ RootAlias extends string = never,
1633
+ Context extends object = never,
1634
+ > extends RunQueryBuilder<T, RootAlias, Context> {}
1635
+ export interface UpdateQueryBuilder<
1636
+ T extends object,
1637
+ RootAlias extends string = never,
1638
+ Context extends object = never,
1639
+ > extends RunQueryBuilder<T, RootAlias, Context> {}
1640
+ export interface DeleteQueryBuilder<
1641
+ T extends object,
1642
+ RootAlias extends string = never,
1643
+ Context extends object = never,
1644
+ > extends RunQueryBuilder<T, RootAlias, Context> {}
1645
+ export interface TruncateQueryBuilder<T extends object> extends RunQueryBuilder<T> {}
1004
1646
  export {};