@mikro-orm/core 7.1.0-dev.3 → 7.1.0-dev.30

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 (54) hide show
  1. package/EntityManager.d.ts +44 -11
  2. package/EntityManager.js +139 -31
  3. package/drivers/IDatabaseDriver.d.ts +39 -1
  4. package/entity/BaseEntity.d.ts +68 -1
  5. package/entity/BaseEntity.js +18 -0
  6. package/entity/Collection.d.ts +6 -3
  7. package/entity/Collection.js +15 -4
  8. package/entity/EntityFactory.js +20 -1
  9. package/entity/EntityLoader.d.ts +3 -1
  10. package/entity/EntityLoader.js +39 -16
  11. package/entity/EntityRepository.d.ts +27 -9
  12. package/entity/EntityRepository.js +12 -0
  13. package/entity/Reference.d.ts +42 -1
  14. package/entity/Reference.js +9 -0
  15. package/entity/defineEntity.d.ts +105 -23
  16. package/entity/defineEntity.js +17 -6
  17. package/entity/utils.js +4 -5
  18. package/errors.d.ts +2 -0
  19. package/errors.js +4 -0
  20. package/index.d.ts +2 -2
  21. package/index.js +1 -1
  22. package/metadata/EntitySchema.js +3 -0
  23. package/metadata/MetadataDiscovery.d.ts +12 -0
  24. package/metadata/MetadataDiscovery.js +185 -16
  25. package/metadata/MetadataValidator.d.ts +24 -0
  26. package/metadata/MetadataValidator.js +202 -1
  27. package/metadata/types.d.ts +77 -4
  28. package/naming-strategy/AbstractNamingStrategy.d.ts +1 -1
  29. package/naming-strategy/NamingStrategy.d.ts +1 -1
  30. package/package.json +1 -1
  31. package/platforms/Platform.d.ts +8 -1
  32. package/platforms/Platform.js +40 -4
  33. package/serialization/EntitySerializer.js +2 -1
  34. package/typings.d.ts +176 -18
  35. package/typings.js +22 -5
  36. package/unit-of-work/UnitOfWork.js +3 -0
  37. package/utils/AbstractMigrator.d.ts +20 -5
  38. package/utils/AbstractMigrator.js +263 -28
  39. package/utils/AbstractSchemaGenerator.d.ts +1 -1
  40. package/utils/AbstractSchemaGenerator.js +4 -1
  41. package/utils/Configuration.d.ts +25 -0
  42. package/utils/Configuration.js +1 -0
  43. package/utils/DataloaderUtils.d.ts +10 -1
  44. package/utils/DataloaderUtils.js +78 -0
  45. package/utils/EntityComparator.js +1 -1
  46. package/utils/QueryHelper.d.ts +16 -0
  47. package/utils/QueryHelper.js +15 -0
  48. package/utils/Utils.js +1 -1
  49. package/utils/fs-utils.d.ts +2 -0
  50. package/utils/fs-utils.js +7 -1
  51. package/utils/index.d.ts +1 -0
  52. package/utils/index.js +1 -0
  53. package/utils/partition-utils.d.ts +17 -0
  54. package/utils/partition-utils.js +79 -0
@@ -1,6 +1,6 @@
1
1
  import type { EntityManager } from '../EntityManager.js';
2
2
  import type { ColumnType, PropertyOptions, ReferenceOptions, EnumOptions, EmbeddedOptions, ManyToOneOptions, OneToManyOptions, OneToOneOptions, ManyToManyOptions, IndexColumnOptions } from '../metadata/types.js';
3
- import type { AnyString, GeneratedColumnCallback, Constructor, CheckCallback, FilterQuery, EntityName, Dictionary, EntityMetadata, PrimaryKeyProp, EntityRepositoryType, Hidden, Opt, Primary, EntityClass, EntitySchemaWithMeta, InferEntity, MaybeReturnType, Ref, IndexCallback, FormulaCallback, EntityCtor, IsNever, IWrappedEntity, DefineConfig, Config, MaybePromise } from '../typings.js';
3
+ import type { AnyString, GeneratedColumnCallback, Constructor, CheckCallback, FilterQuery, EntityName, Dictionary, EntityMetadata, PrimaryKeyProp, EntityRepositoryType, Hidden, Opt, Primary, EntityClass, EntitySchemaWithMeta, InferEntity, MaybeReturnType, Ref, LazyRef, IndexCallback, TriggerCallback, FormulaCallback, EntityCtor, IsNever, IWrappedEntity, DefineConfig, Config, MaybePromise, IndexHints } from '../typings.js';
4
4
  import type { Raw } from '../utils/RawQueryFragment.js';
5
5
  import type { ScalarReference } from './Reference.js';
6
6
  import type { SerializeOptions } from '../serialization/EntitySerializer.js';
@@ -12,7 +12,7 @@ import type { Collection } from './Collection.js';
12
12
  import type { FilterOptions, FindOptions, FindOneOptions } from '../drivers/IDatabaseDriver.js';
13
13
  /** Union of all option keys supported across all property definition types (scalar, enum, embedded, relations). */
14
14
  export type UniversalPropertyKeys = keyof PropertyOptions<any> | keyof EnumOptions<any> | keyof EmbeddedOptions<any, any> | keyof ReferenceOptions<any, any> | keyof ManyToOneOptions<any, any> | keyof OneToManyOptions<any, any> | keyof OneToOneOptions<any, any> | keyof ManyToManyOptions<any, any>;
