@mikro-orm/core 7.1.0-dev.4 → 7.1.0-dev.41

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 (61) hide show
  1. package/EntityManager.d.ts +63 -12
  2. package/EntityManager.js +221 -40
  3. package/README.md +2 -1
  4. package/connections/Connection.d.ts +29 -0
  5. package/drivers/IDatabaseDriver.d.ts +45 -7
  6. package/entity/BaseEntity.d.ts +68 -1
  7. package/entity/BaseEntity.js +18 -0
  8. package/entity/Collection.d.ts +6 -3
  9. package/entity/Collection.js +15 -4
  10. package/entity/EntityAssigner.js +8 -0
  11. package/entity/EntityFactory.js +20 -1
  12. package/entity/EntityLoader.d.ts +8 -1
  13. package/entity/EntityLoader.js +89 -28
  14. package/entity/EntityRepository.d.ts +27 -9
  15. package/entity/EntityRepository.js +12 -0
  16. package/entity/Reference.d.ts +42 -1
  17. package/entity/Reference.js +9 -0
  18. package/entity/defineEntity.d.ts +99 -21
  19. package/entity/defineEntity.js +17 -6
  20. package/entity/utils.js +4 -5
  21. package/enums.d.ts +8 -1
  22. package/errors.d.ts +2 -0
  23. package/errors.js +4 -0
  24. package/index.d.ts +2 -2
  25. package/index.js +1 -1
  26. package/metadata/EntitySchema.js +3 -0
  27. package/metadata/MetadataDiscovery.d.ts +12 -0
  28. package/metadata/MetadataDiscovery.js +166 -20
  29. package/metadata/MetadataValidator.d.ts +24 -0
  30. package/metadata/MetadataValidator.js +202 -1
  31. package/metadata/types.d.ts +71 -4
  32. package/naming-strategy/AbstractNamingStrategy.d.ts +1 -1
  33. package/naming-strategy/NamingStrategy.d.ts +1 -1
  34. package/package.json +1 -1
  35. package/platforms/Platform.d.ts +18 -3
  36. package/platforms/Platform.js +58 -6
  37. package/serialization/EntitySerializer.js +2 -1
  38. package/typings.d.ts +202 -22
  39. package/typings.js +51 -14
  40. package/unit-of-work/UnitOfWork.js +15 -4
  41. package/utils/AbstractMigrator.d.ts +20 -5
  42. package/utils/AbstractMigrator.js +263 -28
  43. package/utils/AbstractSchemaGenerator.d.ts +1 -1
  44. package/utils/AbstractSchemaGenerator.js +4 -1
  45. package/utils/Configuration.d.ts +25 -0
  46. package/utils/Configuration.js +1 -0
  47. package/utils/DataloaderUtils.d.ts +10 -1
  48. package/utils/DataloaderUtils.js +78 -0
  49. package/utils/EntityComparator.js +1 -1
  50. package/utils/QueryHelper.d.ts +16 -0
  51. package/utils/QueryHelper.js +15 -0
  52. package/utils/TransactionManager.js +2 -0
  53. package/utils/Utils.js +1 -1
  54. package/utils/fs-utils.d.ts +2 -0
  55. package/utils/fs-utils.js +7 -1
  56. package/utils/index.d.ts +1 -0
  57. package/utils/index.js +1 -0
  58. package/utils/partition-utils.d.ts +17 -0
  59. package/utils/partition-utils.js +79 -0
  60. package/utils/upsert-utils.d.ts +2 -0
  61. package/utils/upsert-utils.js +26 -1
@@ -6,11 +6,11 @@ import { type EntityRepository } from './entity/EntityRepository.js';
6
6
  import { EntityLoader, type EntityLoaderOptions } from './entity/EntityLoader.js';
7
7
  import { Reference } from './entity/Reference.js';
8
8
  import { UnitOfWork } from './unit-of-work/UnitOfWork.js';
