import { inspect } from 'node:util'; import DataLoader from 'dataloader'; import { type Configuration, Cursor } from './utils'; import { type AssignOptions, EntityFactory, EntityLoader, type EntityLoaderOptions, type EntityRepository, EntityValidator, Reference } from './entity'; import { UnitOfWork } from './unit-of-work'; import type { CountOptions, DeleteOptions, FilterOptions, FindAllOptions, FindByCursorOptions, FindOneOptions, FindOneOrFailOptions, FindOptions, GetReferenceOptions, IDatabaseDriver, LockOptions, NativeInsertUpdateOptions, UpdateOptions, UpsertManyOptions, UpsertOptions } from './drivers'; import type { AnyEntity, AnyString, ArrayElement, AutoPath, ConnectionType, Dictionary, EntityData, EntityDictionary, EntityDTO, EntityMetadata, EntityName, FilterDef, FilterQuery, FromEntityType, GetRepository, IHydrator, IsSubset, Loaded, MaybePromise, MergeLoaded, MergeSelected, NoInfer, ObjectQuery, PopulateOptions, Primary, Ref, RequiredEntityData, UnboxArray } from './typings'; import { FlushMode, LockMode, PopulatePath, type TransactionOptions } from './enums'; import type { MetadataStorage } from './metadata'; import type { Transaction } from './connections'; import { EventManager } from './events'; import type { EntityComparator } from './utils/EntityComparator'; /** * The EntityManager is the central access point to ORM functionality. It is a facade to all different ORM subsystems * such as UnitOfWork, Query Language, and Repository API. * @template {IDatabaseDriver} Driver current driver type */ export declare class EntityManager { readonly config: Configuration; protected readonly driver: Driver; protected readonly metadata: MetadataStorage; protected readonly useContext: boolean; protected readonly eventManager: EventManager; private static counter; readonly _id: number; readonly global = false; readonly name: string; protected readonly refLoader: DataLoader<[Reference, (Omit, "dataloader"> | undefined)?], any, [Reference, (Omit, "dataloader"> | undefined)?]>; protected readonly colLoader: DataLoader<[import("./entity").Collection, (Omit, "dataloader"> | undefined)?], any, [import("./entity").Collection, (Omit, "dataloader"> | undefined)?]>; protected readonly colLoaderMtoN: DataLoader<[import("./entity").Collection, (Omit, "dataloader"> | undefined)?], any, [import("./entity").Collection, (Omit, "dataloader"> | undefined)?]>; private readonly validator; private readonly repositoryMap; private readonly entityLoader; protected readonly comparator: EntityComparator; private readonly entityFactory; private readonly unitOfWork; private readonly resultCache; private filters; private filterParams; protected loggerContext?: Dictionary; private transactionContext?; private disableTransactions; private flushMode?; private _schema?; /** * @internal */ constructor(config: Configuration, driver: Driver, metadata: MetadataStorage, useContext?: boolean, eventManager?: EventManager); /** * Gets the Driver instance used by this EntityManager. * Driver is singleton, for one MikroORM instance, only one driver is created. */ getDriver(): Driver; /** * Gets the Connection instance, by default returns write connection */ getConnection(type?: ConnectionType): ReturnType; /** * Gets the platform instance. Just like the driver, platform is singleton, one for a MikroORM instance. */ getPlatform(): ReturnType; /** * Gets repository for given entity. You can pass either string name or entity class reference. */ getRepository = EntityRepository>(entityName: EntityName): GetRepository; /** * Shortcut for `em.getRepository()`. */ repo = EntityRepository>(entityName: EntityName): GetRepository; /** * Gets EntityValidator instance */ getValidator(): EntityValidator; /** * Finds all entities matching your `where` query. You can pass additional options via the `options` parameter. */ find(entityName: EntityName, where: FilterQuery>, options?: FindOptions): Promise[]>; /** * Finds all entities of given type, optionally matching the `where` condition provided in the `options` parameter. */ findAll(entityName: EntityName, options?: FindAllOptions, Hint, Fields, Excludes>): Promise[]>; private getPopulateWhere; /** * Registers global filter to this entity manager. Global filters are enabled by default (unless disabled via last parameter). */ addFilter(name: string, cond: FilterQuery | ((args: Dictionary) => MaybePromise>), entityName?: EntityName | [EntityName], options?: boolean | Partial): void; /** * Registers global filter to this entity manager. Global filters are enabled by default (unless disabled via last parameter). */ addFilter(name: string, cond: FilterQuery | ((args: Dictionary) => MaybePromise>), entityName?: [EntityName, EntityName], options?: boolean | Partial): void; /** * Registers global filter to this entity manager. Global filters are enabled by default (unless disabled via last parameter). */ addFilter(name: string, cond: FilterQuery | ((args: Dictionary) => MaybePromise>), entityName?: [EntityName, EntityName, EntityName], options?: boolean | Partial): void; /** * Registers global filter to this entity manager. Global filters are enabled by default (unless disabled via last parameter). */ addFilter(name: string, cond: Dictionary | ((args: Dictionary) => MaybePromise>), entityName?: EntityName | EntityName[], options?: boolean | Partial): void; /** * Sets filter parameter values globally inside context defined by this entity manager. * If you want to set shared value for all contexts, be sure to use the root entity manager. */ setFilterParams(name: string, args: Dictionary): void; /** * Returns filter parameters for given filter set in this context. */ getFilterParams(name: string): T; /** * Sets logger context for this entity manager. */ setLoggerContext(context: Dictionary): void; /** * Gets logger context for this entity manager. */ getLoggerContext(options?: { disableContextResolution?: boolean; }): T; setFlushMode(flushMode?: FlushMode): void; protected processWhere(entityName: string, where: FilterQuery, options: FindOptions | FindOneOptions, type: 'read' | 'update' | 'delete'): Promise>; protected applyDiscriminatorCondition(entityName: string, where: FilterQuery): FilterQuery; protected createPopulateWhere(cond: ObjectQuery, options: FindOptions | FindOneOptions | CountOptions): ObjectQuery; protected getJoinedFilters(meta: EntityMetadata, options: FindOptions | FindOneOptions): Promise | undefined>; /** * When filters are active on M:1 or 1:1 relations, we need to ref join them eagerly as they might affect the FK value. */ protected autoJoinRefsForFilters(meta: EntityMetadata, options: FindOptions | FindOneOptions, parent?: { className: string; propName: string; }): Promise; /** * @internal */ applyFilters(entityName: string, where: FilterQuery | undefined, options: FilterOptions | undefined, type: 'read' | 'update' | 'delete', findOptions?: FindOptions | FindOneOptions): Promise | undefined>; /** * Calls `em.find()` and `em.count()` with the same arguments (where applicable) and returns the results as tuple * where the first element is the array of entities, and the second is the count. */ findAndCount(entityName: EntityName, where: FilterQuery>, options?: FindOptions): Promise<[Loaded[], number]>; /** * Calls `em.find()` and `em.count()` with the same arguments (where applicable) and returns the results as {@apilink Cursor} object. * Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option * is required. * * Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. * * - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time * - `before` and `after` specify the previous cursor value, it can be one of the: * - `Cursor` instance * - opaque string provided by `startCursor/endCursor` properties * - POJO/entity instance * * ```ts * const currentCursor = await em.findByCursor(User, {}, { * first: 10, * after: previousCursor, // cursor instance * orderBy: { id: 'desc' }, * }); * * // to fetch next page * const nextCursor = await em.findByCursor(User, {}, { * first: 10, * after: currentCursor.endCursor, // opaque string * orderBy: { id: 'desc' }, * }); * * // to fetch next page * const nextCursor2 = await em.findByCursor(User, {}, { * first: 10, * after: { id: lastSeenId }, // entity-like POJO * orderBy: { id: 'desc' }, * }); * ``` * * The options also support an `includeCount` (true by default) option. If set to false, the `totalCount` is not * returned as part of the cursor. This is useful for performance reason, when you don't care about the total number * of pages. * * The `Cursor` object provides the following interface: * * ```ts * Cursor { * items: [ * User { ... }, * User { ... }, * User { ... }, * ], * totalCount: 50, // not included if `includeCount: false` * startCursor: 'WzRd', * endCursor: 'WzZd', * hasPrevPage: true, * hasNextPage: true, * } * ``` */ findByCursor(entityName: EntityName, where: FilterQuery>, options: FindByCursorOptions): Promise>; /** * Refreshes the persistent state of an entity from the database, overriding any local changes that have not yet been * persisted. Returns the same entity instance (same object reference), but re-hydrated. If the entity is no longer * in database, the method throws an error just like `em.findOneOrFail()` (and respects the same config options). */ refreshOrFail = FromEntityType, Hint extends string = never, Fields extends string = '*', Excludes extends string = never>(entity: Entity, options?: FindOneOrFailOptions): Promise>; /** * Refreshes the persistent state of an entity from the database, overriding any local changes that have not yet been * persisted. Returns the same entity instance (same object reference), but re-hydrated. If the entity is no longer * in database, the method returns `null`. */ refresh = FromEntityType, Hint extends string = never, Fields extends string = '*', Excludes extends string = never>(entity: Entity, options?: FindOneOptions): Promise | null>; /** * Finds first entity matching your `where` query. */ findOne(entityName: EntityName, where: FilterQuery>, options?: FindOneOptions): Promise | null>; /** * Finds first entity matching your `where` query. If nothing found, it will throw an error. * If the `strict` option is specified and nothing is found or more than one matching entity is found, it will throw an error. * You can override the factory for creating this method via `options.failHandler` locally * or via `Configuration.findOneOrFailHandler` (`findExactlyOneOrFailHandler` when specifying `strict`) globally. */ findOneOrFail(entityName: EntityName, where: FilterQuery>, options?: FindOneOrFailOptions): Promise>; /** * Creates or updates the entity, based on whether it is already present in the database. * This method performs an `insert on conflict merge` query ensuring the database is in sync, returning a managed * entity instance. The method accepts either `entityName` together with the entity `data`, or just entity instance. * * ```ts * // insert into "author" ("age", "email") values (33, 'foo@bar.com') on conflict ("email") do update set "age" = 41 * const author = await em.upsert(Author, { email: 'foo@bar.com', age: 33 }); * ``` * * The entity data needs to contain either the primary key, or any other unique property. Let's consider the following example, where `Author.email` is a unique property: * * ```ts * // insert into "author" ("age", "email") values (33, 'foo@bar.com') on conflict ("email") do update set "age" = 41 * // select "id" from "author" where "email" = 'foo@bar.com' * const author = await em.upsert(Author, { email: 'foo@bar.com', age: 33 }); * ``` * * Depending on the driver support, this will either use a returning query, or a separate select query, to fetch the primary key if it's missing from the `data`. * * If the entity is already present in current context, there won't be any queries - instead, the entity data will be assigned and an explicit `flush` will be required for those changes to be persisted. */ upsert(entityNameOrEntity: EntityName | Entity, data?: EntityData | NoInfer, options?: UpsertOptions): Promise; /** * Creates or updates the entity, based on whether it is already present in the database. * This method performs an `insert on conflict merge` query ensuring the database is in sync, returning a managed * entity instance. The method accepts either `entityName` together with the entity `data`, or just entity instance. * * ```ts * // insert into "author" ("age", "email") values (33, 'foo@bar.com') on conflict ("email") do update set "age" = 41 * const authors = await em.upsertMany(Author, [{ email: 'foo@bar.com', age: 33 }, ...]); * ``` * * The entity data needs to contain either the primary key, or any other unique property. Let's consider the following example, where `Author.email` is a unique property: * * ```ts * // insert into "author" ("age", "email") values (33, 'foo@bar.com'), (666, 'lol@lol.lol') on conflict ("email") do update set "age" = excluded."age" * // select "id" from "author" where "email" = 'foo@bar.com' * const author = await em.upsertMany(Author, [ * { email: 'foo@bar.com', age: 33 }, * { email: 'lol@lol.lol', age: 666 }, * ]); * ``` * * Depending on the driver support, this will either use a returning query, or a separate select query, to fetch the primary key if it's missing from the `data`. * * If the entity is already present in current context, there won't be any queries - instead, the entity data will be assigned and an explicit `flush` will be required for those changes to be persisted. */ upsertMany(entityNameOrEntity: EntityName | Entity[], data?: (EntityData | NoInfer)[], options?: UpsertManyOptions): Promise; /** * Runs your callback wrapped inside a database transaction. * * If a transaction is already active, a new savepoint (nested transaction) will be created by default. This behavior * can be controlled via the `propagation` option. Use the provided EntityManager instance for all operations that * should be part of the transaction. You can safely use a global EntityManager instance from a DI container, as this * method automatically creates an async context for the transaction. * * **Concurrency note:** When running multiple transactions concurrently (e.g. in parallel requests or jobs), use the * `clear: true` option. This ensures the callback runs in a clear fork of the EntityManager, providing full isolation * between concurrent transactional handlers. Using `clear: true` is an alternative to forking explicitly and calling * the method on the new fork – it already provides the necessary isolation for safe concurrent usage. * * **Propagation note:** Changes made within a transaction (whether top-level or nested) are always propagated to the * parent context, unless the parent context is a global one. If you want to avoid that, fork the EntityManager first * and then call this method on the fork. * * **Example:** * ```ts * await em.transactional(async (em) => { * const author = new Author('Jon'); * em.persist(author); * // flush is called automatically at the end of the callback * }); * ``` */ transactional(cb: (em: this) => T | Promise, options?: TransactionOptions): Promise; /** * Starts new transaction bound to this EntityManager. Use `ctx` parameter to provide the parent when nesting transactions. */ begin(options?: Omit): Promise; /** * Commits the transaction bound to this EntityManager. Flushes before doing the actual commit query. */ commit(): Promise; /** * Rollbacks the transaction bound to this EntityManager. */ rollback(): Promise; /** * Runs your callback wrapped inside a database transaction. */ lock(entity: T, lockMode: LockMode, options?: LockOptions | number | Date): Promise; /** * Fires native insert query. Calling this has no side effects on the context (identity map). */ insert(entityNameOrEntity: EntityName | Entity, data?: RequiredEntityData | Entity, options?: NativeInsertUpdateOptions): Promise>; /** * Fires native multi-insert query. Calling this has no side effects on the context (identity map). */ insertMany(entityNameOrEntities: EntityName | Entity[], data?: RequiredEntityData[] | Entity[], options?: NativeInsertUpdateOptions): Promise[]>; /** * Fires native update query. Calling this has no side effects on the context (identity map). */ nativeUpdate(entityName: EntityName, where: FilterQuery>, data: EntityData, options?: UpdateOptions): Promise; /** * Fires native delete query. Calling this has no side effects on the context (identity map). */ nativeDelete(entityName: EntityName, where: FilterQuery>, options?: DeleteOptions): Promise; /** * Maps raw database result to an entity and merges it to this EntityManager. */ map(entityName: EntityName, result: EntityDictionary, options?: { schema?: string; }): Entity; /** * Merges given entity to this EntityManager so it becomes managed. You can force refreshing of existing entities * via second parameter. By default, it will return already loaded entities without modifying them. */ merge(entity: Entity, options?: MergeOptions): Entity; /** * Merges given entity to this EntityManager so it becomes managed. You can force refreshing of existing entities * via second parameter. By default, it will return already loaded entities without modifying them. */ merge(entityName: EntityName, data: EntityData | EntityDTO, options?: MergeOptions): Entity; /** * Creates new instance of given entity and populates it with given data. * The entity constructor will be used unless you provide `{ managed: true }` in the `options` parameter. * The constructor will be given parameters based on the defined constructor of the entity. If the constructor * parameter matches a property name, its value will be extracted from `data`. If no matching property exists, * the whole `data` parameter will be passed. This means we can also define `constructor(data: Partial)` and * `em.create()` will pass the data into it (unless we have a property named `data` too). * * The parameters are strictly checked, you need to provide all required properties. You can use `OptionalProps` * symbol to omit some properties from this check without making them optional. Alternatively, use `partial: true` * in the options to disable the strict checks for required properties. This option has no effect on runtime. * * The newly created entity will be automatically marked for persistence via `em.persist` unless you disable this * behavior, either locally via `persist: false` option, or globally via `persistOnCreate` ORM config option. */ create(entityName: EntityName, data: RequiredEntityData, options?: CreateOptions): Entity; /** * Creates new instance of given entity and populates it with given data. * The entity constructor will be used unless you provide `{ managed: true }` in the `options` parameter. * The constructor will be given parameters based on the defined constructor of the entity. If the constructor * parameter matches a property name, its value will be extracted from `data`. If no matching property exists, * the whole `data` parameter will be passed. This means we can also define `constructor(data: Partial)` and * `em.create()` will pass the data into it (unless we have a property named `data` too). * * The parameters are strictly checked, you need to provide all required properties. You can use `OptionalProps` * symbol to omit some properties from this check without making them optional. Alternatively, use `partial: true` * in the options to disable the strict checks for required properties. This option has no effect on runtime. * * The newly created entity will be automatically marked for persistence via `em.persist` unless you disable this * behavior, either locally via `persist: false` option, or globally via `persistOnCreate` ORM config option. */ create(entityName: EntityName, data: EntityData, options: CreateOptions & { partial: true; }): Entity; /** * Shortcut for `wrap(entity).assign(data, { em })` */ assign = FromEntityType, Convert extends boolean = false, Data extends EntityData | Partial> = EntityData | Partial>>(entity: Entity | Partial, data: Data & IsSubset, Data>, options?: AssignOptions): MergeSelected; /** * Gets a reference to the entity identified by the given type and identifier without actually loading it, if the entity is not yet loaded */ getReference(entityName: EntityName, id: Primary, options: Omit & { wrapped: true; }): Ref; /** * Gets a reference to the entity identified by the given type and identifier without actually loading it, if the entity is not yet loaded */ getReference(entityName: EntityName, id: Primary | Primary[]): Entity; /** * Gets a reference to the entity identified by the given type and identifier without actually loading it, if the entity is not yet loaded */ getReference(entityName: EntityName, id: Primary, options: Omit & { wrapped: false; }): Entity; /** * Gets a reference to the entity identified by the given type and identifier without actually loading it, if the entity is not yet loaded */ getReference(entityName: EntityName, id: Primary, options?: GetReferenceOptions): Entity | Reference; /** * Returns total number of entities matching your `where` query. */ count(entityName: EntityName, where?: FilterQuery>, options?: CountOptions): Promise; /** * Tells the EntityManager to make an instance managed and persistent. * The entity will be entered into the database at or before transaction commit or as a result of the flush operation. */ persist(entity: Entity | Reference | Iterable>): this; /** * Persists your entity immediately, flushing all not yet persisted changes to the database too. * Equivalent to `em.persist(e).flush()`. * @deprecated use `em.persist(e).flush()` instead */ persistAndFlush(entity: AnyEntity | Reference | Iterable>): Promise; /** * Marks entity for removal. * A removed entity will be removed from the database at or before transaction commit or as a result of the flush operation. * * To remove entities by condition, use `em.nativeDelete()`. */ remove(entity: Entity | Reference | Iterable>): this; /** * Removes an entity instance immediately, flushing all not yet persisted changes to the database too. * Equivalent to `em.remove(e).flush()` * @deprecated use `em.remove(e).flush()` instead */ removeAndFlush(entity: AnyEntity | Reference | Iterable>): Promise; /** * Flushes all changes to objects that have been queued up to now to the database. * This effectively synchronizes the in-memory state of managed objects with the database. */ flush(): Promise; /** * @internal */ tryFlush(entityName: EntityName, options: { flushMode?: FlushMode | AnyString; }): Promise; /** * Clears the EntityManager. All entities that are currently managed by this EntityManager become detached. */ clear(): void; /** * Checks whether given property can be populated on the entity. */ canPopulate(entityName: EntityName, property: string): boolean; /** * Loads specified relations in batch. This will execute one query for each relation, that will populate it on all the specified entities. */ populate> = FromEntityType>, Hint extends string = never, Fields extends string = '*', Excludes extends string = never>(entities: Entity, populate: readonly AutoPath[] | false, options?: EntityLoaderOptions): Promise, Naked, Hint, Fields, Excludes>[] : MergeLoaded>; /** * Returns new EntityManager instance with its own identity map */ fork(options?: ForkOptions): this; /** * Gets the UnitOfWork used by the EntityManager to coordinate operations. */ getUnitOfWork(useContext?: boolean): UnitOfWork; /** * Gets the EntityFactory used by the EntityManager. */ getEntityFactory(): EntityFactory; /** * @internal use `em.populate()` as the user facing API, this is exposed only for internal usage */ getEntityLoader(): EntityLoader; /** * Gets the Hydrator used by the EntityManager. */ getHydrator(): IHydrator; /** * Gets the EntityManager based on current transaction/request context. * @internal */ getContext(validate?: boolean): this; getEventManager(): EventManager; /** * Checks whether this EntityManager is currently operating inside a database transaction. */ isInTransaction(): boolean; /** * Gets the transaction context (driver dependent object used to make sure queries are executed on same connection). */ getTransactionContext(): T | undefined; /** * Sets the transaction context. */ setTransactionContext(ctx: Transaction): void; /** * Resets the transaction context. */ resetTransactionContext(): void; /** * Gets the `MetadataStorage`. */ getMetadata(): MetadataStorage; /** * Gets the `EntityMetadata` instance when provided with the `entityName` parameter. */ getMetadata(entityName: EntityName): EntityMetadata; /** * Gets the EntityComparator. */ getComparator(): EntityComparator; private checkLockRequirements; private lockAndPopulate; private buildFields; /** @internal */ preparePopulate(entityName: string, options: Pick, 'populate' | 'strategy' | 'fields' | 'flags' | 'filters' | 'exclude'>, validate?: boolean): Promise[]>; /** * when the entity is found in identity map, we check if it was partially loaded or we are trying to populate * some additional lazy properties, if so, we reload and merge the data from database */ protected shouldRefresh(meta: EntityMetadata, entity: T, options: FindOneOptions): boolean; protected prepareOptions(options: FindOptions | FindOneOptions | CountOptions): void; /** * @internal */ cacheKey(entityName: string, options: FindOptions | FindOneOptions | CountOptions, method: string, where: FilterQuery): unknown[]; /** * @internal */ tryCache(entityName: string, config: boolean | number | [string, number] | undefined, key: unknown, refresh?: boolean, merge?: boolean): Promise<{ data?: R | null; key: string; } | undefined>; /** * @internal */ storeCache(config: boolean | number | [string, number] | undefined, key: { key: string; }, data: unknown | (() => unknown)): Promise; /** * Clears result cache for given cache key. If we want to be able to call this method, * we need to set the cache key explicitly when storing the cache. * * ```ts * // set the cache key to 'book-cache-key', with expiration of 60s * const res = await em.find(Book, { ... }, { cache: ['book-cache-key', 60_000] }); * * // clear the cache key by name * await em.clearCache('book-cache-key'); * ``` */ clearCache(cacheKey: string): Promise; /** * Returns the default schema of this EntityManager. Respects the context, so global EM will give you the contextual schema * if executed inside request context handler. */ get schema(): string | undefined; /** * Sets the default schema of this EntityManager. Respects the context, so global EM will set the contextual schema * if executed inside request context handler. */ set schema(schema: string | null | undefined); /** * Returns the ID of this EntityManager. Respects the context, so global EM will give you the contextual ID * if executed inside request context handler. */ get id(): number; /** @ignore */ [inspect.custom](): string; } export interface CreateOptions { /** creates a managed entity instance instead, bypassing the constructor call */ managed?: boolean; /** create entity in a specific schema - alternatively, use `wrap(entity).setSchema()` */ schema?: string; /** persist the entity automatically - this is the default behavior and is also configurable globally via `persistOnCreate` option */ persist?: boolean; /** this option disables the strict typing which requires all mandatory properties to have value, it has no effect on runtime */ partial?: boolean; /** convert raw database values based on mapped types (by default, already converted values are expected) */ convertCustomTypes?: Convert; /** * Property `onCreate` hooks are normally executed during `flush` operation. * With this option, they will be processed early inside `em.create()` method. */ processOnCreateHooksEarly?: boolean; } export interface MergeOptions { refresh?: boolean; convertCustomTypes?: boolean; schema?: string; disableContextResolution?: boolean; keepIdentity?: boolean; validate?: boolean; cascade?: boolean; /** @default true */ } export interface ForkOptions { /** do we want a clear identity map? defaults to true */ clear?: boolean; /** use request context? should be used only for top level request scope EM, defaults to false */ useContext?: boolean; /** do we want to use fresh EventManager instance? defaults to false (global instance) */ freshEventManager?: boolean; /** do we want to clone current EventManager instance? defaults to false (global instance) */ cloneEventManager?: boolean; /** use this flag to ignore the current async context - this is required if we want to call `em.fork()` inside the `getContext` handler */ disableContextResolution?: boolean; /** set flush mode for this fork, overrides the global option can be overridden locally via FindOptions */ flushMode?: FlushMode; /** disable transactions for this fork */ disableTransactions?: boolean; /** should we keep the transaction context of the parent EM? */ keepTransactionContext?: boolean; /** default schema to use for this fork */ schema?: string; /** default logger context, can be overridden via {@apilink FindOptions} */ loggerContext?: Dictionary; }