15
- type BuilderExtraKeys = '~options' | '~type' | '$type' | 'strictNullable';
15
+ type BuilderExtraKeys = '~options' | '~type' | '$type' | 'strictNullable' | 'lazyRef';
16
16
  type ExcludeKeys = 'entity' | 'items';
17
17
  type BuilderKeys = Exclude<UniversalPropertyKeys, ExcludeKeys> | BuilderExtraKeys;
18
18
  type IncludeKeysForProperty = Exclude<keyof PropertyOptions<any>, ExcludeKeys> | BuilderExtraKeys;
@@ -36,9 +36,23 @@ export interface PropertyChain<Value, Options> {
36
36
  nullable: true;
37
37
  strictNullable: true;
38
38
  }>;
39
- ref(): PropertyChain<Value, Omit<Options, 'ref'> & {
39
+ ref(): Options extends {
40
+ lazyRef: true;
41
+ } ? never : PropertyChain<Value, Omit<Options, 'ref'> & {
40
42
  ref: true;
41
43
  }>;
44
+ /**
45
+ * Mark a to-one relation (`m:1`/`1:1`) as a {@apilink LazyRef} — direct entity at runtime, type-restricted
46
+ * until `Loaded<>` narrows it. Type-level only, no `ref: true` wrapping. Not compatible with `.ref()` or
47
+ * `.mapToPk()` — those chains are rejected in both directions at compile time.
48
+ */
49
+ lazyRef(): HasKind<Options, 'm:1' | '1:1'> extends true ? Options extends {
50
+ ref: true;
51
+ } | {
52
+ mapToPk: true;
53
+ } ? never : PropertyChain<Value, Omit<Options, 'lazyRef'> & {
54
+ lazyRef: true;
55
+ }> : never;
42
56
  primary(): PropertyChain<Value, Omit<Options, 'primary'> & {
43
57
  primary: true;
44
58
  }>;
@@ -103,10 +117,19 @@ export interface PropertyChain<Value, Options> {
103
117
  groups(...groups: string[]): PropertyChain<Value, Options>;
104
118
  customOrder(...customOrder: string[] | number[] | boolean[]): PropertyChain<Value, Options>;
105
119
  extra(extra: string): PropertyChain<Value, Options>;
106
- ignoreSchemaChanges(...ignoreSchemaChanges: ('type' | 'extra' | 'default')[]): PropertyChain<Value, Options>;
107
- index(index?: boolean | string): PropertyChain<Value, Options>;
108
- unique(unique?: boolean | string): PropertyChain<Value, Options>;
120
+ ignoreSchemaChanges(...ignoreSchemaChanges: ('type' | 'extra' | 'default' | 'collation')[]): PropertyChain<Value, Options>;
121
+ /** Explicitly specify index on a property. When a string name is passed, it enables type-safe `using` in `FindOptions`. */
122
+ index<N extends string>(name: N): PropertyChain<Value, Omit<Options, 'index'> & {
123
+ index: N;
124
+ }>;
125
+ index(index?: boolean): PropertyChain<Value, Options>;
126
+ /** Set column as unique. When a string name is passed, it enables type-safe `using` in `FindOptions`. (SQL only) */
127
+ unique<N extends string>(name: N): PropertyChain<Value, Omit<Options, 'unique'> & {
128
+ unique: N;
129
+ }>;
130
+ unique(unique?: boolean): PropertyChain<Value, Options>;
109
131
  comment(comment: string): PropertyChain<Value, Options>;
132
+ collation(collation: string): PropertyChain<Value, Options>;
110
133
  accessor(accessor?: string | boolean): PropertyChain<Value, Options>;
111
134
  eager(eager?: boolean): HasKind<Options, 'm:1' | '1:m' | '1:1' | 'm:n'> extends true ? PropertyChain<Value, Options> : never;
112
135
  cascade(...cascade: Cascade[]): HasKind<Options, 'm:1' | '1:m' | '1:1' | 'm:n'> extends true ? PropertyChain<Value, Options> : never;
@@ -117,7 +140,9 @@ export interface PropertyChain<Value, Options> {
117
140
  owner(): HasKind<Options, '1:1' | 'm:n'> extends true ? PropertyChain<Value, Omit<Options, 'owner'> & {
118
141
  owner: true;
119
142
  }> : never;
120
- mapToPk(): HasKind<Options, 'm:1' | '1:1'> extends true ? PropertyChain<Value, Omit<Options, 'mapToPk'> & {
143
+ mapToPk(): HasKind<Options, 'm:1' | '1:1'> extends true ? Options extends {
144
+ lazyRef: true;
145
+ } ? never : PropertyChain<Value, Omit<Options, 'mapToPk'> & {
121
146
  mapToPk: true;
122
147
  }> : never;
123
148
  orphanRemoval(orphanRemoval?: boolean): HasKind<Options, '1:m' | '1:1'> extends true ? PropertyChain<Value, Options> : never;
@@ -127,9 +152,13 @@ export interface PropertyChain<Value, Options> {
127
152
  pivotEntity(pivotEntity: () => EntityName): HasKind<Options, 'm:n'> extends true ? PropertyChain<Value, Options> : never;
128
153
  fixedOrder(fixedOrder?: boolean): HasKind<Options, 'm:n'> extends true ? PropertyChain<Value, Options> : never;
129
154
  fixedOrderColumn(fixedOrderColumn: string): HasKind<Options, 'm:n'> extends true ? PropertyChain<Value, Options> : never;
130
- array(): HasKind<Options, 'embedded' | 'enum'> extends true ? PropertyChain<Value, Omit<Options, 'array'> & {
155
+ array(): Options extends {
156
+ kind: infer K extends string;
157
+ } ? K extends 'embedded' | 'enum' ? PropertyChain<Value, Omit<Options, 'array'> & {
131
158
  array: true;
132
- }> : never;
159
+ }> : never : PropertyChain<Value, Omit<Options, 'array'> & {
160
+ array: true;
161
+ }>;
133
162
  prefix(prefix: string | boolean): HasKind<Options, 'embedded'> extends true ? PropertyChain<Value, Options> : never;
134
163
  prefixMode(prefixMode: EmbeddedPrefixMode): HasKind<Options, 'embedded'> extends true ? PropertyChain<Value, Options> : never;
135
164
  object(object?: boolean): HasKind<Options, 'embedded'> extends true ? PropertyChain<Value, Options> : never;
@@ -313,9 +342,24 @@ export declare class UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys
313
342
  /**
314
343
  * Enable `ScalarReference` wrapper for lazy values. Use this in combination with `lazy: true` to have a type-safe accessor object in place of the value.
315
344
  */
316
- ref(): UniversalPropertyOptionsBuilder<Value, Omit<Options, 'ref'> & {
345
+ ref(): Options extends {
346
+ lazyRef: true;
347
+ } ? never : UniversalPropertyOptionsBuilder<Value, Omit<Options, 'ref'> & {
317
348
  ref: true;
318
349
  }, IncludeKeys>;
350
+ /**
351
+ * Mark a to-one relation (`m:1`/`1:1`) as a {@apilink LazyRef} — the runtime value stays a plain entity
352
+ * (no `Reference` wrapper) but the TypeScript type restricts access to the primary key until `Loaded<>`
353
+ * narrows it. Type-level only; does not set `ref: true`. Not compatible with `.ref()` or `.mapToPk()` —
354
+ * those chains are rejected in both directions at compile time.
355
+ */
356
+ lazyRef(): HasKind<Options, 'm:1' | '1:1'> extends true ? Options extends {
357
+ ref: true;
358
+ } | {
359
+ mapToPk: true;
360
+ } ? never : UniversalPropertyOptionsBuilder<Value, Omit<Options, 'lazyRef'> & {
361
+ lazyRef: true;
362
+ }, IncludeKeys> : never;
319
363
  /**
320
364
  * Set to true to omit the property when {@link https://mikro-orm.io/docs/serializing Serializing}.
321
365
  */
@@ -334,12 +378,20 @@ export declare class UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys
334
378
  concurrencyCheck(concurrencyCheck?: boolean): Pick<UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>, IncludeKeys>;
335
379
  /**
336
380
  * Explicitly specify index on a property.
381
+ * When a string name is passed, it is captured as a literal type for use with the `using` option in `FindOptions`.
337
382
  */
338
- index(index?: boolean | string): Pick<UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>, IncludeKeys>;
383
+ index<N extends string>(name: N): Pick<UniversalPropertyOptionsBuilder<Value, Omit<Options, 'index'> & {
384
+ index: N;
385
+ }, IncludeKeys>, IncludeKeys>;
386
+ index(index?: boolean): Pick<UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>, IncludeKeys>;
339
387
  /**
340
388
  * Set column as unique for {@link https://mikro-orm.io/docs/schema-generator Schema Generator}. (SQL only)
389
+ * When a string name is passed, it is captured as a literal type for use with the `using` option in `FindOptions`.
341
390
  */
342
- unique(unique?: boolean | string): Pick<UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>, IncludeKeys>;
391
+ unique<N extends string>(name: N): Pick<UniversalPropertyOptionsBuilder<Value, Omit<Options, 'unique'> & {
392
+ unique: N;
393
+ }, IncludeKeys>, IncludeKeys>;
394
+ unique(unique?: boolean): Pick<UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>, IncludeKeys>;
343
395
  /**
344
396
  * Specify column with check constraints. (Postgres driver only)
345
397
  *
@@ -427,6 +479,11 @@ export declare class UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys
427
479
  * Specify comment of column for {@link https://mikro-orm.io/docs/schema-generator Schema Generator}. (SQL only)
428
480
  */
429
481
  comment(comment: string): Pick<UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>, IncludeKeys>;
482
+ /**
483
+ * Specify column-level collation for {@link https://mikro-orm.io/docs/schema-generator Schema Generator}. (SQL only)
484
+ * Emits a `COLLATE` clause on the column definition; the accepted collation names are dialect-specific.
485
+ */
486
+ collation(collation: string): Pick<UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>, IncludeKeys>;
430
487
  /** mysql only */
431
488
  extra(extra: string): Pick<UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>, IncludeKeys>;
432
489
  /**
@@ -434,7 +491,7 @@ export declare class UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys
434
491
  *
435
492
  * @see https://mikro-orm.io/docs/defining-entities#sql-generated-columns
436
493
  */
437
- ignoreSchemaChanges(...ignoreSchemaChanges: ('type' | 'extra' | 'default')[]): Pick<UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>, IncludeKeys>;
494
+ ignoreSchemaChanges(...ignoreSchemaChanges: ('type' | 'extra' | 'default' | 'collation')[]): Pick<UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>, IncludeKeys>;
438
495
  array(): Pick<UniversalPropertyOptionsBuilder<Value, Omit<Options, 'array'> & {
439
496
  array: true;
440
497
  }, IncludeKeys>, IncludeKeys>;
@@ -492,7 +549,9 @@ export declare class UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys
492
549
  /** What to do when the reference to the target entity gets updated. */
493
550
  updateRule(updateRule: 'cascade' | 'no action' | 'set null' | 'set default' | AnyString): Pick<UniversalPropertyOptionsBuilder<Value, Options, IncludeKeys>, IncludeKeys>;
494
551
  /** Map this relation to the primary key value instead of an entity. */
495
- mapToPk(): Pick<UniversalPropertyOptionsBuilder<Value, Omit<Options, 'mapToPk'> & {
552
+ mapToPk(): Options extends {
553
+ lazyRef: true;
554
+ } ? never : Pick<UniversalPropertyOptionsBuilder<Value, Omit<Options, 'mapToPk'> & {
496
555
  mapToPk: true;
497
556
  }, IncludeKeys>, IncludeKeys>;
498
557
  /** Set the constraint type. Immediate constraints are checked for each statement, while deferred ones are only checked at the end of the transaction. Only for postgres unique constraints. */
@@ -536,7 +595,7 @@ export type PropertyBuilders = {
536
595
  datetime: (length?: number) => UniversalPropertyOptionsBuilder<InferPropertyValueType<typeof types.datetime>, EmptyOptions, IncludeKeysForProperty>;
537
596
  time: (length?: number) => UniversalPropertyOptionsBuilder<InferPropertyValueType<typeof types.time>, EmptyOptions, IncludeKeysForProperty>;
538
597
  type: <T extends PropertyValueType>(type: T) => UniversalPropertyOptionsBuilder<InferPropertyValueType<T>, EmptyOptions, IncludeKeysForProperty>;
539
- enum: <const T extends readonly (number | string)[] | (() => Dictionary)>(items?: T) => UniversalPropertyOptionsBuilder<T extends () => Dictionary ? ValueOf<ReturnType<T>> : T extends readonly (infer Value)[] ? Value : T, EmptyOptions, IncludeKeysForEnumOptions>;
598
+ enum: <const T extends readonly (number | string)[] | Dictionary | (() => Dictionary)>(items?: T) => UniversalPropertyOptionsBuilder<T extends () => Dictionary ? ValueOf<ReturnType<T>> : T extends readonly (infer Value)[] ? Value : T extends Dictionary ? ValueOf<T> : T, EmptyOptions, IncludeKeysForEnumOptions>;
540
599
  embedded: <Target extends EntityTarget | EntityTarget[]>(target: Target) => PropertyChain<InferEntity<Target extends (infer T)[] ? T : Target>, EmptyOptions & {
541
600
  kind: 'embedded';
542
601
  }>;
@@ -556,12 +615,15 @@ export type PropertyBuilders = {
556
615
  /** Own keys + base entity keys (when TBase is not `never`). Guards against `keyof never = string | number | symbol`. */
557
616
  type AllKeys<TProperties, TBase> = keyof TProperties | (IsNever<TBase> extends true ? never : keyof TBase);
558
617
  /** Metadata descriptor for `defineEntity()`, combining entity options with property definitions. */
559
- export interface EntityMetadataWithProperties<TName extends string, TTableName extends string, TProperties extends Record<string, any>, TPK extends (keyof TProperties)[] | undefined = undefined, TBase = never, TRepository = never, TForceObject extends boolean = false> extends Omit<Partial<EntityMetadata<InferEntityFromProperties<TProperties, TPK, TBase, TRepository>>>, 'properties' | 'extends' | 'primaryKeys' | 'hooks' | 'discriminatorColumn' | 'versionProperty' | 'concurrencyCheckKeys' | 'serializedPrimaryKey' | 'indexes' | 'uniques' | 'repository' | 'filters' | 'orderBy'> {
618
+ export interface EntityMetadataWithProperties<TName extends string, TTableName extends string, TProperties extends Record<string, any>, TPK extends (keyof TProperties)[] | undefined = undefined, TBase = never, TRepository = never, TForceObject extends boolean = false, TDiscriminatorColumn extends string | undefined = undefined, TDiscriminatorValue extends string | number | undefined = undefined, TBaseDiscriminatorColumn extends string | undefined = undefined> extends Omit<Partial<EntityMetadata<InferEntityFromProperties<TProperties, TPK, TBase, TRepository>>>, 'properties' | 'extends' | 'primaryKeys' | 'hooks' | 'discriminatorColumn' | 'discriminatorValue' | 'versionProperty' | 'concurrencyCheckKeys' | 'serializedPrimaryKey' | 'indexes' | 'uniques' | 'triggers' | 'repository' | 'filters' | 'orderBy'> {
560
619
  name: TName;
561
620
  tableName?: TTableName;
562
621
  extends?: {
563
622
  '~entity': TBase;
564
- } | EntityCtor<TBase>;
623
+ '~discriminatorColumn'?: TBaseDiscriminatorColumn;
624
+ } | (EntityCtor<TBase> & {
625
+ '~discriminatorColumn'?: TBaseDiscriminatorColumn;
626
+ });
565
627
  properties: TProperties | ((properties: PropertyBuilders) => TProperties);
566
628
  primaryKeys?: TPK & InferPrimaryKeyConstraint<TProperties>[];
567
629
  hooks?: DefineEntityHooks;
@@ -581,7 +643,8 @@ export interface EntityMetadataWithProperties<TName extends string, TTableName e
581
643
  } | {
582
644
  [K in Extract<AllKeys<TProperties, TBase>, string>]?: QueryOrderKeysFlat;
583
645
  }[];
584
- discriminatorColumn?: string;
646
+ discriminatorColumn?: TDiscriminatorColumn;
647
+ discriminatorValue?: TDiscriminatorValue;
585
648
  versionProperty?: AllKeys<TProperties, TBase>;
586
649
  concurrencyCheckKeys?: Set<AllKeys<TProperties, TBase>>;
587
650
  serializedPrimaryKey?: AllKeys<TProperties, TBase>;
@@ -591,6 +654,7 @@ export interface EntityMetadataWithProperties<TName extends string, TTableName e
591
654
  type?: string;
592
655
  options?: Dictionary;
593
656
  expression?: string | IndexCallback<InferEntityFromProperties<TProperties, TPK, TBase>>;
657
+ where?: string | FilterQuery<InferEntityFromProperties<TProperties, TPK, TBase>>;
594
658
  columns?: IndexColumnOptions[];
595
659
  include?: NoInfer<AllKeys<TProperties, TBase>> | NoInfer<AllKeys<TProperties, TBase>>[];
596
660
  fillFactor?: number;
@@ -603,15 +667,25 @@ export interface EntityMetadataWithProperties<TName extends string, TTableName e
603
667
  name?: string;
604
668
  options?: Dictionary;
605
669
  expression?: string | IndexCallback<InferEntityFromProperties<TProperties, TPK, TBase>>;
670
+ where?: string | FilterQuery<InferEntityFromProperties<TProperties, TPK, TBase>>;
606
671
  deferMode?: DeferMode | `${DeferMode}`;
607
672
  columns?: IndexColumnOptions[];
608
673
  include?: NoInfer<AllKeys<TProperties, TBase>> | NoInfer<AllKeys<TProperties, TBase>>[];
609
674
  fillFactor?: number;
610
675
  disabled?: boolean;
611
676
  }[];
677
+ triggers?: {
678
+ name?: string;
679
+ timing: 'before' | 'after' | 'instead of';
680
+ events: ('insert' | 'update' | 'delete' | 'truncate')[];
681
+ forEach?: 'row' | 'statement';
682
+ body?: string | Raw | TriggerCallback<InferEntityFromProperties<TProperties, TPK, TBase>>;
683
+ when?: string;
684
+ expression?: string;
685
+ }[];
612
686
  }
613
687
  /** Defines an entity schema using property builders, with full type inference from the property definitions. */
614
- export declare function defineEntity<const TName extends string, const TTableName extends string, const TProperties extends Record<string, any>, const TPK extends (keyof TProperties)[] | undefined = undefined, const TBase = never, const TRepository = never, const TForceObject extends boolean = false>(meta: EntityMetadataWithProperties<TName, TTableName, TProperties, TPK, TBase, TRepository, TForceObject>): EntitySchemaWithMeta<TName, TTableName, InferEntityFromProperties<TProperties, TPK, TBase, TRepository, TForceObject>, TBase, TProperties>;
688
+ export declare function defineEntity<const TName extends string, const TTableName extends string, const TProperties extends Record<string, any>, const TPK extends (keyof TProperties)[] | undefined = undefined, const TBase = never, const TRepository = never, const TForceObject extends boolean = false, const TDiscriminatorColumn extends string | undefined = undefined, const TDiscriminatorValue extends string | number | undefined = undefined, const TBaseDiscriminatorColumn extends string | undefined = undefined>(meta: EntityMetadataWithProperties<TName, TTableName, TProperties, TPK, TBase, TRepository, TForceObject, TDiscriminatorColumn, TDiscriminatorValue, TBaseDiscriminatorColumn>): EntitySchemaWithMeta<TName, TTableName, InferEntityFromProperties<TProperties, TPK, TBase, TRepository, TForceObject, TBaseDiscriminatorColumn, TDiscriminatorValue>, TBase, TProperties, EntityCtor<InferEntityFromProperties<TProperties, TPK, TBase, TRepository, TForceObject, TBaseDiscriminatorColumn, TDiscriminatorValue>>, TDiscriminatorColumn>;
615
689
  /** Defines an entity schema for an existing class, combining the class with property builders. */
616
690
  export declare function defineEntity<const TEntity = any, const TProperties extends Record<string, any> = Record<string, any>, const TClassName extends string = string, const TTableName extends string = string, const TBase = never, const TClass extends EntityCtor = EntityCtor<TEntity>>(meta: Omit<Partial<EntityMetadata<TEntity>>, 'properties' | 'extends' | 'className' | 'tableName' | 'hooks'> & {
617
691
  class: TClass;
@@ -647,7 +721,7 @@ type InferJSType<T> = T extends typeof Type<infer TValue, any> ? NonNullable<TVa
647
721
  type InferColumnType<T extends string> = T extends 'int' | 'int4' | 'integer' | 'bigint' | 'int8' | 'int2' | 'tinyint' | 'smallint' | 'mediumint' ? number : T extends 'double' | 'double precision' | 'real' | 'float8' | 'decimal' | 'numeric' | 'float' | 'float4' ? number : T extends 'datetime' | 'time' | 'time with time zone' | 'timestamp' | 'timestamp with time zone' | 'timetz' | 'timestamptz' | 'date' | 'interval' ? Date : T extends 'ObjectId' | 'objectId' | 'character varying' | 'varchar' | 'char' | 'character' | 'uuid' | 'text' | 'tinytext' | 'mediumtext' | 'longtext' | 'enum' ? string : T extends 'boolean' | 'bool' | 'bit' ? boolean : T extends 'blob' | 'tinyblob' | 'mediumblob' | 'longblob' | 'bytea' ? Buffer : T extends 'point' | 'line' | 'lseg' | 'box' | 'circle' | 'path' | 'polygon' | 'geometry' ? number[] : T extends 'tsvector' | 'tsquery' ? string[] : T extends 'json' | 'jsonb' ? any : any;
648
722
  type BaseEntityMethodKeys = 'toObject' | 'toPOJO' | 'serialize' | 'assign' | 'populate' | 'init' | 'toReference';
649
723
  /** Infers the entity type from a `defineEntity()` properties map, resolving builders, base classes, and primary keys. */
650
- export type InferEntityFromProperties<Properties extends Record<string, any>, PK extends (keyof Properties)[] | undefined = undefined, Base = never, Repository = never, ForceObject extends boolean = false> = (IsNever<Base> extends true ? {} : Base extends {
724
+ export type InferEntityFromProperties<Properties extends Record<string, any>, PK extends (keyof Properties)[] | undefined = undefined, Base = never, Repository = never, ForceObject extends boolean = false, BaseDiscriminatorColumn extends string | undefined = undefined, DiscriminatorValue extends string | number | undefined = undefined> = (IsNever<Base> extends true ? {} : Base extends {
651
725
  toObject(...args: any[]): any;
652
726
  } ? Pick<IWrappedEntity<{
653
727
  -readonly [K in keyof Properties]: InferBuilderValue<MaybeReturnType<Properties[K]>>;
@@ -655,17 +729,22 @@ export type InferEntityFromProperties<Properties extends Record<string, any>, PK
655
729
  [PrimaryKeyProp]?: InferCombinedPrimaryKey<Properties, PK, Base>;
656
730
  } & (IsNever<Repository> extends true ? {} : {
657
731
  [EntityRepositoryType]?: Repository extends Constructor<infer R> ? R : Repository;
658
- }) & Omit<Base, typeof PrimaryKeyProp>>, BaseEntityMethodKeys> : {}) & {
732
+ }) & NarrowDiscriminator<Omit<Base, typeof PrimaryKeyProp>, BaseDiscriminatorColumn, DiscriminatorValue>>, BaseEntityMethodKeys> : {}) & {
659
733
  -readonly [K in keyof Properties]: InferBuilderValue<MaybeReturnType<Properties[K]>>;
660
734
  } & {
661
735
  [PrimaryKeyProp]?: InferCombinedPrimaryKey<Properties, PK, Base>;
662
736
  } & (IsNever<Repository> extends true ? {} : {
663
737
  [EntityRepositoryType]?: Repository extends Constructor<infer R> ? R : Repository;
664
- }) & (IsNever<Base> extends true ? {} : Omit<Base, typeof PrimaryKeyProp>) & (ForceObject extends true ? {
738
+ }) & (IsNever<Base> extends true ? {} : NarrowDiscriminator<Omit<Base, typeof PrimaryKeyProp>, BaseDiscriminatorColumn, DiscriminatorValue>) & (ForceObject extends true ? {
665
739
  [Config]?: DefineConfig<{
666
740
  forceObject: true;
667
741
  }>;
668
- } : {});
742
+ } : {}) & {
743
+ [IndexHints]?: [Properties];
744
+ };
745
+ type NarrowDiscriminator<Base, DiscColumn extends string | undefined, DiscValue> = DiscColumn extends string ? DiscColumn extends keyof Base ? DiscValue extends string | number ? Omit<Base, DiscColumn> & {
746
+ [K in DiscColumn]: DiscValue;
747
+ } : Base : Base : Base;
669
748
  type InferCombinedPrimaryKey<Properties extends Record<string, any>, PK, Base> = PK extends undefined ? CombinePrimaryKeys<InferPrimaryKey<Properties>, ExtractBasePrimaryKey<Base>> : PK;
670
749
  type ExtractBasePrimaryKey<Base> = Base extends {
671
750
  [PrimaryKeyProp]?: infer BasePK;
@@ -707,6 +786,9 @@ type MaybeNullable<Value, Options> = Options extends {
707
786
  type MaybeRelationRef<Value, Options> = Options extends {
708
787
  mapToPk: true;
709
788
  } ? Value : Options extends {
789
+ lazyRef: true;
790
+ kind: '1:1' | 'm:1';
791
+ } ? Value extends object ? LazyRef<Value> : never : Options extends {
710
792
  ref: true;
711
793
  kind: '1:1';
712
794
  } ? Value extends object ? Ref<Value> : never : Options extends {
@@ -173,6 +173,16 @@ export class UniversalPropertyOptionsBuilder {
173
173
  ref() {
174
174
  return this.assignOptions({ ref: true });
175
175
  }
176
+ /**
177
+ * Mark a to-one relation (`m:1`/`1:1`) as a {@apilink LazyRef} — the runtime value stays a plain entity
178
+ * (no `Reference` wrapper) but the TypeScript type restricts access to the primary key until `Loaded<>`
179
+ * narrows it. Type-level only; does not set `ref: true`. Not compatible with `.ref()` or `.mapToPk()` —
180
+ * those chains are rejected in both directions at compile time.
181
+ */
182
+ lazyRef() {
183
+ // purely type-level — no runtime metadata change
184
+ return this;
185
+ }
176
186
  /**
177
187
  * Set to true to omit the property when {@link https://mikro-orm.io/docs/serializing Serializing}.
178
188
  */
@@ -191,15 +201,9 @@ export class UniversalPropertyOptionsBuilder {
191
201
  concurrencyCheck(concurrencyCheck = true) {
192
202
  return this.assignOptions({ concurrencyCheck });
193
203
  }
194
- /**
195
- * Explicitly specify index on a property.
196
- */
197
204
  index(index = true) {
198
205
  return this.assignOptions({ index });
199
206
  }
200
- /**
201
- * Set column as unique for {@link https://mikro-orm.io/docs/schema-generator Schema Generator}. (SQL only)
202
- */
203
207
  unique(unique = true) {
204
208
  return this.assignOptions({ unique });
205
209
  }
@@ -312,6 +316,13 @@ export class UniversalPropertyOptionsBuilder {
312
316
  comment(comment) {
313
317
  return this.assignOptions({ comment });
314
318
  }
319
+ /**
320
+ * Specify column-level collation for {@link https://mikro-orm.io/docs/schema-generator Schema Generator}. (SQL only)
321
+ * Emits a `COLLATE` clause on the column definition; the accepted collation names are dialect-specific.
322
+ */
323
+ collation(collation) {
324
+ return this.assignOptions({ collation });
325
+ }
315
326
  /** mysql only */
316
327
  extra(extra) {
317
328
  return this.assignOptions({ extra });
package/entity/utils.js CHANGED
@@ -94,11 +94,10 @@ export function applyPopulateHints(populate, hints) {
94
94
  if (!entry) {
95
95
  continue;
96
96
  }
97
- if (hint.strategy != null) {
98
- entry.strategy = hint.strategy;
99
- }
100
- if (hint.joinType != null) {
101
- entry.joinType = hint.joinType;
97
+ for (const key of Object.keys(hint)) {
98
+ if (hint[key] != null) {
99
+ entry[key] = hint[key];
100
+ }
102
101
  }
103
102
  }
104
103
  }
package/errors.d.ts CHANGED
@@ -74,6 +74,8 @@ export declare class MetadataError<T extends AnyEntity = AnyEntity> extends Vali
74
74
  static viewEntityWithoutExpression(meta: EntityMetadata): MetadataError;
75
75
  static mixedInheritanceStrategies(root: EntityMetadata, child: EntityMetadata): MetadataError;
76
76
  static tptNotSupportedByDriver(meta: EntityMetadata): MetadataError;
77
+ /** Thrown when database triggers are defined on an entity using a driver that does not support them. */
78
+ static triggersNotSupportedByDriver(meta: EntityMetadata): MetadataError;
77
79
  private static fromMessage;
78
80
  }
79
81
  /** Error thrown when an entity lookup fails to find the expected result. */
package/errors.js CHANGED
@@ -243,6 +243,10 @@ export class MetadataError extends ValidationError {
243
243
  static tptNotSupportedByDriver(meta) {
244
244
  return new MetadataError(`Entity ${meta.className} uses TPT (Table-Per-Type) inheritance which is not supported by the current driver. TPT requires SQL JOINs and is only available with SQL drivers.`);
245
245
  }
246
+ /** Thrown when database triggers are defined on an entity using a driver that does not support them. */
247
+ static triggersNotSupportedByDriver(meta) {
248
+ return new MetadataError(`Entity ${meta.className} defines database triggers which are not supported by the current driver. Triggers are only available with SQL drivers.`);
249
+ }
246
250
  static fromMessage(meta, prop, message) {
247
251
  return new MetadataError(`${meta.className}.${prop.name} ${message}`);
248
252
  }
package/index.d.ts CHANGED
@@ -2,8 +2,8 @@
2
2
  * @packageDocumentation
3
3
  * @module core
4
4
  */
5
- export { EntityMetadata, PrimaryKeyProp, EntityRepositoryType, OptionalProps, EagerProps, HiddenProps, Config, EntityName, } from './typings.js';
6
- export type { CompiledFunctions, Constructor, ConnectionType, Dictionary, Primary, IPrimaryKey, ObjectQuery, FilterQuery, IWrappedEntity, InferEntityName, EntityData, Highlighter, MaybePromise, AnyEntity, EntityClass, EntityProperty, PopulateOptions, Populate, Loaded, New, LoadedReference, LoadedCollection, IMigrator, IMigrationGenerator, MigratorEvent, GetRepository, MigrationObject, DeepPartial, PrimaryProperty, Cast, IsUnknown, EntityDictionary, EntityDTO, EntityDTOFlat, EntityDTOProp, SerializeDTO, MigrationDiff, GenerateOptions, FilterObject, IMigrationRunner, IEntityGenerator, ISeedManager, SeederObject, IMigratorStorage, RequiredEntityData, CheckCallback, IndexCallback, FormulaCallback, FormulaTable, SchemaTable, SchemaColumns, SimpleColumnMeta, Rel, Ref, ScalarRef, EntityRef, ISchemaGenerator, MigrationInfo, MigrateOptions, MigrationResult, MigrationRow, EntityKey, EntityValue, EntityDataValue, FilterKey, EntityType, FromEntityType, Selected, IsSubset, EntityProps, ExpandProperty, ExpandScalar, FilterItemValue, ExpandQuery, Scalar, ExpandHint, FilterValue, MergeLoaded, MergeSelected, TypeConfig, AnyString, ClearDatabaseOptions, CreateSchemaOptions, EnsureDatabaseOptions, UpdateSchemaOptions, DropSchemaOptions, RefreshDatabaseOptions, AutoPath, UnboxArray, MetadataProcessor, ImportsResolver, RequiredNullable, DefineConfig, Opt, Hidden, EntitySchemaWithMeta, InferEntity, CheckConstraint, GeneratedColumnCallback, FilterDef, EntityCtor, Subquery, PopulateHintOptions, Prefixes, } from './typings.js';
5
+ export { EntityMetadata, PrimaryKeyProp, EntityRepositoryType, OptionalProps, EagerProps, HiddenProps, Config, EntityName, IndexHints, } from './typings.js';
6
+ export type { CompiledFunctions, Constructor, ConnectionType, Dictionary, Primary, IPrimaryKey, ObjectQuery, FilterQuery, IWrappedEntity, InferEntityName, EntityData, Highlighter, MaybePromise, AnyEntity, EntityClass, EntityProperty, PopulateOptions, Populate, Loaded, New, LoadedReference, LoadedCollection, IMigrator, IMigrationGenerator, MigratorEvent, GetRepository, MigrationObject, DeepPartial, PrimaryProperty, Cast, IsUnknown, EntityDictionary, EntityDTO, EntityDTOFlat, EntityDTOProp, SerializeDTO, MigrationDiff, GenerateOptions, FilterObject, IndexFilterQuery, ExtractIndexHints, IndexName, IndexColumns, WithUsingOptions, IMigrationRunner, IEntityGenerator, ISeedManager, SeederObject, IMigratorStorage, RequiredEntityData, CheckCallback, TriggerCallback, IndexCallback, FormulaCallback, FormulaColumns, FormulaTable, SchemaTable, SchemaColumns, EntityDataPropValue, SimpleColumnMeta, Rel, Ref, LazyRef, ScalarRef, EntityRef, ISchemaGenerator, MigrationInfo, MigrateOptions, MigrationResult, MigrationRow, EntityKey, EntityValue, EntityDataValue, FilterKey, EntityType, FromEntityType, Selected, IsSubset, EntityProps, ExpandProperty, ExpandScalar, FilterItemValue, ExpandQuery, Scalar, ExpandHint, FilterValue, MergeLoaded, MergeSelected, TypeConfig, AnyString, ClearDatabaseOptions, CreateSchemaOptions, EnsureDatabaseOptions, UpdateSchemaOptions, DropSchemaOptions, RefreshDatabaseOptions, AutoPath, UnboxArray, MetadataProcessor, ImportsResolver, RequiredNullable, DefineConfig, Opt, Hidden, EntitySchemaWithMeta, InferEntity, CheckConstraint, TriggerDef, GeneratedColumnCallback, FilterDef, EntityCtor, Subquery, PopulateHintOptions, Prefixes, } from './typings.js';
7
7
  export * from './enums.js';
8
8
  export * from './errors.js';
9
9
  export * from './exceptions.js';
package/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * @packageDocumentation
3
3
  * @module core
4
4
  */
5
- export { EntityMetadata, PrimaryKeyProp, EntityRepositoryType, OptionalProps, EagerProps, HiddenProps, Config, EntityName, } from './typings.js';
5
+ export { EntityMetadata, PrimaryKeyProp, EntityRepositoryType, OptionalProps, EagerProps, HiddenProps, Config, EntityName, IndexHints, } from './typings.js';
6
6
  export * from './enums.js';
7
7
  export * from './errors.js';
8
8
  export * from './exceptions.js';
@@ -85,6 +85,9 @@ export class EntitySchema {
85
85
  if (options.items instanceof Function) {
86
86
  options.items = Utils.extractEnumValues(options.items());
87
87
  }
88
+ else if (options.items && !Array.isArray(options.items) && typeof options.items === 'object') {
89
+ options.items = Utils.extractEnumValues(options.items);
90
+ }
88
91
  // enum arrays are simple numeric/string arrays, the constraint is enforced in the custom type only
89
92
  if (options.array && !options.type) {
90
93
  options.type = new EnumArrayType(`${this._meta.className}.${name}`, options.items);
@@ -54,6 +54,16 @@ export declare class MetadataDiscovery {
54
54
  * Define properties for a polymorphic pivot table.
55
55
  */
56
56
  private definePolymorphicPivotProperties;
57
+ /**
58
+ * Mirror of definePolymorphicPivotProperties for union-target M:N
59
+ * (e.g. Post.attachments -> Image | Video via shared pivot with a target-side discriminator).
60
+ *
61
+ * Pivot shape:
62
+ * (owner_fk..., discriminator_column, target_fk...)
63
+ * - owner side is a normal M:1 to the single owner entity
64
+ * - target side is a discriminator column + per-target-type virtual M:1 relations
65
+ */
66
+ private defineUnionTargetPolymorphicPivotProperties;
57
67
  /**
58
68
  * Create a virtual M:1 relation from pivot to a polymorphic owner entity.
59
69
  * This enables single-query join loading for inverse-side polymorphic M:N.
@@ -66,6 +76,7 @@ export declare class MetadataDiscovery {
66
76
  private initPolyEmbeddables;
67
77
  private initPolymorphicRelation;
68
78
  private initEmbeddables;
79
+ private sameRelationTargetRoot;
69
80
  private initSingleTableInheritance;
70
81
  /**
71
82
  * First pass of TPT initialization: sets up hierarchy relationships
@@ -105,6 +116,7 @@ export declare class MetadataDiscovery {
105
116
  private initAutoincrement;
106
117
  private createSchemaTable;
107
118
  private initCheckConstraints;
119
+ private initTriggers;
108
120
  private initGeneratedColumn;
109
121
  private getDefaultVersionValue;
110
122
  private inferDefaultValue;