9
- import type { CountOptions, DeleteOptions, FilterOptions, FindAllOptions, FindByCursorOptions, FindOneOptions, FindOneOrFailOptions, FindOptions, GetReferenceOptions, IDatabaseDriver, LockOptions, NativeInsertUpdateOptions, StreamOptions, UpdateOptions, UpsertManyOptions, UpsertOptions } from './drivers/IDatabaseDriver.js';
10
- import type { AnyString, ArrayElement, AutoPath, ConnectionType, Dictionary, EntityClass, EntityData, EntityDictionary, EntityDTO, EntityMetadata, EntityName, FilterDef, FilterQuery, FromEntityType, GetRepository, IHydrator, IsSubset, Loaded, MergeLoaded, MergeSelected, ObjectQuery, PopulateOptions, Primary, Ref, RequiredEntityData, UnboxArray } from './typings.js';
9
+ import type { CountByOptions, CountOptions, DeleteOptions, FilterOptions, FindAllOptions, FindByCursorOptions, FindOneOptions, FindOneOrFailOptions, FindOptions, GetReferenceOptions, IDatabaseDriver, LockOptions, NativeInsertUpdateOptions, StreamOptions, UpdateOptions, UpsertManyOptions, UpsertOptions } from './drivers/IDatabaseDriver.js';
10
+ import type { AnyString, ArrayElement, AutoPath, ConnectionType, Dictionary, EntityClass, EntityData, EntityDictionary, EntityDTO, EntityKey, EntityMetadata, EntityName, FilterDef, FilterQuery, FromEntityType, GetRepository, IHydrator, IsSubset, Loaded, MergeLoaded, MergeSelected, ObjectQuery, PopulateOptions, Primary, Ref, RequiredEntityData, UnboxArray, IndexFilterQuery, WithUsingOptions } from './typings.js';
11
11
  import { FlushMode, LockMode, PopulatePath, type TransactionOptions } from './enums.js';
12
12
  import type { MetadataStorage } from './metadata/MetadataStorage.js';
13
- import type { Transaction } from './connections/Connection.js';
13
+ import type { AbortQueryOptions, InflightQueryAbortStrategy, Transaction } from './connections/Connection.js';
14
14
  import { EventManager } from './events/EventManager.js';
15
15
  import type { EntityComparator } from './utils/EntityComparator.js';
16
16
  /**
@@ -33,6 +33,10 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
33
33
  /** The context name of this EntityManager, derived from the ORM configuration. */
34
34
  readonly name: string;
35
35
  protected loggerContext?: Dictionary;
36
+ /** @internal */
37
+ protected signal?: AbortSignal;
38
+ /** @internal */
39
+ protected inflightQueryAbortStrategy?: InflightQueryAbortStrategy;
36
40
  /**
37
41
  * @internal
38
42
  */
@@ -61,7 +65,9 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
61
65
  /**
62
66
  * Finds all entities matching your `where` query. You can pass additional options via the `options` parameter.
63
67
  */
64
- find<Entity extends object, Hint extends string = never, Fields extends string = never, Excludes extends string = never>(entityName: EntityName<Entity>, where: FilterQuery<NoInfer<Entity>>, options?: FindOptions<Entity, Hint, Fields, Excludes>): Promise<Loaded<Entity, Hint, Fields, Excludes>[]>;
68
+ find<Entity extends object, Hint extends string = never, Fields extends string = never, Excludes extends string = never, Using extends string = never>(entityName: EntityName<Entity>, where: [Using] extends [never] ? FilterQuery<NoInfer<Entity>> : IndexFilterQuery<NoInfer<Entity>, Using>, options?: FindOptions<Entity, Hint, Fields, Excludes> & {
69
+ using?: Using | Using[];
70
+ }): Promise<Loaded<Entity, Hint, Fields, Excludes>[]>;
65
71
  /**
66
72
  * Finds all entities and returns an async iterable (async generator) that yields results one by one.
67
73
  * The results are merged and mapped to entity instances, without adding them to the identity map.
@@ -79,11 +85,11 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
79
85
  * }
80
86
  * ```
81
87
  */
