@mikro-orm/core 7.0.0-dev.99 → 7.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/EntityManager.d.ts +34 -17
  2. package/EntityManager.js +95 -103
  3. package/MikroORM.d.ts +5 -5
  4. package/MikroORM.js +25 -20
  5. package/cache/FileCacheAdapter.js +11 -3
  6. package/connections/Connection.d.ts +3 -2
  7. package/connections/Connection.js +4 -3
  8. package/drivers/DatabaseDriver.d.ts +11 -11
  9. package/drivers/DatabaseDriver.js +91 -25
  10. package/drivers/IDatabaseDriver.d.ts +50 -20
  11. package/entity/BaseEntity.d.ts +61 -1
  12. package/entity/Collection.d.ts +8 -1
  13. package/entity/Collection.js +12 -13
  14. package/entity/EntityAssigner.js +9 -9
  15. package/entity/EntityFactory.d.ts +6 -1
  16. package/entity/EntityFactory.js +40 -22
  17. package/entity/EntityHelper.d.ts +2 -2
  18. package/entity/EntityHelper.js +27 -4
  19. package/entity/EntityLoader.d.ts +5 -4
  20. package/entity/EntityLoader.js +193 -80
  21. package/entity/EntityRepository.d.ts +27 -7
  22. package/entity/EntityRepository.js +8 -2
  23. package/entity/PolymorphicRef.d.ts +12 -0
  24. package/entity/PolymorphicRef.js +18 -0
  25. package/entity/WrappedEntity.d.ts +2 -2
  26. package/entity/WrappedEntity.js +1 -1
  27. package/entity/defineEntity.d.ts +89 -50
  28. package/entity/defineEntity.js +12 -0
  29. package/entity/index.d.ts +1 -0
  30. package/entity/index.js +1 -0
  31. package/entity/utils.d.ts +6 -1
  32. package/entity/utils.js +33 -0
  33. package/entity/validators.js +2 -2
  34. package/enums.d.ts +2 -2
  35. package/enums.js +1 -0
  36. package/errors.d.ts +16 -8
  37. package/errors.js +40 -13
  38. package/hydration/ObjectHydrator.js +63 -21
  39. package/index.d.ts +1 -1
  40. package/logging/colors.d.ts +1 -1
  41. package/logging/colors.js +7 -6
  42. package/logging/inspect.js +1 -6
  43. package/metadata/EntitySchema.d.ts +43 -13
  44. package/metadata/EntitySchema.js +82 -27
  45. package/metadata/MetadataDiscovery.d.ts +60 -3
  46. package/metadata/MetadataDiscovery.js +665 -154
  47. package/metadata/MetadataProvider.js +3 -1
  48. package/metadata/MetadataStorage.d.ts +13 -6
  49. package/metadata/MetadataStorage.js +64 -19
  50. package/metadata/MetadataValidator.d.ts +32 -2
  51. package/metadata/MetadataValidator.js +196 -31
  52. package/metadata/discover-entities.js +5 -5
  53. package/metadata/types.d.ts +111 -14
  54. package/naming-strategy/AbstractNamingStrategy.d.ts +11 -3
  55. package/naming-strategy/AbstractNamingStrategy.js +12 -0
  56. package/naming-strategy/EntityCaseNamingStrategy.d.ts +3 -3
  57. package/naming-strategy/EntityCaseNamingStrategy.js +6 -5
  58. package/naming-strategy/MongoNamingStrategy.d.ts +3 -3
  59. package/naming-strategy/MongoNamingStrategy.js +6 -6
  60. package/naming-strategy/NamingStrategy.d.ts +17 -3
  61. package/naming-strategy/UnderscoreNamingStrategy.d.ts +3 -3
  62. package/naming-strategy/UnderscoreNamingStrategy.js +6 -6
  63. package/package.json +2 -2
  64. package/platforms/Platform.d.ts +4 -2
  65. package/platforms/Platform.js +5 -2
  66. package/serialization/EntitySerializer.d.ts +3 -0
  67. package/serialization/EntitySerializer.js +15 -13
  68. package/serialization/EntityTransformer.js +6 -6
  69. package/serialization/SerializationContext.d.ts +6 -6
  70. package/typings.d.ts +325 -110
  71. package/typings.js +84 -17
  72. package/unit-of-work/ChangeSet.d.ts +4 -3
  73. package/unit-of-work/ChangeSet.js +2 -3
  74. package/unit-of-work/ChangeSetComputer.d.ts +3 -6
  75. package/unit-of-work/ChangeSetComputer.js +34 -13
  76. package/unit-of-work/ChangeSetPersister.d.ts +12 -10
  77. package/unit-of-work/ChangeSetPersister.js +55 -25
  78. package/unit-of-work/CommitOrderCalculator.d.ts +12 -10
  79. package/unit-of-work/CommitOrderCalculator.js +13 -13
  80. package/unit-of-work/IdentityMap.d.ts +12 -0
  81. package/unit-of-work/IdentityMap.js +39 -1
  82. package/unit-of-work/UnitOfWork.d.ts +21 -3
  83. package/unit-of-work/UnitOfWork.js +203 -56
  84. package/utils/AbstractSchemaGenerator.js +17 -8
  85. package/utils/AsyncContext.d.ts +6 -0
  86. package/utils/AsyncContext.js +42 -0
  87. package/utils/Configuration.d.ts +52 -11
  88. package/utils/Configuration.js +12 -8
  89. package/utils/Cursor.js +21 -8
  90. package/utils/DataloaderUtils.js +13 -11
  91. package/utils/EntityComparator.d.ts +14 -7
  92. package/utils/EntityComparator.js +132 -46
  93. package/utils/QueryHelper.d.ts +16 -6
  94. package/utils/QueryHelper.js +53 -18
  95. package/utils/RawQueryFragment.d.ts +28 -23
  96. package/utils/RawQueryFragment.js +34 -56
  97. package/utils/RequestContext.js +2 -2
  98. package/utils/TransactionContext.js +2 -2
  99. package/utils/TransactionManager.js +1 -1
  100. package/utils/Utils.d.ts +7 -26
  101. package/utils/Utils.js +25 -79
  102. package/utils/clone.js +7 -21
  103. package/utils/env-vars.d.ts +4 -0
  104. package/utils/env-vars.js +13 -3
  105. package/utils/fs-utils.d.ts +21 -0
  106. package/utils/fs-utils.js +106 -11
  107. package/utils/upsert-utils.d.ts +4 -4
package/typings.d.ts CHANGED
@@ -11,17 +11,20 @@ import type { SerializationContext } from './serialization/SerializationContext.
11
11
  import type { SerializeOptions } from './serialization/EntitySerializer.js';
12
12
  import type { MetadataStorage } from './metadata/MetadataStorage.js';
13
13
  import type { EntitySchema } from './metadata/EntitySchema.js';
14
+ import type { IndexColumnOptions } from './metadata/types.js';
14
15
  import type { Type, types } from './types/index.js';
15
16
  import type { Platform } from './platforms/Platform.js';
16
17
  import type { Configuration } from './utils/Configuration.js';
17
- import type { RawQueryFragment } from './utils/RawQueryFragment.js';
18
+ import type { Raw } from './utils/RawQueryFragment.js';
18
19
  import type { EntityManager } from './EntityManager.js';
19
20
  import type { EventSubscriber } from './events/EventSubscriber.js';
20
21
  import type { FilterOptions, FindOneOptions, FindOptions, LoadHint } from './drivers/IDatabaseDriver.js';
22
+ export type { Raw };
21
23
  export type Constructor<T = unknown> = new (...args: any[]) => T;
22
24
  export type Dictionary<T = any> = {
23
25
  [k: string]: T;
24
26
  };
27
+ export type CompiledFunctions = Record<string, (...args: any[]) => any>;
25
28
  export type EntityKey<T = unknown, B extends boolean = false> = string & {
26
29
  [K in keyof T]-?: CleanKeys<T, K, B> extends never ? never : K;
27
30
  }[keyof T];
@@ -40,7 +43,64 @@ export type IsUnknown<T> = T extends unknown ? unknown extends T ? true : never
40
43
  export type IsAny<T> = 0 extends (1 & T) ? true : false;
