import type { PopulatePath } from '../enums.js'; import type { CreateOptions, EntityManager, MergeOptions } from '../EntityManager.js'; import type { AssignOptions } from './EntityAssigner.js'; import type { EntityData, EntityName, Primary, Loaded, FilterQuery, EntityDictionary, AutoPath, RequiredEntityData, Ref, EntityType, EntityDTO, MergeSelected, FromEntityType, IsSubset, MergeLoaded, ArrayElement } from '../typings.js'; import type { CountOptions, DeleteOptions, FindAllOptions, FindByCursorOptions, FindOneOptions, FindOneOrFailOptions, FindOptions, GetReferenceOptions, NativeInsertUpdateOptions, StreamOptions, UpdateOptions, UpsertManyOptions, UpsertOptions } from '../drivers/IDatabaseDriver.js'; import type { EntityLoaderOptions } from './EntityLoader.js'; import type { Cursor } from '../utils/Cursor.js'; /** Repository class providing a type-safe API for querying and persisting a specific entity type. */ export declare class EntityRepository { protected readonly em: EntityManager; protected readonly entityName: EntityName; constructor(em: EntityManager, entityName: EntityName); /** * Finds first entity matching your `where` query. */ findOne(where: FilterQuery, options?: FindOneOptions): Promise | null>; /** * Finds first entity matching your `where` query. If nothing is found, it will throw an error. * You can override the factory for creating this method via `options.failHandler` locally * or via `Configuration.findOneOrFailHandler` globally. */ findOneOrFail(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.getRepository(Author).upsert({ 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.getRepository(Author).upsert({ 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(entityOrData?: EntityData | Entity, 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. * * ```ts * // insert into "author" ("age", "email") values (33, 'foo@bar.com') on conflict ("email") do update set "age" = 41 * const authors = await em.getRepository(Author).upsertMany([{ 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.getRepository(Author).upsertMany([ * { 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(entitiesOrData?: EntityData[] | Entity[], options?: UpsertManyOptions): Promise; /** * Finds all entities matching your `where` query. You can pass additional options via the `options` parameter. */ find(where: FilterQuery, options?: FindOptions): Promise[]>; /** * Calls `em.find()` and `em.count()` with the same arguments (where applicable) and returns the results as tuple * where first element is the array of entities, and the second is the count. */ findAndCount(where: FilterQuery, options?: FindOptions): Promise<[Loaded[], number]>; /** * @inheritDoc EntityManager.findByCursor */ findByCursor(options: FindByCursorOptions): Promise>; /** * Finds all entities of given type. You can pass additional options via the `options` parameter. */ findAll(options?: FindAllOptions): Promise[]>; /** * @inheritDoc EntityManager.stream */ stream(options?: StreamOptions): AsyncIterableIterator>; /** * @inheritDoc EntityManager.insert */ insert(data: Entity | RequiredEntityData, options?: NativeInsertUpdateOptions): Promise>; /** * @inheritDoc EntityManager.insert */ insertMany(data: Entity[] | RequiredEntityData[], options?: NativeInsertUpdateOptions): Promise[]>; /** * Fires native update query. Calling this has no side effects on the context (identity map). */ nativeUpdate(where: FilterQuery, data: EntityData, options?: UpdateOptions): Promise; /** * Fires native delete query. Calling this has no side effects on the context (identity map). */ nativeDelete(where: FilterQuery, options?: DeleteOptions): Promise; /** * Maps raw database result to an entity and merges it to this EntityManager. */ map(result: EntityDictionary, options?: { schema?: string; }): Entity; /** * Gets a reference to the entity identified by the given type and alternate key property without actually loading it. * The key option specifies which property to use for identity map lookup instead of the primary key. */ getReference(id: Entity[K], options: Omit & { key: K; wrapped: true; }): Ref; /** * Gets a reference to the entity identified by the given type and alternate key property without actually loading it. * The key option specifies which property to use for identity map lookup instead of the primary key. */ getReference(id: Entity[K], options: Omit & { key: K; 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(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(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(id: Primary, options: Omit & { wrapped: false; }): Entity; /** * Checks whether given property can be populated on the entity. */ canPopulate(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, Fields extends string = never, Excludes extends string = never>(entities: Ent, populate: AutoPath[] | false, options?: EntityLoaderOptions): Promise, Naked, Hint, Fields, Excludes>[] : MergeLoaded>; /** * 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 = RequiredEntityData>(data: Data & IsSubset, Data>, 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 pass. 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 = EntityData>(data: Data & IsSubset, Data>, options: CreateOptions & { partial: true; }): Entity; /** * Shortcut for `wrap(entity).assign(data, { em })` */ assign, Naked extends FromEntityType = FromEntityType, Convert extends boolean = false, Data extends EntityData | Partial> = EntityData | Partial>>(entity: Ent | Partial, data: Data & IsSubset, Data>, options?: AssignOptions): MergeSelected; /** * 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(data: Entity | EntityData, options?: MergeOptions): Entity; /** * Returns total number of entities matching your `where` query. */ count(where?: FilterQuery, options?: CountOptions): Promise; /** Returns the entity class name associated with this repository. */ getEntityName(): string; /** * Returns the underlying EntityManager instance */ getEntityManager(): EntityManager; protected validateRepositoryType(entities: Entity[] | Entity, method: string): void; }