82
- stream<Entity extends object, Hint extends string = never, Fields extends string = never, Excludes extends string = never>(entityName: EntityName<Entity>, options?: StreamOptions<NoInfer<Entity>, Hint, Fields, Excludes>): AsyncIterableIterator<Loaded<Entity, Hint, Fields, Excludes>>;
88
+ stream<Entity extends object, Hint extends string = never, Fields extends string = never, Excludes extends string = never, Using extends string = never>(entityName: EntityName<Entity>, options?: WithUsingOptions<StreamOptions<NoInfer<Entity>, Hint, Fields, Excludes>, NoInfer<Entity>, Using>): AsyncIterableIterator<Loaded<Entity, Hint, Fields, Excludes>>;
83
89
  /**
84
90
  * Finds all entities of given type, optionally matching the `where` condition provided in the `options` parameter.
85
91
  */
86
- findAll<Entity extends object, Hint extends string = never, Fields extends string = never, Excludes extends string = never>(entityName: EntityName<Entity>, options?: FindAllOptions<NoInfer<Entity>, Hint, Fields, Excludes>): Promise<Loaded<Entity, Hint, Fields, Excludes>[]>;
92
+ findAll<Entity extends object, Hint extends string = never, Fields extends string = never, Excludes extends string = never, Using extends string = never>(entityName: EntityName<Entity>, options?: WithUsingOptions<FindAllOptions<NoInfer<Entity>, Hint, Fields, Excludes>, NoInfer<Entity>, Using>): Promise<Loaded<Entity, Hint, Fields, Excludes>[]>;
87
93
  private getPopulateWhere;
88
94
  /**
89
95
  * Registers global filter to this entity manager. Global filters are enabled by default (unless disabled via last parameter).
@@ -130,7 +136,9 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
130
136
  * Calls `em.find()` and `em.count()` with the same arguments (where applicable) and returns the results as tuple
131
137
  * where the first element is the array of entities, and the second is the count.
132
138
  */
133
- findAndCount<Entity extends object, Hint extends string = never, Fields extends string = never, Excludes extends string = never>(entityName: EntityName<Entity>, where: FilterQuery<NoInfer<Entity>>, options?: FindOptions<Entity, Hint, Fields, Excludes>): Promise<[Loaded<Entity, Hint, Fields, Excludes>[], number]>;
139
+ findAndCount<Entity extends object, Hint extends string = never, Fields extends string = never, Excludes extends string = never, Using extends string = never>(entityName: EntityName<Entity>, where: [Using] extends [never] ? FilterQuery<NoInfer<Entity>> : IndexFilterQuery<NoInfer<Entity>, Using>, options?: FindOptions<Entity, Hint, Fields, Excludes> & {
140
+ using?: Using | Using[];
141
+ }): Promise<[Loaded<Entity, Hint, Fields, Excludes>[], number]>;
134
142
  /**
135
143
  * Calls `em.find()` and `em.count()` with the same arguments (where applicable) and returns the results as {@apilink Cursor} object.
136
144
  * Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option
@@ -187,7 +195,7 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
187
195
  * }
188
196
  * ```
189
197
  */
190
- findByCursor<Entity extends object, Hint extends string = never, Fields extends string = never, Excludes extends string = never, IncludeCount extends boolean = true>(entityName: EntityName<Entity>, options: FindByCursorOptions<Entity, Hint, Fields, Excludes, IncludeCount>): Promise<Cursor<Entity, Hint, Fields, Excludes, IncludeCount>>;
198
+ findByCursor<Entity extends object, Hint extends string = never, Fields extends string = never, Excludes extends string = never, IncludeCount extends boolean = true, Using extends string = never>(entityName: EntityName<Entity>, options: WithUsingOptions<FindByCursorOptions<Entity, Hint, Fields, Excludes, IncludeCount>, Entity, Using>): Promise<Cursor<Entity, Hint, Fields, Excludes, IncludeCount>>;
191
199
  /**
192
200
  * Refreshes the persistent state of an entity from the database, overriding any local changes that have not yet been
193
201
  * persisted. Returns the same entity instance (same object reference), but re-hydrated. If the entity is no longer
@@ -203,14 +211,18 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
203
211
  /**
204
212
  * Finds first entity matching your `where` query.
205
213
  */