41
44
  export type IsNever<T, True = true, False = false> = [T] extends [never] ? True : False;
42
45
  export type MaybePromise<T> = T | Promise<T>;
43
- export type NoInfer<T> = [T][T extends any ? 0 : never];
46
+ /**
47
+ * Structural type for matching Collection without triggering full interface evaluation.
48
+ * Using `T extends CollectionShape` instead of `T extends Collection<any, any>` avoids
49
+ * forcing TypeScript to evaluate Collection's 30+ methods, preventing instantiation explosion
50
+ * (~133k → ~2k instantiations).
51
+ *
52
+ * Usage:
53
+ * - Matching only: `T extends CollectionShape`
54
+ * - With inference: `T extends CollectionShape<infer U>`
55
+ */
56
+ type CollectionShape<T = any> = {
57
+ [k: number]: T;
58
+ readonly owner: object;
59
+ };
60
+ /**
61
+ * Structural type for matching LoadedCollection (extends CollectionShape with `$` property).
62
+ *
63
+ * Usage:
64
+ * - Matching only: `T extends LoadedCollectionShape`
65
+ * - With inference: `T extends LoadedCollectionShape<infer U>`
66
+ */
67
+ type LoadedCollectionShape<T = any> = CollectionShape<T> & {
68
+ $: any;
69
+ };
70
+ /**
71
+ * Structural type for matching Reference without triggering full class evaluation.
72
+ * Using `T extends ReferenceShape` instead of `T extends Reference<any>` avoids
73
+ * forcing TypeScript to evaluate Reference's methods, preventing instantiation overhead
74
+ * (~800 → ~15 instantiations).
75
+ *
76
+ * Usage:
77
+ * - Matching only: `T extends ReferenceShape`
78
+ * - With inference: `T extends ReferenceShape<infer U>`
79
+ */
80
+ type ReferenceShape<T = any> = {
81
+ unwrap(): T;
82
+ };
83
+ /**
84
+ * Structural type for matching LoadedReference (Reference with `$` property).
85
+ * Note: We don't parameterize ReferenceShape here because for loaded relations,
86
+ * the Reference unwrap() returns the base type while $ returns the Loaded type.
87
+ * We infer T from $ to get the full Loaded type for EntityDTO.
88
+ */
89
+ type LoadedReferenceShape<T = any> = ReferenceShape & {
90
+ $: T;
91
+ };
92
+ /**
93
+ * Structural type for matching any loadable relation (Collection, Reference, or array).
94
+ * Using this instead of `Loadable<any>` in conditional type checks prevents
95
+ * TypeScript from evaluating the full Collection/Reference interfaces.
96
+ */
97
+ type LoadableShape = CollectionShape | ReferenceShape | readonly any[];
98
+ export type UnionKeys<T> = T extends any ? keyof T : never;
99
+ export type UnionPropertyType<T, K extends PropertyKey> = T extends any ? (K extends keyof T ? T[K] : never) : never;
100
+ type IsUnion<T, U = T> = T extends any ? ([U] extends [T] ? false : true) : false;
101
+ export type MergeUnion<T> = [T] extends [object] ? (T extends Scalar ? T : IsUnion<T> extends true ? {
102
+ [K in UnionKeys<T>]: UnionPropertyType<T, K>;
103
+ } : T) : T;
44
104
  export type DeepPartial<T> = T & {
45
105
  [P in keyof T]?: T[P] extends (infer U)[] ? DeepPartial<U>[] : T[P] extends Readonly<infer U>[] ? Readonly<DeepPartial<U>>[] : DeepPartial<T[P]>;
46
106
  };
@@ -82,7 +142,17 @@ export type CleanTypeConfig<T> = Compute<Pick<T, Extract<keyof T, keyof TypeConf
82
142
  export interface TypeConfig {
83
143
  forceObject?: boolean;
84
144
  }
85
- export type UnwrapPrimary<T> = T extends Scalar ? T : T extends Reference<infer U> ? Primary<U> : Primary<T>;
145
+ declare const __selectedType: unique symbol;
146
+ declare const __loadedType: unique symbol;
147
+ declare const __loadHint: unique symbol;
148
+ /**
149
+ * Expands a populate hint into all its prefixes.
150
+ * e.g., Prefixes<'a.b.c'> = 'a' | 'a.b' | 'a.b.c'
151
+ * This reflects that loading 'a.b.c' means 'a' and 'a.b' are also loaded.
152
+ * Special case: '*' returns string to ensure Loaded<T, '*'> is assignable to any Loaded<T, Hint>.
153
+ */
154
+ export type Prefixes<S extends string> = S extends '*' ? string : S extends `${infer H}.${infer T}` ? H | `${H}.${Prefixes<T>}` : S;
155
+ export type UnwrapPrimary<T> = T extends Scalar ? T : T extends ReferenceShape<infer U> ? Primary<U> : Primary<T>;
86
156
  type PrimaryPropToType<T, Keys extends (keyof T)[]> = {
87
157
  [Index in keyof Keys]: UnwrapPrimary<T[Keys[Index]]>;
88
158
  };
@@ -115,22 +185,35 @@ export type IPrimaryKey<T extends IPrimaryKeyValue = IPrimaryKeyValue> = T;
115
185
  export type Scalar = boolean | number | string | bigint | symbol | Date | RegExp | Uint8Array | {
116
186
  toHexString(): string;
117
187
  };
188
+ type Primitive = boolean | number | string | bigint | symbol;
118
189
  export type ExpandScalar<T> = null | (T extends string ? T | RegExp : T extends Date ? Date | string : T extends bigint ? bigint | string | number : T);
190
+ /** Marker interface for query builders that can be used as subqueries */
191
+ export interface Subquery {
192
+ readonly __subquery: true;
193
+ }
119
194
  export type OperatorMap<T> = {
120
195
  $and?: ExpandQuery<T>[];
121
196
  $or?: ExpandQuery<T>[];
122
- $eq?: ExpandScalar<T> | readonly ExpandScalar<T>[];
123
- $ne?: ExpandScalar<T>;
124
- $in?: readonly ExpandScalar<T>[];
125
- $nin?: readonly ExpandScalar<T>[];
197
+ $eq?: ExpandScalar<T> | readonly ExpandScalar<T>[] | Subquery;
198
+ $ne?: ExpandScalar<T> | readonly ExpandScalar<T>[] | Subquery;
199
+ $in?: readonly ExpandScalar<T>[] | readonly Primary<T>[] | Raw | Subquery;
200
+ $nin?: readonly ExpandScalar<T>[] | readonly Primary<T>[] | Raw | Subquery;
126
201
  $not?: ExpandQuery<T>;
127
202
  $none?: ExpandQuery<T>;
128
203
  $some?: ExpandQuery<T>;
129
204
  $every?: ExpandQuery<T>;
130
- $gt?: ExpandScalar<T>;
131
- $gte?: ExpandScalar<T>;
132
- $lt?: ExpandScalar<T>;
133
- $lte?: ExpandScalar<T>;
205
+ $size?: number | {
206
+ $eq?: number;
207
+ $ne?: number;
208
+ $gt?: number;
209
+ $gte?: number;
210
+ $lt?: number;
211
+ $lte?: number;
212
+ };
213
+ $gt?: ExpandScalar<T> | readonly ExpandScalar<T>[] | Subquery;
214
+ $gte?: ExpandScalar<T> | readonly ExpandScalar<T>[] | Subquery;
215
+ $lt?: ExpandScalar<T> | readonly ExpandScalar<T>[] | Subquery;
216
+ $lte?: ExpandScalar<T> | readonly ExpandScalar<T>[] | Subquery;
134
217
  $like?: string;
135
218
  $re?: string;
136
219
  $ilike?: string;
@@ -143,10 +226,12 @@ export type OperatorMap<T> = {
143
226
  $hasKeys?: readonly string[];
144
227
  $hasSomeKeys?: readonly string[];
145
228
  };
146
- export type FilterItemValue<T> = T | ExpandScalar<T> | Primary<T>;
229
+ export type FilterItemValue<T> = T | ExpandScalar<T> | Primary<T> | Raw;
147
230
  export type FilterValue<T> = OperatorMap<FilterItemValue<T>> | FilterItemValue<T> | FilterItemValue<T>[] | null;
231
+ type FilterObjectProp<T, K extends PropertyKey> = K extends keyof MergeUnion<T> ? MergeUnion<T>[K] : K extends keyof T ? T[K] : never;
232
+ type ExpandQueryMerged<T> = [T] extends [object] ? [T] extends [Scalar] ? never : FilterQuery<MergeUnion<T>> : FilterValue<T>;
148
233
  export type FilterObject<T> = {
149
- -readonly [K in EntityKey<T>]?: ExpandQuery<ExpandProperty<T[K]>> | FilterValue<ExpandProperty<T[K]>> | null;
234
+ -readonly [K in EntityKey<T>]?: ExpandQuery<ExpandProperty<FilterObjectProp<T, K>>> | ExpandQueryMerged<ExpandProperty<FilterObjectProp<T, K>>> | FilterValue<ExpandProperty<FilterObjectProp<T, K>>> | null;
150
235
  };
151
236
  export type ExpandQuery<T> = T extends object ? T extends Scalar ? never : FilterQuery<T> : FilterValue<T>;
152
237
  export type EntityProps<T> = {
@@ -154,12 +239,11 @@ export type EntityProps<T> = {
154
239
  };
155
240
  export type ObjectQuery<T> = OperatorMap<T> & FilterObject<T>;
156
241
  export type FilterQuery<T> = ObjectQuery<T> | NonNullable<ExpandScalar<Primary<T>>> | NonNullable<EntityProps<T> & OperatorMap<T>> | FilterQuery<T>[];
157
- export type QBFilterQuery<T = any> = ObjectQuery<T> | Dictionary;
158
242
  export interface IWrappedEntity<Entity extends object> {
159
243
  isInitialized(): boolean;
160
244
  isManaged(): boolean;
161
245
  populated(populated?: boolean): void;
162
- populate<Hint extends string = never>(populate: AutoPath<Entity, Hint>[] | false, options?: EntityLoaderOptions<Entity>): Promise<Loaded<Entity, Hint>>;
246
+ populate<Hint extends string = never>(populate: readonly AutoPath<Entity, Hint, PopulatePath.ALL>[] | false, options?: EntityLoaderOptions<Entity>): Promise<Loaded<Entity, Hint>>;
163
247
  init<Hint extends string = never, Fields extends string = '*', Exclude extends string = never>(options?: FindOneOptions<Entity, Hint, Fields, Exclude>): Promise<Loaded<Entity, Hint, Fields, Exclude> | null>;
164
248
  toReference(): Ref<Entity> & LoadedReference<Loaded<Entity, AddEager<Entity>>>;
165
249
  toObject(): EntityDTO<Entity>;
@@ -206,16 +290,21 @@ export interface IWrappedEntityInternal<Entity extends object> extends IWrappedE
206
290
  };
207
291
  }
208
292
  export type AnyEntity<T = any> = Partial<T>;
209
- export type EntityClass<T> = Function & {
293
+ export type EntityClass<T = any> = Function & {
210
294
  prototype: T;
211
295
  };
212
- export type EntityName<T> = string | EntityClass<T> | EntitySchema<T, any> | {
213
- name: string;
214
- };
296
+ export type EntityName<T = any> = EntityClass<T> | EntityCtor<T> | EntitySchema<T, any>;
215
297
  export type GetRepository<Entity extends {
216
298
  [k: PropertyKey]: any;
217
299
  }, Fallback> = Entity[typeof EntityRepositoryType] extends EntityRepository<any> | undefined ? NonNullable<Entity[typeof EntityRepositoryType]> : Fallback;
218
- export type EntityDataPropValue<T> = T | Primary<T>;
300
+ type PolymorphicPrimaryInner<T> = T extends object ? Primary<T> extends readonly [infer First, infer Second, ...infer Rest] ? readonly [string, First, Second, ...Rest] | [string, First, Second, ...Rest] : readonly [string, Primary<T>] | [string, Primary<T>] : never;
301
+ /**
302
+ * Tuple format for polymorphic FK values: [discriminator, ...pkValues]
303
+ * Distributes over unions, so `Post | Comment` becomes `['post', number] | ['comment', number]`
304
+ * For composite keys like [tenantId, orgId], becomes ['discriminator', tenantId, orgId]
305
+ */
306
+ export type PolymorphicPrimary<T> = true extends IsUnion<T> ? PolymorphicPrimaryInner<T> : never;
307
+ export type EntityDataPropValue<T> = T | Primary<T> | PolymorphicPrimary<T>;
219
308
  type ExpandEntityProp<T, C extends boolean = false> = T extends Record<string, any> ? {
220
309
  [K in keyof T as CleanKeys<T, K>]?: EntityDataProp<ExpandProperty<T[K]>, C> | EntityDataPropValue<ExpandProperty<T[K]>> | null;
221
310
  } | EntityDataPropValue<ExpandProperty<T>> : T;
@@ -228,16 +317,17 @@ type ExpandRequiredEntityPropObject<T, I = never, C extends boolean = false> = {
228
317
  type NonArrayObject = object & {
229
318
  [Symbol.iterator]?: never;
230
319
  };
231
- export type EntityDataProp<T, C extends boolean> = T extends Date ? string | Date : T extends Scalar ? T : T extends {
320
+ export type EntityDataProp<T, C extends boolean> = T extends Date ? string | Date : T extends Scalar ? T : T extends ScalarReference<infer U> ? EntityDataProp<U, C> : T extends {
232
321
  __runtime?: infer Runtime;
233
322
  __raw?: infer Raw;
234
- } ? (C extends true ? Raw : Runtime) : T extends Reference<infer U> ? EntityDataNested<U, C> : T extends ScalarReference<infer U> ? EntityDataProp<U, C> : T extends Collection<infer U, any> ? U | U[] | EntityDataNested<U, C> | EntityDataNested<U, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | EntityDataNested<U, C> | EntityDataNested<U, C>[] : U[] | EntityDataNested<U, C>[] : EntityDataNested<T, C>;
235
- export type RequiredEntityDataProp<T, O, C extends boolean> = T extends Date ? string | Date : Exclude<T, null> extends RequiredNullable.Brand ? T | null : T extends Scalar ? T : T extends {
323
+ } ? (C extends true ? Raw : Runtime) : T extends ReferenceShape<infer U> ? EntityDataNested<U, C> : T extends CollectionShape<infer U> ? U | U[] | EntityDataNested<U & object, C> | EntityDataNested<U & object, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | EntityDataNested<U, C> | EntityDataNested<U, C>[] : U[] | EntityDataNested<U, C>[] : EntityDataNested<T, C>;
324
+ export type RequiredEntityDataProp<T, O, C extends boolean> = T extends Date ? string | Date : Exclude<T, null> extends RequiredNullable.Brand ? T | null : T extends Scalar ? T : T extends ScalarReference<infer U> ? RequiredEntityDataProp<U, O, C> : T extends {
236
325
  __runtime?: infer Runtime;
237
326
  __raw?: infer Raw;
238
- } ? (C extends true ? Raw : Runtime) : T extends Reference<infer U> ? RequiredEntityDataNested<U, O, C> : T extends ScalarReference<infer U> ? RequiredEntityDataProp<U, O, C> : T extends Collection<infer U, any> ? U | U[] | RequiredEntityDataNested<U, O, C> | RequiredEntityDataNested<U, O, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | RequiredEntityDataNested<U, O, C> | RequiredEntityDataNested<U, O, C>[] : U[] | RequiredEntityDataNested<U, O, C>[] : RequiredEntityDataNested<T, O, C>;
327
+ } ? (C extends true ? Raw : Runtime) : T extends ReferenceShape<infer U> ? RequiredEntityDataNested<U, O, C> : T extends CollectionShape<infer U> ? U | U[] | RequiredEntityDataNested<U & object, O, C> | RequiredEntityDataNested<U & object, O, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | RequiredEntityDataNested<U, O, C> | RequiredEntityDataNested<U, O, C>[] : U[] | RequiredEntityDataNested<U, O, C>[] : RequiredEntityDataNested<T, O, C>;
239
328
  export type EntityDataNested<T, C extends boolean = false> = T extends undefined ? never : T extends any[] ? Readonly<T> : EntityData<T, C> | ExpandEntityProp<T, C>;
240
- type EntityDataItem<T, C extends boolean> = C extends false ? T | EntityDataProp<T, C> | null : EntityDataProp<T, C> | null;
329
+ type UnwrapScalarRef<T> = T extends ScalarReference<infer U> ? U : T;
330
+ type EntityDataItem<T, C extends boolean> = C extends false ? UnwrapScalarRef<T> | EntityDataProp<T, C> | Raw | null : EntityDataProp<T, C> | Raw | null;
241
331
  export type RequiredEntityDataNested<T, O, C extends boolean> = T extends any[] ? Readonly<T> : RequiredEntityData<T, O> | ExpandRequiredEntityProp<T, O, C>;
242
332
  type ExplicitlyOptionalProps<T> = (T extends {
243
333
  [OptionalProps]?: infer K;
@@ -245,22 +335,22 @@ type ExplicitlyOptionalProps<T> = (T extends {
245
335
  [K in keyof T]: T[K] extends Opt ? K : never;
246
336
  }[keyof T] & {});
247
337
  type NullableKeys<T, V = null> = {
248
- [K in keyof T]: V extends T[K] ? K : never;
338
+ [K in keyof T]: unknown extends T[K] ? never : V extends T[K] ? K : never;
249
339
  }[keyof T];
250
340
  type RequiredNullableKeys<T> = {
251
341
  [K in keyof T]: Exclude<T[K], null> extends RequiredNullable.Brand ? K : never;
252
342
  }[keyof T];
253
343
  type ProbablyOptionalProps<T> = PrimaryProperty<T> | ExplicitlyOptionalProps<T> | Exclude<NonNullable<NullableKeys<T, null | undefined>>, RequiredNullableKeys<T>>;
254
- type IsOptional<T, K extends keyof T, I> = T[K] extends Collection<any, any> ? true : ExtractType<T[K]> extends I ? true : K extends ProbablyOptionalProps<T> ? true : false;
344
+ type IsOptional<T, K extends keyof T, I> = T[K] extends CollectionShape ? true : ExtractType<T[K]> extends I ? true : K extends ProbablyOptionalProps<T> ? true : false;
255
345
  type RequiredKeys<T, K extends keyof T, I> = IsOptional<T, K, I> extends false ? CleanKeys<T, K> : never;
256
346
  type OptionalKeys<T, K extends keyof T, I> = IsOptional<T, K, I> extends false ? never : CleanKeys<T, K>;
257
347
  export type EntityData<T, C extends boolean = false> = {
258
348
  [K in EntityKey<T>]?: EntityDataItem<T[K] & {}, C>;
259
349
  };
260
350
  export type RequiredEntityData<T, I = never, C extends boolean = false> = {
261
- [K in keyof T as RequiredKeys<T, K, I>]: T[K] | RequiredEntityDataProp<T[K], T, C> | Primary<T[K]>;
351
+ [K in keyof T as RequiredKeys<T, K, I>]: T[K] | RequiredEntityDataProp<T[K], T, C> | Primary<T[K]> | PolymorphicPrimary<T[K]> | Raw;
262
352
  } & {
263
- [K in keyof T as OptionalKeys<T, K, I>]?: T[K] | RequiredEntityDataProp<T[K], T, C> | Primary<T[K]> | null;
353
+ [K in keyof T as OptionalKeys<T, K, I>]?: T[K] | RequiredEntityDataProp<T[K], T, C> | Primary<T[K]> | PolymorphicPrimary<T[K]> | Raw | null;
264
354
  };
265
355
  export type EntityDictionary<T> = EntityData<T> & Record<any, any>;
266
356
  type ExtractEagerProps<T> = T extends {
@@ -285,7 +375,7 @@ export type Ref<T> = T extends any ? IsAny<T> extends true ? Reference<T & objec
285
375
  type ExtractHiddenProps<T> = (T extends {
286
376
  [HiddenProps]?: infer K;
287
377
  } ? K : never) | ({
288
- [K in keyof T]: T[K] extends Hidden ? K : never;
378
+ [K in keyof T]: T[K] extends Primitive ? (T[K] extends Hidden ? K : never) : never;
289
379
  }[keyof T] & {});
290
380
  type ExcludeHidden<T, K extends keyof T> = K extends ExtractHiddenProps<T> ? never : K;
291
381
  type ExtractConfig<T> = T extends {
@@ -295,11 +385,14 @@ type PreferExplicitConfig<E, I> = IsNever<E, I, E>;
295
385
  type PrimaryOrObject<T, U, C extends TypeConfig> = PreferExplicitConfig<C, ExtractConfig<T>>['forceObject'] extends true ? {
296
386
  [K in PrimaryProperty<U> & keyof U]: U[K];
297
387
  } : Primary<U>;
298
- export type EntityDTOProp<E, T, C extends TypeConfig = never> = T extends Scalar ? T : T extends {
388
+ export type EntityDTOProp<E, T, C extends TypeConfig = never> = T extends Scalar ? T : T extends ScalarReference<infer U> ? U : T extends {
299
389
  __serialized?: infer U;
300
- } ? (IsUnknown<U> extends false ? U : T) : T extends LoadedReference<infer U> ? EntityDTO<U, C> : T extends Reference<infer U> ? PrimaryOrObject<E, U, C> : T extends ScalarReference<infer U> ? U : T extends LoadedCollection<infer U> ? EntityDTO<U, C>[] : T extends Collection<infer U> ? PrimaryOrObject<E, U, C>[] : T extends readonly (infer U)[] ? (T extends readonly any[] ? T : U[]) : T extends Relation<T> ? EntityDTO<T, C> : T;
301
- type DTOProbablyOptionalProps<T> = NonNullable<NullableKeys<T, undefined>>;
302
- type DTOIsOptional<T, K extends keyof T> = T[K] extends LoadedCollection<any> ? false : K extends PrimaryProperty<T> ? false : K extends DTOProbablyOptionalProps<T> ? true : false;
390
+ } ? (IsUnknown<U> extends false ? U : T) : T extends LoadedReferenceShape<infer U> ? EntityDTO<U, C> : T extends ReferenceShape<infer U> ? PrimaryOrObject<E, U, C> : T extends LoadedCollectionShape<infer U> ? EntityDTO<U & object, C>[] : T extends CollectionShape<infer U> ? PrimaryOrObject<E, U & object, C>[] : T extends readonly (infer U)[] ? U extends Scalar ? T : EntityDTOProp<E, U, C>[] : T extends Relation<T> ? EntityDTO<T, C> : T;
391
+ type UnwrapLoadedEntity<T> = T extends {
392
+ [__loadedType]?: infer U;
393
+ } ? NonNullable<U> : T;
394
+ type DTOProbablyOptionalProps<T> = NonNullable<NullableKeys<UnwrapLoadedEntity<T>, undefined>>;
395
+ type DTOIsOptional<T, K extends keyof T> = T[K] extends LoadedCollectionShape ? false : K extends PrimaryProperty<UnwrapLoadedEntity<T>> ? false : K extends DTOProbablyOptionalProps<T> ? true : false;
303
396
  type DTORequiredKeys<T, K extends keyof T> = DTOIsOptional<T, K> extends false ? ExcludeHidden<T, K> & CleanKeys<T, K> : never;
304
397
  type DTOOptionalKeys<T, K extends keyof T> = DTOIsOptional<T, K> extends false ? never : ExcludeHidden<T, K> & CleanKeys<T, K>;
305
398
  export type EntityDTO<T, C extends TypeConfig = never> = {
@@ -309,28 +402,61 @@ export type EntityDTO<T, C extends TypeConfig = never> = {
309
402
  };
310
403
  type TargetKeys<T> = T extends EntityClass<infer P> ? keyof P : keyof T;
311
404
  type PropertyName<T> = IsUnknown<T> extends false ? TargetKeys<T> : string;
312
- type TableName = {
405
+ export type FormulaTable = {
406
+ alias: string;
407
+ name: string;
408
+ schema?: string;
409
+ qualifiedName: string;
410
+ toString: () => string;
411
+ };
412
+ /**
413
+ * Table reference for schema callbacks (indexes, checks, generated columns).
414
+ * Unlike FormulaTable, this has no alias since schema generation doesn't use query aliases.
415
+ */
416
+ export type SchemaTable = {
313
417
  name: string;
314
418
  schema?: string;
419
+ qualifiedName: string;
315
420
  toString: () => string;
316
421
  };
317
- export type IndexCallback<T> = (table: TableName, columns: Record<PropertyName<T>, string>, indexName: string) => string | RawQueryFragment;
318
- export type CheckCallback<T> = (columns: Record<PropertyName<T>, string>) => string;
319
- export type GeneratedColumnCallback<T> = (columns: Record<keyof T, string>) => string;
422
+ /**
423
+ * Column mapping for formula callbacks. Maps property names to fully-qualified alias.fieldName.
424
+ * Has toString() returning the main alias for backwards compatibility with old formula syntax.
425
+ * @example
426
+ * // New recommended syntax - use cols.propName for fully-qualified references
427
+ * formula: cols => `${cols.firstName} || ' ' || ${cols.lastName}`
428
+ *
429
+ * // Old syntax still works - cols.toString() returns the alias
430
+ * formula: cols => `${cols}.first_name || ' ' || ${cols}.last_name`
431
+ */
432
+ export type FormulaColumns<T> = Record<PropertyName<T>, string> & {
433
+ toString(): string;
434
+ };
435
+ /**
436
+ * Column mapping for schema callbacks (indexes, checks, generated columns).
437
+ * Maps property names to field names. For TPT entities, only includes properties
438
+ * that belong to the current table (not inherited properties from parent tables).
439
+ */
440
+ export type SchemaColumns<T> = Record<PropertyName<T>, string>;
441
+ export type IndexCallback<T> = (columns: Record<PropertyName<T>, string>, table: SchemaTable, indexName: string) => string | Raw;
442
+ export type FormulaCallback<T> = (columns: FormulaColumns<T>, table: FormulaTable) => string | Raw;
443
+ export type CheckCallback<T> = (columns: Record<PropertyName<T>, string>, table: SchemaTable) => string | Raw;
444
+ export type GeneratedColumnCallback<T> = (columns: Record<PropertyName<T>, string>, table: SchemaTable) => string | Raw;
320
445
  export interface CheckConstraint<T = any> {
321
446
  name?: string;
322
447
  property?: string;
323
- expression: string | CheckCallback<T>;
448
+ expression: string | Raw | CheckCallback<T>;
324
449
  }
325
450
  export type AnyString = string & {};
326
451
  export interface EntityProperty<Owner = any, Target = any> {
327
452
  name: EntityKey<Owner>;
328
453
  entity: () => EntityName<Owner>;
454
+ target: EntityClass<Target>;
329
455
  type: keyof typeof types | AnyString;
330
456
  runtimeType: 'number' | 'string' | 'boolean' | 'bigint' | 'Buffer' | 'Date' | 'object' | 'any' | AnyString;
331
457
  targetMeta?: EntityMetadata<Target>;
332
458
  columnTypes: string[];
333
- generated?: string | GeneratedColumnCallback<Owner>;
459
+ generated?: string | Raw | GeneratedColumnCallback<Owner>;
334
460
  customType?: Type<any>;
335
461
  customTypes: (Type<any> | undefined)[];
336
462
  hasConvertToJSValueSQL: boolean;
@@ -351,7 +477,7 @@ export interface EntityProperty<Owner = any, Target = any> {
351
477
  fieldNameRaw?: string;
352
478
  default?: string | number | boolean | null;
353
479
  defaultRaw?: string;
354
- formula?: (alias: string) => string;
480
+ formula?: FormulaCallback<Owner>;
355
481
  filters?: FilterOptions;
356
482
  prefix?: string | boolean;
357
483
  prefixMode?: EmbeddedPrefixMode;
@@ -360,11 +486,19 @@ export interface EntityProperty<Owner = any, Target = any> {
360
486
  embeddable: EntityClass<Owner>;
361
487
  embeddedProps: Dictionary<EntityProperty>;
362
488
  discriminatorColumn?: string;
489
+ discriminator?: string;
490
+ polymorphic?: boolean;
491
+ polymorphTargets?: EntityMetadata[];
492
+ discriminatorMap?: Dictionary<EntityClass<Target>>;
493
+ discriminatorValue?: string;
363
494
  object?: boolean;
364
495
  index?: boolean | string;
365
496
  unique?: boolean | string;
366
497
  nullable?: boolean;
367
498
  inherited?: boolean;
499
+ renamedFrom?: string;
500
+ stiFieldNames?: string[];
501
+ stiFieldNameMap?: Dictionary<string>;
368
502
  unsigned?: boolean;
369
503
  mapToPk?: boolean;
370
504
  persist?: boolean;
@@ -396,13 +530,14 @@ export interface EntityProperty<Owner = any, Target = any> {
396
530
  fixedOrder?: boolean;
397
531
  fixedOrderColumn?: string;
398
532
  pivotTable: string;
399
- pivotEntity: string;
533
+ pivotEntity: EntityClass<Target>;
400
534
  joinColumns: string[];
401
535
  ownColumns: string[];
402
536
  inverseJoinColumns: string[];
403
537
  referencedColumnNames: string[];
404
538
  referencedTableName: string;
405
539
  referencedPKs: EntityKey<Owner>[];
540
+ targetKey?: string;
406
541
  serializer?: (value: any, options?: SerializeOptions<any>) => any;
407
542
  serializedName?: string;
408
543
  comment?: string;
@@ -415,18 +550,30 @@ export interface EntityProperty<Owner = any, Target = any> {
415
550
  createForeignKeyConstraint: boolean;
416
551
  foreignKeyName?: string;
417
552
  }
418
- export declare class EntityMetadata<T = any> {
553
+ export declare class EntityMetadata<Entity = any, Class extends EntityCtor<Entity> = EntityCtor<Entity>> {
419
554
  private static counter;
420
555
  readonly _id: number;
421
556
  readonly propertyOrder: Map<string, number>;
422
557
  constructor(meta?: Partial<EntityMetadata>);
423
- addProperty(prop: Partial<EntityProperty<T>>, sync?: boolean): void;
558
+ addProperty(prop: Partial<EntityProperty<Entity>>): void;
424
559
  removeProperty(name: string, sync?: boolean): void;
425
- getPrimaryProps(flatten?: boolean): EntityProperty<T>[];
426
- getPrimaryProp(): EntityProperty<T>;
427
- createColumnMappingObject(): Dictionary<any>;
560
+ getPrimaryProps(flatten?: boolean): EntityProperty<Entity>[];
561
+ getPrimaryProp(): EntityProperty<Entity>;
562
+ /**
563
+ * Creates a mapping from property names to field names.
564
+ * @param alias - Optional alias to prefix field names. Can be a string (same for all) or a function (per-property).
565
+ * When provided, also adds toString() returning the alias for backwards compatibility with formulas.
566
+ * @param toStringAlias - Optional alias to return from toString(). Defaults to `alias` when it's a string.
567
+ */
568
+ createColumnMappingObject(alias?: string | ((prop: EntityProperty<Entity>) => string), toStringAlias?: string): FormulaColumns<Entity>;
569
+ /**
570
+ * Creates a column mapping for schema callbacks (indexes, checks, generated columns).
571
+ * For TPT entities, only includes properties that belong to the current table (ownProps).
572
+ */
573
+ createSchemaColumnMappingObject(): SchemaColumns<Entity>;
428
574
  get tableName(): string;
429
575
  set tableName(name: string);
576
+ get uniqueName(): string;
430
577
  sync(initIndexes?: boolean, config?: Configuration): void;
431
578
  private initIndexes;
432
579
  /** @internal */
@@ -436,67 +583,87 @@ export interface SimpleColumnMeta {
436
583
  name: string;
437
584
  type: string;
438
585
  }
439
- export interface EntityMetadata<T = any> {
586
+ export type EntityCtor<T = any> = abstract new (...args: any[]) => T;
587
+ export interface EntityMetadata<Entity = any, Class extends EntityCtor<Entity> = EntityCtor<Entity>> {
440
588
  name?: string;
441
589
  className: string;
442
590
  tableName: string;
443
591
  schema?: string;
444
592
  pivotTable?: boolean;
445
593
  virtual?: boolean;
446
- expression?: string | ((em: any, where: ObjectQuery<T>, options: FindOptions<T, any, any, any>, stream?: boolean) => MaybePromise<RawQueryFragment | object | string>);
447
- discriminatorColumn?: EntityKey<T> | AnyString;
594
+ /** True if this entity represents a database view (not a virtual entity). Accepts `{ materialized: true }` as input, normalized to `true` during sync. */
595
+ view?: boolean | {
596
+ materialized?: boolean;
597
+ withData?: boolean;
598
+ };
599
+ /** True if this is a materialized view (PostgreSQL only). Requires `view: true`. */
600
+ materialized?: boolean;
601
+ /** For materialized views, whether data is populated on creation. Defaults to true. */
602
+ withData?: boolean;
603
+ expression?: string | ((em: any, where: ObjectQuery<Entity>, options: FindOptions<Entity, any, any, any>, stream?: boolean) => MaybePromise<Raw | object | string>);
604
+ discriminatorColumn?: EntityKey<Entity> | AnyString;
448
605
  discriminatorValue?: number | string;
449
- discriminatorMap?: Dictionary<string>;
606
+ discriminatorMap?: Dictionary<EntityClass>;
450
607
  embeddable: boolean;
451
- constructorParams?: (keyof T)[];
608
+ constructorParams?: (keyof Entity)[];
452
609
  forceConstructor: boolean;
453
- extends: string;
610
+ extends?: EntityName<Entity>;
454
611
  collection: string;
455
612
  path: string;
456
- primaryKeys: EntityKey<T>[];
613
+ primaryKeys: EntityKey<Entity>[];
457
614
  simplePK: boolean;
458
615
  compositePK: boolean;
459
- versionProperty: EntityKey<T>;
460
- concurrencyCheckKeys: Set<EntityKey<T>>;
461
- serializedPrimaryKey?: EntityKey<T>;
616
+ versionProperty: EntityKey<Entity>;
617
+ concurrencyCheckKeys: Set<EntityKey<Entity>>;
618
+ serializedPrimaryKey?: EntityKey<Entity>;
462
619
  properties: {
463
- [K in EntityKey<T>]: EntityProperty<T>;
620
+ [K in EntityKey<Entity>]: EntityProperty<Entity>;
464
621
  };
465
- props: EntityProperty<T>[];
466
- relations: EntityProperty<T>[];
467
- bidirectionalRelations: EntityProperty<T>[];
622
+ props: EntityProperty<Entity>[];
623
+ relations: EntityProperty<Entity>[];
624
+ bidirectionalRelations: EntityProperty<Entity>[];
468
625
  referencingProperties: {
469
- meta: EntityMetadata<T>;
470
- prop: EntityProperty<T>;
626
+ meta: EntityMetadata<Entity>;
627
+ prop: EntityProperty<Entity>;
471
628
  }[];
472
- comparableProps: EntityProperty<T>[];
473
- trackingProps: EntityProperty<T>[];
474
- hydrateProps: EntityProperty<T>[];
475
- validateProps: EntityProperty<T>[];
476
- uniqueProps: EntityProperty<T>[];
477
- getterProps: EntityProperty<T>[];
629
+ comparableProps: EntityProperty<Entity>[];
630
+ trackingProps: EntityProperty<Entity>[];
631
+ hydrateProps: EntityProperty<Entity>[];
632
+ validateProps: EntityProperty<Entity>[];
633
+ uniqueProps: EntityProperty<Entity>[];
634
+ getterProps: EntityProperty<Entity>[];
478
635
  indexes: {
479
- properties?: EntityKey<T> | EntityKey<T>[];
636
+ properties?: EntityKey<Entity> | EntityKey<Entity>[];
480
637
  name?: string;
481
638
  type?: string;
482
639
  options?: Dictionary;
483
- expression?: string | IndexCallback<T>;
640
+ expression?: string | IndexCallback<Entity>;
641
+ columns?: IndexColumnOptions[];
642
+ include?: EntityKey<Entity> | EntityKey<Entity>[];
643
+ fillFactor?: number;
644
+ invisible?: boolean;
645
+ disabled?: boolean;
646
+ clustered?: boolean;
484
647
  }[];
485
648
  uniques: {
486
- properties?: EntityKey<T> | EntityKey<T>[];
649
+ properties?: EntityKey<Entity> | EntityKey<Entity>[];
487
650
  name?: string;
488
651
  options?: Dictionary;
489
- expression?: string | IndexCallback<T>;
652
+ expression?: string | IndexCallback<Entity>;
490
653
  deferMode?: DeferMode | `${DeferMode}`;
654
+ columns?: IndexColumnOptions[];
655
+ include?: EntityKey<Entity> | EntityKey<Entity>[];
656
+ fillFactor?: number;
657
+ disabled?: boolean;
491
658
  }[];
492
- checks: CheckConstraint<T>[];
659
+ checks: CheckConstraint<Entity>[];
493
660
  repositoryClass?: string;
494
661
  repository: () => EntityClass<EntityRepository<any>>;
495
662
  hooks: {
496
- [K in EventType]?: (keyof T | EventSubscriber<T>[EventType])[];
663
+ [K in EventType]?: (keyof Entity | EventSubscriber<Entity>[EventType])[];
497
664
  };
498
- prototype: T;
499
- class: EntityClass<T>;
665
+ prototype: Entity;
666
+ class: Class;
500
667
  abstract: boolean;
501
668
  filters: Dictionary<FilterDef>;
502
669
  comment?: string;
@@ -504,9 +671,32 @@ export interface EntityMetadata<T = any> {
504
671
  hasUniqueProps?: boolean;
505
672
  readonly?: boolean;
506
673
  polymorphs?: EntityMetadata[];
507
- root: EntityMetadata<T>;
674
+ root: EntityMetadata<Entity>;
508
675
  definedProperties: Dictionary;
676
+ /** For polymorphic M:N pivot tables, maps discriminator values to entity classes */
677
+ polymorphicDiscriminatorMap?: Dictionary<EntityClass>;
678
+ /** Inheritance type: 'sti' (Single Table Inheritance) or 'tpt' (Table-Per-Type). Only set on root entities. */
679
+ inheritanceType?: 'sti' | 'tpt';
680
+ /** For TPT: direct parent entity metadata (the entity this one extends). */
681
+ tptParent?: EntityMetadata;
682
+ /** For TPT: direct child entities (entities that extend this one). */
683
+ tptChildren?: EntityMetadata[];
684
+ /** For TPT: all non-abstract descendants, sorted by depth (deepest first). Precomputed during discovery. */
685
+ allTPTDescendants?: EntityMetadata[];
686
+ /** For TPT: synthetic property representing the join to the parent table (child PK → parent PK). */
687
+ tptParentProp?: EntityProperty;
688
+ /** For TPT: inverse of tptParentProp, used for joining from parent to child (parent PK → child PK). */
689
+ tptInverseProp?: EntityProperty;
690
+ /** For TPT: virtual discriminator property name (computed at query time, not persisted). */
691
+ tptDiscriminatorColumn?: string;
692
+ /** For TPT: properties defined only in THIS entity (not inherited from parent). */
693
+ ownProps?: EntityProperty<Entity>[];
509
694
  hasTriggers?: boolean;
695
+ /**
696
+ * Default ordering for this entity. Applied when querying this entity directly
697
+ * or when it's populated as a relation. Combined with other orderings based on precedence.
698
+ */
699
+ orderBy?: QueryOrderMap<Entity> | QueryOrderMap<Entity>[];
510
700
  /** @internal can be used for computed numeric cache keys */
511
701
  readonly _id: number;
512
702
  }
@@ -714,13 +904,13 @@ export interface MigrationObject {
714
904
  type EntityFromInput<T> = T extends readonly EntityName<infer U>[] ? U : T extends EntityName<infer U> ? U : never;
715
905
  type FilterDefResolved<T extends object = any> = {
716
906
  name: string;
717
- cond: FilterQuery<T> | ((args: Dictionary, type: 'read' | 'update' | 'delete', em: any, options?: FindOptions<T, any, any, any> | FindOneOptions<T, any, any, any>, entityName?: EntityName<T>) => MaybePromise<FilterQuery<T>>);
907
+ cond: FilterQuery<T> | ((args: Dictionary, type: 'read' | 'update' | 'delete', em: any, options?: FindOptions<T, any, any, any> | FindOneOptions<T, any, any, any>, entityName?: string) => MaybePromise<FilterQuery<T>>);
718
908
  default?: boolean;
719
909
  entity?: EntityName<T> | EntityName<T>[];
720
910
  args?: boolean;
721
911
  strict?: boolean;
722
912
  };
723
- export type FilterDef<T extends EntityName<any> | readonly EntityName<any>[] = any> = FilterDefResolved<EntityFromInput<T>> & {
913
+ export type FilterDef<T extends EntityName | readonly EntityName[] = any> = FilterDefResolved<EntityFromInput<T>> & {
724
914
  entity?: T;
725
915
  };
726
916
  export type Populate<T, P extends string = never> = readonly AutoPath<T, P, `${PopulatePath}`>[] | false;
@@ -731,39 +921,61 @@ export type PopulateOptions<T> = {
731
921
  filter?: boolean;
732
922
  joinType?: 'inner join' | 'left join';
733
923
  children?: PopulateOptions<T[keyof T]>[];
924
+ /** When true, ignores `mapToPk` on the property and returns full entity data instead of just PKs. */
925
+ dataOnly?: boolean;
926
+ };
927
+ export type PopulateHintOptions = {
928
+ strategy?: LoadStrategy.JOINED | LoadStrategy.SELECT_IN | 'joined' | 'select-in';
929
+ joinType?: 'inner join' | 'left join';
734
930
  };
735
- type Loadable<T extends object> = Collection<T, any> | Reference<T> | Ref<T> | readonly T[];
736
- type ExtractType<T> = T extends Loadable<infer U> ? U : T;
931
+ type ExtractType<T> = T extends CollectionShape<infer U> ? U : T extends ReferenceShape<infer U> ? U : T extends Ref<infer U> ? U : T extends readonly (infer U)[] ? U : T;
737
932
  type ExtractStringKeys<T> = {
738
- [K in keyof T]: CleanKeys<T, K>;
933
+ [K in keyof T]-?: CleanKeys<T, K>;
739
934
  }[keyof T] & {};
740
- type StringKeys<T, E extends string = never> = T extends Collection<any, any> ? ExtractStringKeys<ExtractType<T>> | E : T extends Reference<any> ? ExtractStringKeys<ExtractType<T>> | E : T extends object ? ExtractStringKeys<ExtractType<T>> | E : never;
935
+ /**
936
+ * Extracts string keys from an entity type, handling Collection/Reference wrappers.
937
+ * Simplified to just check `T extends object` since ExtractType handles the unwrapping.
938
+ */
939
+ type StringKeys<T, E extends string = never> = T extends object ? ExtractStringKeys<ExtractType<T>> | E : never;
741
940
  type GetStringKey<T, K extends StringKeys<T, string>, E extends string> = K extends keyof T ? ExtractType<T[K]> : (K extends E ? keyof T : never);
742
941
  type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
743
- type CollectionKeys<T> = T extends object ? {
744
- [K in keyof T]: T[K] extends Collection<any> ? IsAny<T[K]> extends true ? never : K & string : never;
942
+ type RelationKeys<T> = T extends object ? {
943
+ [K in keyof T]-?: CleanKeys<T, K, true>;
745
944
  }[keyof T] & {} : never;
746
- export type AutoPath<O, P extends string | boolean, E extends string = never, D extends Prev[number] = 9> = P extends boolean ? P : [D] extends [never] ? never : P extends any ? P extends string ? (P & `${string}.` extends never ? P : P & `${string}.`) extends infer Q ? Q extends `${infer A}.${infer B}` ? A extends StringKeys<O, E> ? `${A}.${AutoPath<NonNullable<GetStringKey<O, A, E>>, B, E, Prev[D]>}` : never : Q extends StringKeys<O, E> ? (NonNullable<GetStringKey<O, Q, E>> extends unknown ? Exclude<P, `${string}.`> : never) | (StringKeys<NonNullable<GetStringKey<O, Q, E>>, E> extends never ? never : `${Q & string}.`) : StringKeys<O, E> | `${CollectionKeys<O>}:ref` : never : never : never;
945
+ export type AutoPath<O, P extends string | boolean, E extends string = never, D extends Prev[number] = 9> = P extends boolean ? P : [D] extends [never] ? never : P extends any ? P extends string ? P extends `${infer A}.${infer B}` ? A extends StringKeys<O, E> ? `${A}.${AutoPath<NonNullable<GetStringKey<O, A, E>>, B, E, Prev[D]>}` : never : P extends StringKeys<O, E> ? (NonNullable<GetStringKey<O, P & StringKeys<O, E>, E>> extends unknown ? Exclude<P, `${string}.`> : never) | (StringKeys<NonNullable<GetStringKey<O, P & StringKeys<O, E>, E>>, E> extends never ? never : `${P & string}.`) : StringKeys<O, E> | `${RelationKeys<O>}:ref` : never : never;
747
946
  export type UnboxArray<T> = T extends any[] ? ArrayElement<T> : T;
748
947
  export type ArrayElement<ArrayType extends unknown[]> = ArrayType extends (infer ElementType)[] ? ElementType : never;
749
- export type ExpandProperty<T> = T extends Reference<infer U> ? NonNullable<U> : T extends Collection<infer U, any> ? NonNullable<U> : T extends (infer U)[] ? NonNullable<U> : NonNullable<T>;
750
- type LoadedLoadable<T, E extends object> = T extends Collection<any, any> ? LoadedCollection<E> : T extends Reference<any> ? T & LoadedReference<E> : T extends ScalarReference<infer U> ? LoadedScalarReference<U> : T extends Scalar | any[] ? T : E;
948
+ export type ExpandProperty<T> = T extends ReferenceShape<infer U> ? NonNullable<U> : T extends CollectionShape<infer U> ? NonNullable<U> : T extends (infer U)[] ? NonNullable<U> : NonNullable<T>;
949
+ type LoadedLoadable<T, E extends object> = T extends CollectionShape ? LoadedCollection<E> : T extends ScalarReference<infer U> ? LoadedScalarReference<U> : T extends ReferenceShape ? T & LoadedReference<E> : T extends Scalar ? T : T extends (infer U)[] ? U extends Scalar ? T : E[] : E;
751
950
  type IsTrue<T> = IsNever<T> extends true ? false : T extends boolean ? T extends true ? true : false : false;
752
951
  type StringLiteral<T> = T extends string ? string extends T ? never : T : never;
753
952
  type Prefix<T, K> = K extends `${infer S}.${string}` ? S : (K extends '*' ? keyof T : K);
754
953
  type IsPrefixedExclude<T, K extends keyof T, E extends string> = K extends E ? never : K;
755
- export type IsPrefixed<T, K extends keyof T, L extends string, E extends string = never> = IsNever<E> extends false ? IsPrefixedExclude<T, K, E> : K extends symbol ? never : IsTrue<L> extends true ? (T[K] & {} extends Loadable<any> ? K : never) : IsNever<StringLiteral<L>> extends true ? never : K extends Prefix<T, L> ? K : K extends PrimaryProperty<T> ? K : never;
954
+ export type IsPrefixed<T, K extends keyof T, L extends string, E extends string = never> = IsNever<E> extends false ? IsPrefixedExclude<T, K, E> : K extends symbol ? never : IsTrue<L> extends true ? (T[K] & {} extends LoadableShape ? K : never) : IsNever<StringLiteral<L>> extends true ? never : L extends '*' ? K : K extends Prefix<T, L> ? K : K extends PrimaryProperty<T> ? K : never;
756
955
  type Suffix<Key, Hint extends string, All = true | '*'> = Hint extends `${infer Pref}.${infer Suf}` ? (Pref extends Key ? Suf : never) : Hint extends All ? Hint : never;
757
- export type IsSubset<T, U> = keyof U extends keyof T ? {} : Dictionary extends U ? {} : {
956
+ export type IsSubset<T, U> = keyof U extends keyof T ? {} : string extends keyof U ? {} : {
758
957
  [K in keyof U as K extends keyof T ? never : CleanKeys<U, K>]: never;
759
958
  };
760
- declare const __selectedType: unique symbol;
761
- declare const __loadedType: unique symbol;
762
- type AnyStringToNever<T> = string extends T ? never : T;
763
- export type MergeSelected<T, U, F extends string> = T extends Loaded<infer TT, infer P, infer FF, infer E> ? IsNever<Exclude<E, F>> extends true ? Loaded<TT, P, AnyStringToNever<F> | AnyStringToNever<FF>> : Loaded<TT, AnyStringToNever<P>, AnyStringToNever<FF>, AnyStringToNever<Exclude<E, F>>> : T;
764
- type MergeFields<F1 extends string, F2 extends string, P1, P2> = P1 | P2 extends '*' ? '*' : F1 | F2;
765
- type MergeExcludes<F extends string, E extends string> = F extends E ? never : Exclude<E, F>;
766
- export type MergeLoaded<T, U, P extends string, F extends string, E extends string, R extends boolean = false> = T extends Loaded<U, infer PP, infer FF, infer EE> ? string extends FF ? Loaded<T, P, F, AnyStringToNever<EE> | E> : string extends P ? Loaded<U, never, F | (FF & string), MergeExcludes<F | (FF & string), EE | E>> : Loaded<U, P | AnyStringToNever<PP>, MergeFields<F, AnyStringToNever<FF>, P, PP>, MergeExcludes<MergeFields<F, AnyStringToNever<FF>, P, PP>, (R extends true ? never : EE) | E>> : Loaded<T, P, F>;
959
+ /**
960
+ * Fast check if T is a Loaded type by looking for the marker symbol.
961
+ * This is much cheaper than matching against the full Loaded structure.
962
+ */
963
+ type IsLoadedType<T> = T extends {
964
+ [__loadedType]?: any;
965
+ } ? true : false;
966
+ /**
967
+ * Optimized MergeSelected using intersection instead of extraction.
968
+ * When T is already Loaded, we intersect with a new Loaded type for the selected fields.
969
+ * This avoids the expensive pattern matching needed to extract hints from Loaded types.
970
+ */
971
+ export type MergeSelected<T, U, F extends string> = IsLoadedType<T> extends true ? T & Loaded<U, never, F, never> : T;
972
+ /**
973
+ * Optimized MergeLoaded using intersection instead of extraction.
974
+ * When T is already Loaded, we intersect with a new Loaded type for the additional hints.
975
+ * This avoids the expensive pattern matching needed to extract hints from Loaded types.
976
+ * Used for `em.populate` and `em.refresh`.
977
+ */
978
+ export type MergeLoaded<T, U, P extends string, F extends string, E extends string, R extends boolean = false> = IsLoadedType<T> extends true ? T & Loaded<U, P, F, E> : Loaded<T, P, F, E>;
767
979
  export type AddOptional<T> = undefined | null extends T ? null | undefined : null extends T ? null : undefined extends T ? undefined : never;
768
980
  type LoadedProp<T, L extends string = never, F extends string = '*', E extends string = never> = LoadedLoadable<T, Loaded<ExtractType<T>, L, F, E>>;
769
981
  export type AddEager<T> = ExtractEagerProps<T> & string;
@@ -782,18 +994,18 @@ type LoadedEntityType<T> = {
782
994
  };
783
995
  export type EntityType<T> = T | LoadedEntityType<T>;
784
996
  export type FromEntityType<T> = T extends LoadedEntityType<infer U> ? U : T;
785
- type LoadedInternal<T, L extends string = never, F extends string = '*', E extends string = never> = [
786
- F
787
- ] extends ['*'] ? IsNever<E> extends true ? T & {
997
+ type LoadedInternal<T, L extends string = never, F extends string = '*', E extends string = never> = [F] extends ['*'] ? IsNever<E> extends true ? T & {
788
998
  [K in keyof T as IsPrefixed<T, K, ExpandHint<T, L>>]: LoadedProp<NonNullable<T[K]>, Suffix<K, L>, Suffix<K, F>, Suffix<K, E>> | AddOptional<T[K]>;
789
999
  } : {
790
1000
  [K in keyof T as IsPrefixed<T, K, ExpandHint<T, L>, E>]: LoadedProp<NonNullable<T[K]>, Suffix<K, L>, Suffix<K, F>, Suffix<K, E>> | AddOptional<T[K]>;
791
1001
  } : Selected<T, L, F>;
792
1002
  /**
793
1003
  * Represents entity with its loaded relations (`populate` hint) and selected properties (`fields` hint).
1004
+ * The __loadHint marker uses contravariance to ensure Loaded<A, 'b'> is NOT assignable to Loaded<A, 'b.c'>.
794
1005
  */
795
1006
  export type Loaded<T, L extends string = never, F extends string = '*', E extends string = never> = LoadedInternal<T, L, F, E> & {
796
1007
  [__loadedType]?: T;
1008
+ [__loadHint]?: (hint: Prefixes<L>) => void;
797
1009
  };
798
1010
  export interface LoadedReference<T> extends Reference<NonNullable<T>> {
799
1011
  $: NonNullable<T>;
@@ -813,12 +1025,12 @@ export interface Highlighter {
813
1025
  highlight(text: string): string;
814
1026
  }
815
1027
  export interface IMetadataStorage {
816
- getAll(): Dictionary<EntityMetadata>;
817
- get<T = any>(entity: string, init?: boolean, validate?: boolean): EntityMetadata<T>;
818
- find<T = any>(entity: string): EntityMetadata<T> | undefined;
819
- has(entity: string): boolean;
820
- set(entity: string, meta: EntityMetadata): EntityMetadata;
821
- reset(entity: string): void;
1028
+ getAll(): Map<EntityName, EntityMetadata>;
1029
+ get<T = any>(entity: EntityName<T>, init?: boolean, validate?: boolean): EntityMetadata<T>;
1030
+ find<T = any>(entity: EntityName<T>): EntityMetadata<T> | undefined;
1031
+ has<T>(entity: EntityName<T>): boolean;
1032
+ set<T>(entity: EntityName<T>, meta: EntityMetadata): EntityMetadata;
1033
+ reset<T>(entity: EntityName<T>): void;
822
1034
  }
823
1035
  export interface IHydrator {
824
1036
  /**
@@ -847,10 +1059,13 @@ export interface Seeder<T extends Dictionary = Dictionary> {
847
1059
  export type ConnectionType = 'read' | 'write';
848
1060
  export type MetadataProcessor = (metadata: EntityMetadata[], platform: Platform) => MaybePromise<void>;
849
1061
  export type MaybeReturnType<T> = T extends (...args: any[]) => infer R ? R : T;
850
- export interface EntitySchemaWithMeta<TName extends string = string, TTableName extends string = string, TEntity = any, TBase = never, TProperties extends Record<string, any> = Record<string, any>> extends EntitySchema<TEntity, TBase> {
1062
+ export interface EntitySchemaWithMeta<TName extends string = string, TTableName extends string = string, TEntity = any, TBase = never, TProperties extends Record<string, any> = Record<string, any>, TClass extends EntityCtor = EntityCtor<TEntity>> extends EntitySchema<TEntity, TBase, TClass> {
851
1063
  readonly name: TName;
852
1064
  readonly properties: TProperties;
853
1065
  readonly tableName: TTableName;
1066
+ /** @internal Direct entity type access - avoids expensive pattern matching */
1067
+ readonly '~entity': TEntity;
854
1068
  }
855
- export type InferEntity<Schema> = Schema extends EntitySchemaWithMeta<any, any, infer Entity, any, any> ? Entity : Schema extends EntitySchema<infer Entity> ? Entity : Schema extends EntityClass<infer Entity> ? Entity : Schema;
856
- export {};
1069
+ export type InferEntity<Schema> = Schema extends {
1070
+ '~entity': infer E;
1071
+ } ? E : Schema extends EntitySchema<infer Entity> ? Entity : Schema extends EntityClass<infer Entity> ? Entity : Schema;