206
- findOne<Entity extends object, Hint extends string = never, Fields extends string = never, Excludes extends string = never>(entityName: EntityName<Entity>, where: FilterQuery<NoInfer<Entity>>, options?: FindOneOptions<Entity, Hint, Fields, Excludes>): Promise<Loaded<Entity, Hint, Fields, Excludes> | null>;
214
+ findOne<Entity extends object, Hint extends string = never, Fields extends string = never, Excludes extends string = never, Using extends string = never>(entityName: EntityName<Entity>, where: [Using] extends [never] ? FilterQuery<NoInfer<Entity>> : IndexFilterQuery<NoInfer<Entity>, Using>, options?: FindOneOptions<Entity, Hint, Fields, Excludes> & {
215
+ using?: Using | Using[];
216
+ }): Promise<Loaded<Entity, Hint, Fields, Excludes> | null>;
207
217
  /**
208
218
  * Finds first entity matching your `where` query. If nothing found, it will throw an error.
209
219
  * If the `strict` option is specified and nothing is found or more than one matching entity is found, it will throw an error.
210
220
  * You can override the factory for creating this method via `options.failHandler` locally
211
221
  * or via `Configuration.findOneOrFailHandler` (`findExactlyOneOrFailHandler` when specifying `strict`) globally.
212
222
  */
213
- findOneOrFail<Entity extends object, Hint extends string = never, Fields extends string = never, Excludes extends string = never>(entityName: EntityName<Entity>, where: FilterQuery<NoInfer<Entity>>, options?: FindOneOrFailOptions<Entity, Hint, Fields, Excludes>): Promise<Loaded<Entity, Hint, Fields, Excludes>>;
223
+ findOneOrFail<Entity extends object, Hint extends string = never, Fields extends string = never, Excludes extends string = never, Using extends string = never>(entityName: EntityName<Entity>, where: [Using] extends [never] ? FilterQuery<NoInfer<Entity>> : IndexFilterQuery<NoInfer<Entity>, Using>, options?: FindOneOrFailOptions<Entity, Hint, Fields, Excludes> & {
224
+ using?: Using | Using[];
225
+ }): Promise<Loaded<Entity, Hint, Fields, Excludes>>;
214
226
  /**
215
227
  * Creates or updates the entity, based on whether it is already present in the database.
216
228
  * This method performs an `insert on conflict merge` query ensuring the database is in sync, returning a managed
@@ -433,6 +445,27 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
433
445
  * Returns total number of entities matching your `where` query.
434
446
  */
435
447
  count<Entity extends object, Hint extends string = never>(entityName: EntityName<Entity>, where?: FilterQuery<NoInfer<Entity>>, options?: CountOptions<Entity, Hint>): Promise<number>;
448
+ /**
449
+ * Counts entities grouped by one or more properties. Returns a dictionary keyed by the grouped
450
+ * field value(s), with counts as values. For composite `groupBy`, keys are joined with `~~~`.
451
+ *
452
+ * SQL drivers issue a single `GROUP BY` query; MongoDB uses an aggregation pipeline.
453
+ *
454
+ * @example
455
+ * ```ts
456
+ * // Count books per author
457
+ * const counts = await em.countBy(Book, 'author');
458
+ * // { '1': 2, '2': 1, '3': 3 }
459
+ *
460
+ * // Count with a filter
461
+ * const counts = await em.countBy(Book, 'author', { where: { active: true } });
462
+ *
463
+ * // Composite groupBy — keys joined with ~~~
464
+ * const counts = await em.countBy(Order, ['status', 'country']);
465
+ * // { 'pending~~~US': 5, 'shipped~~~DE': 3 }
466
+ * ```
467
+ */
468
+ countBy<Entity extends object>(entityName: EntityName<Entity>, groupBy: EntityKey<Entity> | readonly EntityKey<Entity>[], options?: CountByOptions<Entity>): Promise<Dictionary<number>>;
436
469
  /**
437
470
  * Tells the EntityManager to make an instance managed and persistent.
438
471
  * The entity will be entered into the database at or before transaction commit or as a result of the flush operation.
@@ -503,6 +536,13 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
503
536
  * Gets the transaction context (driver dependent object used to make sure queries are executed on same connection).
504
537
  */
505
538
  getTransactionContext<T extends Transaction = Transaction>(): T | undefined;
539
+ /**
540
+ * Returns the cancellation defaults configured on this EntityManager (via `em.fork({ signal })`
541
+ * or inherited from a transactional fork). Returns `undefined` when no signal is set.
542
+ *
543
+ * @internal — exposed for subclass drivers and `UnitOfWork`; not part of the public API.
544
+ */
545
+ protected getAbortOptions(): AbortQueryOptions | undefined;
506
546
  /**
507
547
  * Sets the transaction context.
508
548
  */
@@ -524,16 +564,20 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
524
564
  */
525
565
  getComparator(): EntityComparator;
526
566
  private checkLockRequirements;
567
+ private validateIndexUsage;
568
+ private validateWhereKeysForIndex;
527
569
  private lockAndPopulate;
528
570
  private buildFields;
529
571
  /** @internal */
530
572
  preparePopulate<Entity extends object>(entityName: EntityName<Entity>, options: Pick<FindOptions<Entity, any, any, any>, 'populate' | 'strategy' | 'fields' | 'flags' | 'filters' | 'exclude' | 'populateHints'>, validate?: boolean): Promise<PopulateOptions<Entity>[]>;
573
+ /** Force SELECT_IN strategy on populate entries with `limit`, since JOINED cannot do per-parent limiting. */
574
+ private forceSelectInForLimitedPopulate;
531
575
  /**
532
576
  * when the entity is found in identity map, we check if it was partially loaded or we are trying to populate
533
577
  * some additional lazy properties, if so, we reload and merge the data from database
534
578
  */
535
579
  protected shouldRefresh<T extends object, P extends string = never, F extends string = never, E extends string = never>(meta: EntityMetadata<T>, entity: T, options: FindOneOptions<T, P, F, E>): boolean;
536
- protected prepareOptions(options: FindOptions<any, any, any, any> | FindOneOptions<any, any, any, any> | CountOptions<any, any>): void;
580
+ protected prepareOptions(options: (FindOptions<any, any, any, any> | FindOneOptions<any, any, any, any> | CountOptions<any, any> | CountByOptions<any>) & AbortQueryOptions): void;
537
581
  /**
538
582
  * @internal
539
583
  */
@@ -575,7 +619,7 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
575
619
  */
576
620
  set schema(schema: string | null | undefined);
577
621
  /** @internal */
578
- getDataLoader(type: 'ref' | '1:m' | 'm:n'): Promise<any>;
622
+ getDataLoader(type: 'ref' | '1:m' | 'm:n' | 'count'): Promise<any>;
579
623
  /**
580
624
  * Returns the ID of this EntityManager. Respects the context, so global EM will give you the contextual ID
581
625
  * if executed inside request context handler.
@@ -628,4 +672,11 @@ export interface ForkOptions {
628
672
  schema?: string;
629
673
  /** default logger context, can be overridden via {@apilink FindOptions} */
630
674
  loggerContext?: Dictionary;
675
+ /**
676
+ * Default `AbortSignal` applied to every operation on this fork (queries and UoW flushes).
677
+ * Per-call options.signal still takes precedence.
678
+ */
679
+ signal?: AbortSignal;
680
+ /** Default cancellation strategy paired with {@link signal}. */
681
+ inflightQueryAbortStrategy?: InflightQueryAbortStrategy;
631
682
  }