import type { Transaction } from './connections/Connection.js'; import { type Cascade, type DeferMode, type EmbeddedPrefixMode, type EventType, type LoadStrategy, type PopulatePath, type QueryOrderMap, ReferenceKind } from './enums.js'; import { type AssignOptions } from './entity/EntityAssigner.js'; import { type EntityIdentifier } from './entity/EntityIdentifier.js'; import { type EntityLoaderOptions } from './entity/EntityLoader.js'; import { type Collection } from './entity/Collection.js'; import { type EntityFactory } from './entity/EntityFactory.js'; import { type EntityRepository } from './entity/EntityRepository.js'; import { Reference, type ScalarReference } from './entity/Reference.js'; import type { SerializationContext } from './serialization/SerializationContext.js'; import type { SerializeOptions } from './serialization/EntitySerializer.js'; import type { MetadataStorage } from './metadata/MetadataStorage.js'; import type { EntitySchema } from './metadata/EntitySchema.js'; import type { IndexColumnOptions } from './metadata/types.js'; import type { Type, types } from './types/index.js'; import type { Platform } from './platforms/Platform.js'; import type { Configuration } from './utils/Configuration.js'; import type { Raw } from './utils/RawQueryFragment.js'; import type { EntityManager } from './EntityManager.js'; import type { EventSubscriber } from './events/EventSubscriber.js'; import type { FilterOptions, FindOneOptions, FindOptions, LoadHint } from './drivers/IDatabaseDriver.js'; export type { Raw }; /** Generic constructor type. Matches any class that can be instantiated with `new`. */ export type Constructor = new (...args: any[]) => T; /** Simple string-keyed object type. Use instead of `Record` for convenience. */ export type Dictionary = { [k: string]: T; }; /** Record of compiled functions, used internally for hydration and comparison. */ export type CompiledFunctions = Record any>; /** * Extracts string property keys from an entity, excluding symbols, functions, and internal keys. * Pass `B = true` to also exclude scalar properties (useful for getting only relation keys). */ export type EntityKey = string & { [K in keyof T]-?: CleanKeys extends never ? never : K; }[keyof T]; /** Resolves to the value type of entity properties (keyed by `EntityKey`). */ export type EntityValue = T[EntityKey]; /** Resolves to the value type within `EntityData` (the data shape used for create/update). */ export type EntityDataValue = EntityData[EntityKey]; /** Extracts valid keys for `FilterQuery`. */ export type FilterKey = keyof FilterQuery; /** A function type that accepts a dictionary argument and returns a Promise. */ export type AsyncFunction = (args: T) => Promise; /** Identity mapped type that forces TypeScript to eagerly evaluate and flatten `T`. */ export type Compute = { [K in keyof T]: T[K]; } & {}; type InternalKeys = 'EntityRepositoryType' | 'PrimaryKeyProp' | 'OptionalProps' | 'EagerProps' | 'HiddenProps' | '__selectedType' | '__loadedType'; /** Filters out function, symbol, and internal keys from an entity type. When `B = true`, also excludes scalar keys. */ export type CleanKeys = T[K] & {} extends Function ? never : K extends symbol | InternalKeys ? never : B extends true ? T[K] & {} extends Scalar ? never : K : K; /** Extracts keys of `T` whose values are functions. */ export type FunctionKeys = T[K] extends Function ? K : never; /** Conditional cast: returns `T` if it extends `R`, otherwise returns `R`. */ export type Cast = T extends R ? T : R; /** Evaluates to `true` if `T` is the `unknown` type. */ export type IsUnknown = T extends unknown ? (unknown extends T ? true : never) : never; /** Evaluates to `true` if `T` is `any`. */ export type IsAny = 0 extends 1 & T ? true : false; /** Evaluates to `True` if `T` is `never`, otherwise `False`. */ export type IsNever = [T] extends [never] ? True : False; /** Represents a value that may be synchronous or wrapped in a Promise. */ export type MaybePromise = T | Promise; /** * Structural type for matching Collection without triggering full interface evaluation. * Using `T extends CollectionShape` instead of `T extends Collection` avoids * forcing TypeScript to evaluate Collection's 30+ methods, preventing instantiation explosion * (~133k → ~2k instantiations). * * Usage: * - Matching only: `T extends CollectionShape` * - With inference: `T extends CollectionShape` */ type CollectionShape = { [k: number]: T; readonly [CollectionBrand]: true; }; /** * Structural type for matching LoadedCollection (extends CollectionShape with `$` property). * * Usage: * - Matching only: `T extends LoadedCollectionShape` * - With inference: `T extends LoadedCollectionShape` */ type LoadedCollectionShape = CollectionShape & { $: any; }; /** * Structural type for matching Reference without triggering full class evaluation. * Using `T extends ReferenceShape` instead of `T extends Reference` avoids * forcing TypeScript to evaluate Reference's methods, preventing instantiation overhead * (~800 → ~15 instantiations). * * Usage: * - Matching only: `T extends ReferenceShape` * - With inference: `T extends ReferenceShape` */ type ReferenceShape = { unwrap(): T; }; /** * Structural type for matching LoadedReference (Reference with `$` property). * Note: We don't parameterize ReferenceShape here because for loaded relations, * the Reference unwrap() returns the base type while $ returns the Loaded type. * We infer T from $ to get the full Loaded type for EntityDTO. */ type LoadedReferenceShape = ReferenceShape & { $: T; }; /** * Structural type for matching any loadable relation (Collection, Reference, or array). * Using this instead of `Loadable` in conditional type checks prevents * TypeScript from evaluating the full Collection/Reference interfaces. */ type LoadableShape = CollectionShape | ReferenceShape | readonly any[]; /** Gets all keys from all members of a union type (distributes over the union). */ export type UnionKeys = T extends any ? keyof T : never; /** Gets the type of a property from all union members that have it (distributes over the union). */ export type UnionPropertyType = T extends any ? (K extends keyof T ? T[K] : never) : never; type IsUnion = T extends any ? ([U] extends [T] ? false : true) : false; /** * Merges all members of a union type into a single object with all their properties. * For non-union types, returns `T` directly to avoid expensive key iteration. */ export type MergeUnion = [T] extends [object] ? T extends Scalar ? T : IsUnion extends true ? { [K in UnionKeys]: UnionPropertyType; } : T : T; /** Recursively makes all properties of `T` optional, including nested objects and arrays. */ export type DeepPartial = T & { [P in keyof T]?: T[P] extends (infer U)[] ? DeepPartial[] : T[P] extends Readonly[] ? Readonly>[] : DeepPartial; }; /** Symbol used to declare a custom repository type on an entity class (e.g., `[EntityRepositoryType]?: BookRepository`). */ export declare const EntityRepositoryType: unique symbol; /** Symbol used to declare the primary key property name(s) on an entity (e.g., `[PrimaryKeyProp]?: 'id'`). */ export declare const PrimaryKeyProp: unique symbol; /** Symbol used as a brand on `CollectionShape` to prevent false structural matches with entities that have properties like `owner`. */ export declare const CollectionBrand: unique symbol; /** Symbol used to declare which properties are optional in `em.create()` (e.g., `[OptionalProps]?: 'createdAt'`). */ export declare const OptionalProps: unique symbol; /** Symbol used to declare which relation properties should be eagerly loaded (e.g., `[EagerProps]?: 'author'`). */ export declare const EagerProps: unique symbol; /** Symbol used to declare which properties are hidden from serialization (e.g., `[HiddenProps]?: 'password'`). */ export declare const HiddenProps: unique symbol; /** Symbol used to declare type-level configuration on an entity (e.g., `[Config]?: DefineConfig<{ forceObject: true }>`). */ export declare const Config: unique symbol; /** Symbol used to declare the entity name as a string literal type (used by `defineEntity`). */ export declare const EntityName: unique symbol; /** Extracts the entity name string literal from an entity type that declares `[EntityName]`. */ export type InferEntityName = T extends { [EntityName]?: infer Name; } ? (Name extends string ? Name : never) : never; /** * Branded type that marks a property as optional in `em.create()`. * Use as a property type wrapper: `createdAt: Opt` instead of listing in `[OptionalProps]`. */ export type Opt = T & Opt.Brand; export declare namespace Opt { const __optional: unique symbol; interface Brand { [__optional]?: 1; } } /** * Branded type that marks a nullable property as required in `em.create()`. * By default, nullable properties are treated as optional; this forces them to be explicitly provided. */ export type RequiredNullable = (T & RequiredNullable.Brand) | null; export declare namespace RequiredNullable { const __requiredNullable: unique symbol; interface Brand { [__requiredNullable]?: 1; } } /** * Branded type that marks a property as hidden from serialization. * Use as a property type wrapper: `password: Hidden` instead of listing in `[HiddenProps]`. */ export type Hidden = T & Hidden.Brand; export declare namespace Hidden { const __hidden: unique symbol; interface Brand { [__hidden]?: 1; } } /** * Branded type for entity-level configuration (e.g., `[Config]?: DefineConfig<{ forceObject: true }>`). * Controls type-level behavior such as forcing object representation for primary keys in DTOs. */ export type DefineConfig = T & DefineConfig.Brand; export declare namespace DefineConfig { const __config: unique symbol; interface Brand { [__config]?: 1; } } /** Extracts only the `TypeConfig` keys from a branded config type, stripping the brand. */ export type CleanTypeConfig = Compute>>; /** Configuration options that can be set on an entity via the `[Config]` symbol. */ export interface TypeConfig { forceObject?: boolean; } declare const __selectedType: unique symbol; declare const __loadedType: unique symbol; declare const __loadHint: unique symbol; declare const __fieldsHint: unique symbol; /** * Expands a populate hint into all its prefixes. * e.g., Prefixes<'a.b.c'> = 'a' | 'a.b' | 'a.b.c' * This reflects that loading 'a.b.c' means 'a' and 'a.b' are also loaded. * Special case: '*' returns string to ensure Loaded is assignable to any Loaded. */ export type Prefixes = S extends '*' ? string : S extends `${infer H}.${infer T}` ? H | `${H}.${Prefixes}` : S; /** Unwraps a value to its primary key type. Scalars pass through; References are unwrapped first. */ export type UnwrapPrimary = T extends Scalar ? T : T extends ReferenceShape ? Primary : Primary; type PrimaryPropToType = { [Index in keyof Keys]: UnwrapPrimary; }; type ReadonlyPrimary = T extends any[] ? Readonly : T; /** * Resolves the primary key type for an entity. Uses `[PrimaryKeyProp]` if declared, * otherwise falls back to `_id`, `id`, or `uuid` properties. For composite keys, returns a tuple. */ export type Primary = IsAny extends true ? any : T extends { [PrimaryKeyProp]?: infer PK; } ? PK extends undefined ? Omit : PK extends keyof T ? ReadonlyPrimary> : PK extends (keyof T)[] ? ReadonlyPrimary> : PK : T extends { _id?: infer PK; } ? ReadonlyPrimary | string : T extends { id?: infer PK; } ? ReadonlyPrimary : T extends { uuid?: infer PK; } ? ReadonlyPrimary : T; /** @internal */ export type PrimaryProperty = T extends { [PrimaryKeyProp]?: infer PK; } ? PK extends keyof T ? PK : PK extends any[] ? PK[number] : never : T extends { _id?: any; } ? T extends { id?: any; } ? 'id' | '_id' : '_id' : T extends { id?: any; } ? 'id' : T extends { uuid?: any; } ? 'uuid' : never; /** Union of all allowed primary key value types (number, string, bigint, Date, ObjectId-like). */ export type IPrimaryKeyValue = number | string | bigint | Date | { toHexString(): string; }; /** Alias for a primary key value, constrained to `IPrimaryKeyValue`. */ export type IPrimaryKey = T; /** Union of types considered "scalar" (non-entity) values. Used to distinguish entity relations from plain values. */ export type Scalar = boolean | number | string | bigint | symbol | Date | RegExp | Uint8Array | { toHexString(): string; }; type Primitive = boolean | number | string | bigint | symbol; /** Expands a scalar type to include alternative representations accepted in queries (e.g., `Date | string`). */ export type ExpandScalar = null | (T extends string ? T | RegExp : T extends Date ? Date | string : T extends bigint ? bigint | string | number : T); /** Marker interface for query builders that can be used as subqueries */ export interface Subquery { readonly __subquery: true; } /** Map of query operators (`$eq`, `$gt`, `$in`, etc.) available for filtering a value of type `T`. */ export type OperatorMap = { $and?: ExpandQuery[]; $or?: ExpandQuery[]; $eq?: ExpandScalar | readonly ExpandScalar[] | Subquery; $ne?: ExpandScalar | readonly ExpandScalar[] | Subquery; $in?: readonly ExpandScalar[] | readonly Primary[] | Raw | Subquery; $nin?: readonly ExpandScalar[] | readonly Primary[] | Raw | Subquery; $not?: ExpandQuery; $none?: ExpandQuery; $some?: ExpandQuery; $every?: ExpandQuery; $size?: number | { $eq?: number; $ne?: number; $gt?: number; $gte?: number; $lt?: number; $lte?: number; }; $gt?: ExpandScalar | readonly ExpandScalar[] | Subquery; $gte?: ExpandScalar | readonly ExpandScalar[] | Subquery; $lt?: ExpandScalar | readonly ExpandScalar[] | Subquery; $lte?: ExpandScalar | readonly ExpandScalar[] | Subquery; $like?: string; $re?: string; $ilike?: string; $fulltext?: string; $overlap?: readonly string[] | string | object; $contains?: readonly string[] | string | object; $contained?: readonly string[] | string | object; $exists?: boolean; $hasKey?: string; $hasKeys?: readonly string[]; $hasSomeKeys?: readonly string[]; }; /** A single filter value: the raw value, its expanded scalar form, its primary key, or a raw SQL expression. */ export type FilterItemValue = T | ExpandScalar | Primary | Raw; /** A complete filter value: an operator map, a single value, an array of values, or null. */ export type FilterValue = OperatorMap> | FilterItemValue | FilterItemValue[] | null; type FilterObjectProp = K extends keyof MergeUnion ? MergeUnion[K] : K extends keyof T ? T[K] : never; type ExpandQueryMerged = [T] extends [object] ? [T] extends [Scalar] ? never : FilterQuery> : FilterValue; type ElemMatchCondition> = { [K in keyof T]?: T[K] | OperatorMap; } & { $or?: ElemMatchCondition[]; $and?: ElemMatchCondition[]; $not?: ElemMatchCondition; }; type ElemMatchFilter = T extends readonly (infer E)[] ? E extends Record ? { $elemMatch: ElemMatchCondition; } : never : never; /** Object form of a filter query, mapping entity keys to their filter conditions. */ export type FilterObject = { -readonly [K in EntityKey]?: ExpandQuery>> | ExpandQueryMerged>> | FilterValue>> | ElemMatchFilter> | null; }; /** Recursively expands a type into its `FilterQuery` form for nested object filtering. */ export type ExpandQuery = T extends object ? (T extends Scalar ? never : FilterQuery) : FilterValue; /** Partial entity shape with all entity properties optional. */ export type EntityProps = { -readonly [K in EntityKey]?: T[K]; }; /** Object-based query filter combining operator maps with property-level filters. */ export type ObjectQuery = OperatorMap & FilterObject; /** * The main query filter type used in `em.find()`, `em.findOne()`, etc. * Accepts an object query, a primary key value, entity props with operators, or an array of filters. */ export type FilterQuery = ObjectQuery | NonNullable>> | NonNullable & OperatorMap> | FilterQuery[]; /** Public interface for the entity wrapper, accessible via `wrap(entity)`. Provides helper methods for entity state management. */ export interface IWrappedEntity { isInitialized(): boolean; isManaged(): boolean; populated(populated?: boolean): void; populate(populate: readonly AutoPath[] | false, options?: EntityLoaderOptions): Promise>; init(options?: FindOneOptions): Promise | null>; toReference(): Ref & LoadedReference>>; toObject(): EntityDTO; toObject(ignoreFields: never[]): EntityDTO; toObject>(ignoreFields: Ignored[]): Omit, Ignored>; toJSON(...args: any[]): EntityDTO; toPOJO(): EntityDTO; serialize = FromEntityType, Hint extends string = never, Exclude extends string = never>(options?: SerializeOptions): SerializeDTO; setSerializationContext(options: LoadHint): void; assign = FromEntityType, Convert extends boolean = false, Data extends EntityData | Partial> = EntityData | Partial>>(data: Data & IsSubset, Data>, options?: AssignOptions): MergeSelected; getSchema(): string | undefined; setSchema(schema?: string): void; } /** @internal Extended wrapper interface with internal state used by the ORM runtime. */ export interface IWrappedEntityInternal extends IWrappedEntity { hasPrimaryKey(): boolean; getPrimaryKey(convertCustomTypes?: boolean): Primary | null; getPrimaryKeys(convertCustomTypes?: boolean): Primary[] | null; setPrimaryKey(val: Primary): void; getSerializedPrimaryKey(): string & keyof Entity; __meta: EntityMetadata; __data: Dictionary; __em?: EntityManager; __platform: Platform; __config: Configuration; __factory: EntityFactory; __hydrator: IHydrator; __initialized: boolean; __originalEntityData?: EntityData; __loadedProperties: Set; __identifier?: EntityIdentifier | EntityIdentifier[]; __managed: boolean; __processing: boolean; __schema?: string; __populated: boolean; __onLoadFired: boolean; __reference?: Ref; __pk?: Primary; __primaryKeys: Primary[]; __serializationContext: { root?: SerializationContext; populate?: PopulateOptions[]; fields?: Set; exclude?: string[]; }; } /** Loose entity type used in generic contexts. Equivalent to `Partial`. */ export type AnyEntity = Partial; /** A class (function with prototype) whose instances are of type `T`. */ export type EntityClass = Function & { prototype: T; }; /** Any valid entity name reference: a class, abstract constructor, or EntitySchema. */ export type EntityName = EntityClass | EntityCtor | EntitySchema; /** Resolves the custom repository type for an entity (from `[EntityRepositoryType]`), or falls back to `Fallback`. */ export type GetRepository = Entity[typeof EntityRepositoryType] extends EntityRepository | undefined ? NonNullable : Fallback; type PolymorphicPrimaryInner = T extends object ? Primary extends readonly [infer First, infer Second, ...infer Rest] ? readonly [string, First, Second, ...Rest] | [string, First, Second, ...Rest] : readonly [string, Primary] | [string, Primary] : never; /** * Tuple format for polymorphic FK values: [discriminator, ...pkValues] * Distributes over unions, so `Post | Comment` becomes `['post', number] | ['comment', number]` * For composite keys like [tenantId, orgId], becomes ['discriminator', tenantId, orgId] */ export type PolymorphicPrimary = true extends IsUnion ? PolymorphicPrimaryInner : never; /** Allowed value types when assigning to an entity data property: the entity itself, its PK, or a polymorphic PK tuple. */ export type EntityDataPropValue = T | Primary | PolymorphicPrimary; type ExpandEntityProp = T extends Record ? { [K in keyof T as CleanKeys]?: EntityDataProp, C> | EntityDataPropValue> | null; } | EntityDataPropValue> : T; type ExpandRequiredEntityProp = T extends Record ? ExpandRequiredEntityPropObject | EntityDataPropValue> : T; type ExpandRequiredEntityPropObject = { [K in keyof T as RequiredKeys]: RequiredEntityDataProp, T, C> | EntityDataPropValue>; } & { [K in keyof T as OptionalKeys]?: RequiredEntityDataProp, T, C> | EntityDataPropValue> | null | undefined; }; type NonArrayObject = object & { [Symbol.iterator]?: never; }; /** Resolves the allowed input type for a single entity property in `EntityData`. Handles scalars, references, collections, and nested entities. */ export type EntityDataProp = T extends Date ? string | Date : T extends Scalar ? T : T extends ScalarReference ? EntityDataProp : T extends { __runtime?: infer Runtime; __raw?: infer Raw; } ? C extends true ? Raw : Runtime : T extends ReferenceShape ? EntityDataNested : T extends CollectionShape ? U | U[] | EntityDataNested | EntityDataNested[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | EntityDataNested | EntityDataNested[] : U[] | EntityDataNested[] : EntityDataNested; /** Like `EntityDataProp` but used in `RequiredEntityData` context with required/optional key distinction. */ export type RequiredEntityDataProp = T extends Date ? string | Date : Exclude extends RequiredNullable.Brand ? T | null : T extends Scalar ? T : T extends ScalarReference ? RequiredEntityDataProp : T extends { __runtime?: infer Runtime; __raw?: infer Raw; } ? C extends true ? Raw : Runtime : T extends ReferenceShape ? RequiredEntityDataNested : T extends CollectionShape ? U | U[] | RequiredEntityDataNested | RequiredEntityDataNested[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | RequiredEntityDataNested | RequiredEntityDataNested[] : U[] | RequiredEntityDataNested[] : RequiredEntityDataNested; /** Nested entity data shape for embedded or related entities within `EntityData`. */ export type EntityDataNested = T extends undefined ? never : T extends any[] ? Readonly : EntityData | ExpandEntityProp; type UnwrapScalarRef = T extends ScalarReference ? U : T; type EntityDataItem = C extends false ? UnwrapScalarRef | EntityDataProp | Raw | null : EntityDataProp | Raw | null; /** Nested entity data shape used within `RequiredEntityData` for embedded or related entities. */ export type RequiredEntityDataNested = T extends any[] ? Readonly : RequiredEntityData | ExpandRequiredEntityProp; type ExplicitlyOptionalProps = (T extends { [OptionalProps]?: infer K; } ? K : never) | ({ [K in keyof T]: T[K] extends Opt ? K : never; }[keyof T] & {}); type NullableKeys = { [K in keyof T]: unknown extends T[K] ? never : V extends T[K] ? K : never; }[keyof T]; type RequiredNullableKeys = { [K in keyof T]: Exclude extends RequiredNullable.Brand ? K : never; }[keyof T]; type ProbablyOptionalProps = PrimaryProperty | ExplicitlyOptionalProps | Exclude>, RequiredNullableKeys>; type IsOptional = T[K] extends CollectionShape ? true : ExtractType extends I ? true : K extends ProbablyOptionalProps ? true : false; type RequiredKeys = IsOptional extends false ? CleanKeys : never; type OptionalKeys = IsOptional extends false ? never : CleanKeys; /** Data shape for creating or updating entities. All properties are optional. Used in `em.create()` and `em.assign()`. */ export type EntityData = { [K in EntityKey]?: EntityDataItem; }; /** * Data shape for `em.create()` with required/optional distinction based on entity metadata. * Properties with defaults, nullable types, `Opt` brand, or `[OptionalProps]` declaration are optional. * `I` excludes additional types from being required (used for inverse side of relations). */ export type RequiredEntityData = { [K in keyof T as RequiredKeys]: T[K] | RequiredEntityDataProp | Primary | PolymorphicPrimary | Raw; } & { [K in keyof T as OptionalKeys]?: T[K] | RequiredEntityDataProp | Primary | PolymorphicPrimary | Raw | null; }; /** `EntityData` extended with an index signature, allowing arbitrary additional properties. */ export type EntityDictionary = EntityData & Record; type ExtractEagerProps = T extends { [EagerProps]?: infer PK; } ? PK : never; type Relation = { [P in keyof T as T[P] extends unknown[] | Record ? P : never]?: T[P]; }; /** Identity type that can be used to get around issues with cycles in bidirectional relations. It will disable reflect-metadata inference. */ export type Rel = T; /** Alias for `ScalarReference` (see {@apilink Ref}). */ export type ScalarRef = ScalarReference; /** Alias for `Reference & { id: number }` (see {@apilink Ref}). */ export type EntityRef = true extends IsUnknown> ? Reference : IsAny extends true ? Reference : { [K in PrimaryProperty & keyof T]: T[K]; } & Reference; /** * Ref type represents a `Reference` instance, and adds the primary keys to its prototype automatically, so you can do * `ref.id` instead of `ref.unwrap().id`. It resolves to either `ScalarRef` or `EntityRef`, based on the type argument. */ export type Ref = T extends any ? IsAny extends true ? Reference : T extends Scalar ? ScalarReference : EntityRef : never; type ExtractHiddenProps = (T extends { [HiddenProps]?: infer K; } ? K : never) | ({ [K in keyof T]: T[K] extends Primitive ? (T[K] extends Hidden ? K : never) : never; }[keyof T] & {}); type ExcludeHidden = K extends ExtractHiddenProps ? never : K; type ExtractConfig = T extends { [Config]?: infer K; } ? K & TypeConfig : TypeConfig; type PreferExplicitConfig = IsNever; type PrimaryOrObject = PreferExplicitConfig>['forceObject'] extends true ? { [K in PrimaryProperty & keyof U]: U[K]; } : Primary; type DTOWrapper = Flat extends true ? EntityDTOFlat : EntityDTO; /** Resolves the serialized (DTO) type for a single entity property. Unwraps references, collections, and custom serialized types. */ export type EntityDTOProp = T extends Scalar ? T : T extends ScalarReference ? U : T extends { __serialized?: infer U; } ? IsUnknown extends false ? U : T : T extends LoadedReferenceShape ? DTOWrapper : T extends ReferenceShape ? PrimaryOrObject : T extends LoadedCollectionShape ? DTOWrapper[] : T extends CollectionShape ? PrimaryOrObject[] : T extends readonly (infer U)[] ? U extends Scalar ? T : EntityDTOProp[] : T extends Relation ? DTOWrapper : T; type UnwrapLoadedEntity = T extends { [__loadedType]?: infer U; } ? NonNullable : T; type DTOProbablyOptionalProps = NonNullable, undefined>>; type DTOIsOptional = T[K] extends LoadedCollectionShape ? false : K extends PrimaryProperty> ? false : K extends DTOProbablyOptionalProps ? true : false; type DTORequiredKeys = DTOIsOptional extends false ? ExcludeHidden & CleanKeys : never; type DTOOptionalKeys = DTOIsOptional extends false ? never : ExcludeHidden & CleanKeys; /** * Plain object (DTO) representation of an entity as returned by `toObject()` / `toPOJO()`. * Unwraps references to PKs, collections to arrays, and respects hidden properties. */ export type EntityDTO = { [K in keyof T as DTORequiredKeys]: EntityDTOProp | AddOptional; } & { [K in keyof T as DTOOptionalKeys]?: EntityDTOProp | AddOptional; }; /** * @internal * 1-pass variant of EntityDTO — ~2x cheaper to resolve but all keys are required * (optional keys use `| undefined` in value type instead of `?` modifier). * Use only for internal type computations (output types), never as a user-facing * function parameter type where generic assignability checks are needed. */ export type EntityDTOFlat = { [K in keyof T as ExcludeHidden & CleanKeys]: EntityDTOProp | AddOptional; }; /** * @internal * Single-pass fused type that combines Loaded + EntityDTO into one mapped type. * ~40x faster than `EntityDTO>` for populated entities. */ type SerializeTopHints = H extends `${infer Top}.${string}` ? Top : H; type SerializeSubHints = H extends `${K}.${infer Rest}` ? Rest : never; type SerializeSubFields = K extends F ? '*' : [F extends `${K & string}.${infer Rest}` ? Rest : never] extends [never] ? '*' : F extends `${K & string}.${infer Rest}` ? Rest : never; type SerializeFieldsFilter = K extends Prefix | PrimaryProperty ? K : never; type SerializePropValue = K & string extends SerializeTopHints ? NonNullable extends CollectionShape ? SerializeDTO, never, C>[] : SerializeDTO, SerializeSubHints, never, C> | Extract : EntityDTOProp; type SerializePropValueWithFields = K & string extends SerializeTopHints ? NonNullable extends CollectionShape ? SerializeDTO, never, C, SerializeSubFields>[] : SerializeDTO, SerializeSubHints, never, C, SerializeSubFields> | Extract : EntityDTOProp; /** * Return type of `serialize()`. Combines Loaded + EntityDTO in a single pass for better performance. * Respects populate hints (`H`), exclude hints (`E`), and fields hints (`F`). */ export type SerializeDTO = string extends H ? EntityDTOFlat : [F] extends ['*'] ? { [K in keyof T as ExcludeHidden & CleanKeys & (IsNever extends true ? K : Exclude)]: SerializePropValue | Extract; } : { [K in keyof T as ExcludeHidden & CleanKeys & (IsNever extends true ? K : Exclude) & SerializeFieldsFilter]: SerializePropValueWithFields | Extract; }; type TargetKeys = T extends EntityClass ? keyof P : keyof T; type PropertyName = IsUnknown extends false ? TargetKeys : string; /** Table reference object passed to formula callbacks, including alias and schema information. */ export type FormulaTable = { alias: string; name: string; schema?: string; qualifiedName: string; toString: () => string; }; /** * Table reference for schema callbacks (indexes, checks, generated columns). * Unlike FormulaTable, this has no alias since schema generation doesn't use query aliases. */ export type SchemaTable = { name: string; schema?: string; qualifiedName: string; toString: () => string; }; /** * Column mapping for formula callbacks. Maps property names to fully-qualified alias.fieldName. * Has toString() returning the main alias for backwards compatibility with old formula syntax. * @example * // New recommended syntax - use cols.propName for fully-qualified references * formula: cols => `${cols.firstName} || ' ' || ${cols.lastName}` * * // Old syntax still works - cols.toString() returns the alias * formula: cols => `${cols}.first_name || ' ' || ${cols}.last_name` */ export type FormulaColumns = Record, string> & { toString(): string; }; /** * Column mapping for schema callbacks (indexes, checks, generated columns). * Maps property names to field names. For TPT entities, only includes properties * that belong to the current table (not inherited properties from parent tables). */ export type SchemaColumns = Record, string>; /** Callback for custom index expressions. Receives column mappings, table info, and the index name. */ export type IndexCallback = (columns: Record, string>, table: SchemaTable, indexName: string) => string | Raw; /** Callback for computed (formula) properties. Receives column mappings and table info, returns a SQL expression. */ export type FormulaCallback = (columns: FormulaColumns, table: FormulaTable) => string | Raw; /** Callback for CHECK constraint expressions. Receives column mappings and table info. */ export type CheckCallback = (columns: Record, string>, table: SchemaTable) => string | Raw; /** Callback for generated (computed) column expressions. Receives column mappings and table info. */ export type GeneratedColumnCallback = (columns: Record, string>, table: SchemaTable) => string | Raw; /** Definition of a CHECK constraint on a table or property. */ export interface CheckConstraint { name?: string; property?: string; expression: string | Raw | CheckCallback; } /** Branded string that accepts any string value while preserving autocompletion for known literals. */ export type AnyString = string & {}; /** Describes a single property (column, relation, or embedded) within an entity's metadata. */ export interface EntityProperty { name: EntityKey; entity: () => EntityName; target: EntityClass; type: keyof typeof types | AnyString; runtimeType: 'number' | 'string' | 'boolean' | 'bigint' | 'Buffer' | 'Date' | 'object' | 'any' | AnyString; targetMeta?: EntityMetadata; columnTypes: string[]; generated?: string | Raw | GeneratedColumnCallback; customType?: Type; customTypes: (Type | undefined)[]; hasConvertToJSValueSQL: boolean; hasConvertToDatabaseValueSQL: boolean; autoincrement?: boolean; returning?: boolean; primary?: boolean; serializedPrimaryKey: boolean; groups?: string[]; lazy?: boolean; array?: boolean; length?: number; precision?: number; scale?: number; kind: ReferenceKind; ref?: boolean; fieldNames: string[]; fieldNameRaw?: string; default?: string | number | boolean | null; defaultRaw?: string; formula?: FormulaCallback; filters?: FilterOptions; prefix?: string | boolean; prefixMode?: EmbeddedPrefixMode; embedded?: [EntityKey, EntityKey]; embeddedPath?: string[]; embeddable: EntityClass; embeddedProps: Dictionary; discriminatorColumn?: string; discriminator?: string; polymorphic?: boolean; polymorphTargets?: EntityMetadata[]; discriminatorMap?: Dictionary>; discriminatorValue?: string; object?: boolean; index?: boolean | string; unique?: boolean | string; nullable?: boolean; inherited?: boolean; renamedFrom?: string; stiMerged?: boolean; stiFieldNames?: string[]; stiFieldNameMap?: Dictionary; unsigned?: boolean; mapToPk?: boolean; persist?: boolean; hydrate?: boolean; hidden?: boolean; enum?: boolean; items?: (number | string)[]; nativeEnumName?: string; version?: boolean; concurrencyCheck?: boolean; eager?: boolean; setter?: boolean; getter?: boolean; getterName?: keyof Owner; accessor?: EntityKey; cascade: Cascade[]; orphanRemoval?: boolean; onCreate?: (entity: Owner, em: EntityManager) => any; onUpdate?: (entity: Owner, em: EntityManager) => any; deleteRule?: 'cascade' | 'no action' | 'set null' | 'set default' | AnyString; updateRule?: 'cascade' | 'no action' | 'set null' | 'set default' | AnyString; strategy?: LoadStrategy; owner: boolean; inversedBy: EntityKey; mappedBy: EntityKey; where?: FilterQuery; orderBy?: QueryOrderMap | QueryOrderMap[]; customOrder?: string[] | number[] | boolean[]; fixedOrder?: boolean; fixedOrderColumn?: string; pivotTable: string; pivotEntity: EntityClass; joinColumns: string[]; ownColumns: string[]; inverseJoinColumns: string[]; referencedColumnNames: string[]; referencedTableName: string; referencedPKs: EntityKey[]; targetKey?: string; serializer?: (value: any, options?: SerializeOptions) => any; serializedName?: string; comment?: string; /** mysql only */ extra?: string; userDefined?: boolean; optional?: boolean; ignoreSchemaChanges?: ('type' | 'extra' | 'default')[]; deferMode?: DeferMode; createForeignKeyConstraint: boolean; foreignKeyName?: string; } /** * Runtime metadata for an entity, holding its properties, relations, indexes, hooks, and more. * Created during metadata discovery and used throughout the ORM lifecycle. */ export declare class EntityMetadata = EntityCtor> { private static counter; readonly _id: number; readonly propertyOrder: Map; constructor(meta?: Partial); addProperty(prop: Partial>): void; removeProperty(name: string, sync?: boolean): void; getPrimaryProps(flatten?: boolean): EntityProperty[]; getPrimaryProp(): EntityProperty; /** * Creates a mapping from property names to field names. * @param alias - Optional alias to prefix field names. Can be a string (same for all) or a function (per-property). * When provided, also adds toString() returning the alias for backwards compatibility with formulas. * @param toStringAlias - Optional alias to return from toString(). Defaults to `alias` when it's a string. */ createColumnMappingObject(alias?: string | ((prop: EntityProperty) => string), toStringAlias?: string): FormulaColumns; /** * Creates a column mapping for schema callbacks (indexes, checks, generated columns). * For TPT entities, only includes properties that belong to the current table (ownProps). */ createSchemaColumnMappingObject(): SchemaColumns; get tableName(): string; set tableName(name: string); get uniqueName(): string; sync(initIndexes?: boolean, config?: Configuration): void; private initIndexes; /** @internal */ clone(): this; } /** Minimal column metadata with just a name and database type. */ export interface SimpleColumnMeta { name: string; type: string; } /** Abstract constructor type that matches both abstract and concrete entity classes. */ export type EntityCtor = abstract new (...args: any[]) => T; export interface EntityMetadata = EntityCtor> { name?: string; className: string; tableName: string; schema?: string; pivotTable?: boolean; virtual?: boolean; /** True if this entity represents a database view (not a virtual entity). Accepts `{ materialized: true }` as input, normalized to `true` during sync. */ view?: boolean | { materialized?: boolean; withData?: boolean; }; /** True if this is a materialized view (PostgreSQL only). Requires `view: true`. */ materialized?: boolean; /** For materialized views, whether data is populated on creation. Defaults to true. */ withData?: boolean; expression?: string | ((em: any, where: ObjectQuery, options: FindOptions, stream?: boolean) => MaybePromise); discriminatorColumn?: EntityKey | AnyString; discriminatorValue?: number | string; discriminatorMap?: Dictionary; embeddable: boolean; constructorParams?: (keyof Entity)[]; forceConstructor: boolean; extends?: EntityName; collection: string; path: string; primaryKeys: EntityKey[]; simplePK: boolean; compositePK: boolean; versionProperty: EntityKey; concurrencyCheckKeys: Set>; serializedPrimaryKey?: EntityKey; properties: { [K in EntityKey]: EntityProperty; }; props: EntityProperty[]; relations: EntityProperty[]; bidirectionalRelations: EntityProperty[]; referencingProperties: { meta: EntityMetadata; prop: EntityProperty; }[]; comparableProps: EntityProperty[]; trackingProps: EntityProperty[]; hydrateProps: EntityProperty[]; validateProps: EntityProperty[]; uniqueProps: EntityProperty[]; getterProps: EntityProperty[]; indexes: { properties?: EntityKey | EntityKey[]; name?: string; type?: string; options?: Dictionary; expression?: string | IndexCallback; columns?: IndexColumnOptions[]; include?: EntityKey | EntityKey[]; fillFactor?: number; invisible?: boolean; disabled?: boolean; clustered?: boolean; }[]; uniques: { properties?: EntityKey | EntityKey[]; name?: string; options?: Dictionary; expression?: string | IndexCallback; deferMode?: DeferMode | `${DeferMode}`; columns?: IndexColumnOptions[]; include?: EntityKey | EntityKey[]; fillFactor?: number; disabled?: boolean; }[]; checks: CheckConstraint[]; repositoryClass?: string; repository: () => EntityClass>; hooks: { [K in EventType]?: (keyof Entity | EventSubscriber[EventType])[]; }; prototype: Entity; class: Class; abstract: boolean; filters: Dictionary; comment?: string; selfReferencing?: boolean; hasUniqueProps?: boolean; readonly?: boolean; polymorphs?: EntityMetadata[]; root: EntityMetadata; definedProperties: Dictionary; /** For polymorphic M:N pivot tables, maps discriminator values to entity classes */ polymorphicDiscriminatorMap?: Dictionary; /** Inheritance type: 'sti' (Single Table Inheritance) or 'tpt' (Table-Per-Type). Only set on root entities. */ inheritanceType?: 'sti' | 'tpt'; /** For TPT: direct parent entity metadata (the entity this one extends). */ tptParent?: EntityMetadata; /** For TPT: direct child entities (entities that extend this one). */ tptChildren?: EntityMetadata[]; /** For TPT: all non-abstract descendants, sorted by depth (deepest first). Precomputed during discovery. */ allTPTDescendants?: EntityMetadata[]; /** For TPT: synthetic property representing the join to the parent table (child PK → parent PK). */ tptParentProp?: EntityProperty; /** For TPT: inverse of tptParentProp, used for joining from parent to child (parent PK → child PK). */ tptInverseProp?: EntityProperty; /** For TPT: virtual discriminator property name (computed at query time, not persisted). */ tptDiscriminatorColumn?: string; /** For TPT: properties defined only in THIS entity (not inherited from parent). */ ownProps?: EntityProperty[]; hasTriggers?: boolean; /** * Default ordering for this entity. Applied when querying this entity directly * or when it's populated as a relation. Combined with other orderings based on precedence. */ orderBy?: QueryOrderMap | QueryOrderMap[]; /** @internal can be used for computed numeric cache keys */ readonly _id: number; } /** Options for `ISchemaGenerator.create()`. */ export interface CreateSchemaOptions { wrap?: boolean; schema?: string; } /** Options for `ISchemaGenerator.clear()` to truncate/clear database tables. */ export interface ClearDatabaseOptions { schema?: string; truncate?: boolean; clearIdentityMap?: boolean; } /** Options for `ISchemaGenerator.ensureDatabase()` which creates and optionally clears the database. */ export interface EnsureDatabaseOptions extends CreateSchemaOptions, ClearDatabaseOptions { clear?: boolean; create?: boolean; forceCheck?: boolean; } /** Options for `ISchemaGenerator.drop()`. */ export interface DropSchemaOptions { wrap?: boolean; dropMigrationsTable?: boolean; dropForeignKeys?: boolean; dropDb?: boolean; schema?: string; } /** Options for `ISchemaGenerator.update()` to apply incremental schema changes. */ export interface UpdateSchemaOptions { wrap?: boolean; safe?: boolean; dropDb?: boolean; dropTables?: boolean; schema?: string; fromSchema?: DatabaseSchema; } /** Options for `ISchemaGenerator.refresh()` which drops and recreates the schema. */ export interface RefreshDatabaseOptions extends CreateSchemaOptions { ensureIndexes?: boolean; dropDb?: boolean; createSchema?: boolean; } /** Interface for the schema generator, responsible for creating, updating, and dropping database schemas. */ export interface ISchemaGenerator { create(options?: CreateSchemaOptions): Promise; update(options?: UpdateSchemaOptions): Promise; drop(options?: DropSchemaOptions): Promise; refresh(options?: RefreshDatabaseOptions): Promise; clear(options?: ClearDatabaseOptions): Promise; execute(sql: string, options?: { wrap?: boolean; }): Promise; getCreateSchemaSQL(options?: CreateSchemaOptions): Promise; getDropSchemaSQL(options?: Omit): Promise; getUpdateSchemaSQL(options?: UpdateSchemaOptions): Promise; getUpdateSchemaMigrationSQL(options?: UpdateSchemaOptions): Promise<{ up: string; down: string; }>; ensureDatabase(options?: EnsureDatabaseOptions): Promise; createDatabase(name?: string): Promise; dropDatabase(name?: string): Promise; ensureIndexes(): Promise; } /** Custom resolver for import paths in the entity generator. Returns a path/name pair or undefined to use the default. */ export type ImportsResolver = (alias: string, basePath: string, extension: '.js' | '', originFileName: string) => { path: string; name: string; } | undefined; /** Options for the entity generator (`IEntityGenerator.generate()`). Controls output format, filtering, and style. */ export interface GenerateOptions { path?: string; save?: boolean; schema?: string; takeTables?: (RegExp | string)[]; skipTables?: (RegExp | string)[]; skipColumns?: Dictionary<(RegExp | string)[]>; forceUndefined?: boolean; undefinedDefaults?: boolean; bidirectionalRelations?: boolean; identifiedReferences?: boolean; entityDefinition?: 'decorators' | 'defineEntity' | 'entitySchema'; decorators?: 'es' | 'legacy'; inferEntityType?: boolean; enumMode?: 'ts-enum' | 'union-type' | 'dictionary'; esmImport?: boolean; scalarTypeInDecorator?: boolean; scalarPropertiesForRelations?: 'always' | 'never' | 'smart'; fileName?: (className: string) => string; onImport?: ImportsResolver; extraImports?: (basePath: string, originFileName: string) => string[] | undefined; onlyPurePivotTables?: boolean; outputPurePivotTables?: boolean; readOnlyPivotTables?: boolean; customBaseEntityName?: string; useCoreBaseEntity?: boolean; coreImportsPrefix?: string; onInitialMetadata?: MetadataProcessor; onProcessedMetadata?: MetadataProcessor; } /** Interface for the entity generator, which reverse-engineers database schema into entity source files. */ export interface IEntityGenerator { generate(options?: GenerateOptions): Promise; } /** Basic migration descriptor with a name and optional file path. */ export type MigrationInfo = { name: string; path?: string; }; /** Options for controlling which migrations to run (range, specific list, or transaction). */ export type MigrateOptions = { from?: string | number; to?: string | number; migrations?: string[]; transaction?: Transaction; }; /** Result of creating a new migration file, including the generated code and schema diff. */ export type MigrationResult = { fileName: string; code: string; diff: MigrationDiff; }; /** A row from the migrations tracking table, representing an executed migration. */ export type MigrationRow = { id: number; name: string; executed_at: Date; }; /** * @internal */ export interface IMigrationRunner { run(migration: Migration, method: 'up' | 'down'): Promise; setMasterMigration(trx: Transaction): void; unsetMasterMigration(): void; } /** * @internal */ export interface IMigratorStorage { executed(): Promise; logMigration(params: Dictionary): Promise; unlogMigration(params: Dictionary): Promise; getExecutedMigrations(): Promise; ensureTable?(): Promise; setMasterMigration(trx: Transaction): void; unsetMasterMigration(): void; getMigrationName(name: string): string; getTableName?(): { schemaName?: string; tableName: string; }; } /** Interface for the migrator, responsible for creating and executing database migrations. */ export interface IMigrator { /** * Checks current schema for changes, generates new migration if there are any. */ create(path?: string, blank?: boolean, initial?: boolean, name?: string): Promise; /** * Checks current schema for changes. */ checkSchema(): Promise; /** * Creates initial migration. This generates the schema based on metadata, and checks whether all the tables * are already present. If yes, it will also automatically log the migration as executed. * Initial migration can be created only if the schema is already aligned with the metadata, or when no schema * is present - in such case regular migration would have the same effect. */ createInitial(path?: string): Promise; /** * Returns list of already executed migrations. */ getExecuted(): Promise; /** * Returns list of pending (not yet executed) migrations found in the migration directory. */ getPending(): Promise; /** * Executes specified migrations. Without parameter it will migrate up to the latest version. */ up(options?: string | string[] | MigrateOptions): Promise; /** * Executes down migrations to the given point. Without parameter it will migrate one version down. */ down(options?: string | string[] | Omit): Promise; /** * Registers event handler. */ on(event: MigratorEvent, listener: (event: MigrationInfo) => MaybePromise): IMigrator; /** * Removes event handler. */ off(event: MigratorEvent, listener: (event: MigrationInfo) => MaybePromise): IMigrator; /** * @internal */ getStorage(): IMigratorStorage; } /** Events emitted by the migrator during migration execution. */ export type MigratorEvent = 'migrating' | 'migrated' | 'reverting' | 'reverted'; /** The up and down SQL statements representing a schema diff for a migration. */ export interface MigrationDiff { up: string[]; down: string[]; } /** Interface for generating migration file contents from schema diffs. */ export interface IMigrationGenerator { /** * Generates the full contents of migration file. Uses `generateMigrationFile` to get the file contents. */ generate(diff: MigrationDiff, path?: string, name?: string): Promise<[string, string]>; /** * Creates single migration statement. By default adds `this.addSql(sql);` to the code. */ createStatement(sql: string, padLeft: number): string; /** * Returns the file contents of given migration. */ generateMigrationFile(className: string, diff: MigrationDiff): MaybePromise; } /** Interface that all migration classes must implement. */ export interface Migration { up(): Promise | void; down(): Promise | void; isTransactional(): boolean; reset(): void; setTransactionContext(ctx: Transaction): void; getQueries?(): any[]; } /** A named migration class reference, used for inline migration registration. */ export interface MigrationObject { name: string; class: Constructor; } type EntityFromInput = T extends readonly EntityName[] ? U : T extends EntityName ? U : never; type FilterDefResolved = { name: string; cond: FilterQuery | ((args: Dictionary, type: 'read' | 'update' | 'delete', em: any, options?: FindOptions | FindOneOptions, entityName?: string) => MaybePromise>); default?: boolean; entity?: EntityName | EntityName[]; args?: boolean; strict?: boolean; }; /** Definition of a query filter that can be registered globally or per-entity via `@Filter()`. */ export type FilterDef = FilterDefResolved> & { entity?: T; }; /** Type for the `populate` option in find methods. An array of relation paths to eagerly load, or `false` to disable. */ export type Populate = readonly AutoPath[] | false; /** Parsed populate hint for a single relation, including strategy and nested children. */ export type PopulateOptions = { field: EntityKey; strategy?: LoadStrategy; all?: boolean; filter?: boolean; joinType?: 'inner join' | 'left join'; children?: PopulateOptions[]; /** When true, ignores `mapToPk` on the property and returns full entity data instead of just PKs. */ dataOnly?: boolean; }; /** Inline options that can be appended to populate hint strings (e.g., strategy, join type). */ export type PopulateHintOptions = { strategy?: LoadStrategy.JOINED | LoadStrategy.SELECT_IN | 'joined' | 'select-in'; joinType?: 'inner join' | 'left join'; }; type ExtractType = T extends CollectionShape ? U : T extends ReferenceShape ? U : T extends Ref ? U : T extends readonly (infer U)[] ? U : T; type ExtractStringKeys = { [K in keyof T]-?: CleanKeys; }[keyof T] & {}; /** * Extracts string keys from an entity type, handling Collection/Reference wrappers. * Simplified to just check `T extends object` since ExtractType handles the unwrapping. */ type StringKeys = T extends object ? ExtractStringKeys> | E : never; type GetStringKey, E extends string> = K extends keyof T ? ExtractType : K extends E ? keyof T : never; type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; type RelationKeys = T extends object ? { [K in keyof T]-?: CleanKeys; }[keyof T] & {} : never; /** * Autocomplete-friendly type for dot-separated relation paths (e.g., `'author.books'`). * Validates each segment against entity keys and provides IDE suggestions. Depth-limited to prevent infinite recursion. */ export type AutoPath = P extends boolean ? P : [D] extends [never] ? never : P extends any ? P extends string ? P extends `${infer A}.${infer B}` ? A extends StringKeys ? `${A}.${AutoPath>, B, E, Prev[D]>}` : never : P extends StringKeys ? (NonNullable, E>> extends unknown ? Exclude : never) | (StringKeys, E>>, E> extends never ? never : `${P & string}.`) : StringKeys | `${RelationKeys}:ref` : never : never; /** Unwraps an array type to its element type; non-arrays pass through unchanged. */ export type UnboxArray = T extends any[] ? ArrayElement : T; /** Extracts the element type from an array type. */ export type ArrayElement = ArrayType extends (infer ElementType)[] ? ElementType : never; /** Unwraps a property type from its wrapper (Reference, Collection, or array) to the inner entity type. */ export type ExpandProperty = T extends ReferenceShape ? NonNullable : T extends CollectionShape ? NonNullable : T extends (infer U)[] ? NonNullable : NonNullable; type LoadedLoadable = T extends CollectionShape ? LoadedCollection : T extends ScalarReference ? LoadedScalarReference : T extends ReferenceShape ? T & LoadedReference : T extends Scalar ? T : T extends (infer U)[] ? U extends Scalar ? T : E[] : E; type IsTrue = IsNever extends true ? false : T extends boolean ? (T extends true ? true : false) : false; type StringLiteral = T extends string ? (string extends T ? never : T) : never; type Prefix = K extends `${infer S}.${string}` ? S : K extends '*' ? keyof T : K; type IsPrefixedExclude = K extends E ? never : K; /** Checks whether a key `K` is included in the populate/fields hints. Used to filter entity keys in `Loaded`/`Selected`. */ export type IsPrefixed = IsNever extends false ? IsPrefixedExclude : K extends symbol ? never : IsTrue extends true ? T[K] & {} extends LoadableShape ? K : never : IsNever> extends true ? never : '*' extends L ? K : K extends Prefix ? K : K extends PrimaryProperty ? K : never; type Suffix = Hint extends `${infer Pref}.${infer Suf}` ? Pref extends Key ? Suf : never : Hint extends All ? Hint : never; /** Validates that `U` is a subset of `T`. Returns `{}` if valid, or a mapped type with `never` values to cause a type error. */ export type IsSubset = keyof U extends keyof T ? {} : string extends keyof U ? {} : { [K in keyof U as K extends keyof T ? never : CleanKeys]: never; }; /** * Fast check if T is a Loaded type by looking for the marker symbol. * This is much cheaper than matching against the full Loaded structure. */ type IsLoadedType = T extends { [__loadedType]?: any; } ? true : false; /** * Optimized MergeSelected using intersection instead of extraction. * When T is already Loaded, we intersect with a new Loaded type for the selected fields. * This avoids the expensive pattern matching needed to extract hints from Loaded types. */ export type MergeSelected = IsLoadedType extends true ? T & Loaded : T; /** * Optimized MergeLoaded using intersection instead of extraction. * When T is already Loaded, we intersect with a new Loaded type for the additional hints. * This avoids the expensive pattern matching needed to extract hints from Loaded types. * Used for `em.populate` and `em.refresh`. */ export type MergeLoaded = IsLoadedType extends true ? T & Loaded : Loaded; /** Extracts the nullability modifiers (`null`, `undefined`, or both) from a type `T`. */ export type AddOptional = undefined | null extends T ? null | undefined : null extends T ? null : undefined extends T ? undefined : never; type LoadedProp = LoadedLoadable, L, F, E>>; /** Extracts the eager-loaded property names declared via `[EagerProps]` as a string union. */ export type AddEager = ExtractEagerProps & string; /** Combines an explicit populate hint `L` with the entity's eagerly loaded properties. */ export type ExpandHint = L | AddEager; /** * Entity type narrowed to only the selected fields (`F`) and populated relations (`L`). * Used as the return type when `fields` option is specified in find methods. */ export type Selected = { [K in keyof T as IsPrefixed> | FunctionKeys]: T[K] extends Function ? T[K] : NonNullable extends Scalar ? T[K] : LoadedProp, Suffix, Suffix> | AddOptional; } & { [__selectedType]?: T; [__fieldsHint]?: (hint: F) => void; }; type LoadedEntityType = { [__loadedType]?: T; } | { [__selectedType]?: T; }; /** Accepts either a plain entity type or a `Loaded`/`Selected` wrapped version. */ export type EntityType = T | LoadedEntityType; /** Extracts the base entity type from a `Loaded`/`Selected` wrapper, or returns `T` as-is. */ export type FromEntityType = T extends LoadedEntityType ? U : T; /** Extracts the fields hint (`F`) from a `Loaded`/`Selected` type, or returns `'*'` (all fields) for unwrapped entities. */ export type ExtractFieldsHint = T extends { [__fieldsHint]?: (hint: infer F extends string) => void; } ? F : '*'; type LoadedInternal = [F] extends ['*'] ? IsNever extends true ? T & { [K in keyof T as IsPrefixed>]: LoadedProp, Suffix, Suffix, Suffix> | AddOptional; } : { [K in keyof T as IsPrefixed, E>]: LoadedProp, Suffix, Suffix, Suffix> | AddOptional; } : Selected; /** * Represents entity with its loaded relations (`populate` hint) and selected properties (`fields` hint). * The __loadHint marker uses contravariance to ensure Loaded is NOT assignable to Loaded. */ export type Loaded = LoadedInternal & { [__loadedType]?: T; [__loadHint]?: (hint: Prefixes) => void; }; /** A `Reference` that is guaranteed to be loaded, providing synchronous access via `$` and `get()`. */ export interface LoadedReference extends Reference> { $: NonNullable; get(): NonNullable; } /** A `ScalarReference` that is guaranteed to be loaded, providing synchronous access via `$` and `get()`. */ export interface LoadedScalarReference extends ScalarReference { $: T; get(): T; } /** A `Collection` that is guaranteed to be loaded, providing synchronous access via `$`, `get()`, and `getItems()`. */ export interface LoadedCollection extends Collection { $: Collection; get(): Collection; getItems(check?: boolean): T[]; } /** Alias for `Loaded`. Represents a newly created entity with all specified relations populated. */ export type New = Loaded; /** Interface for SQL/code syntax highlighters used in logging output. */ export interface Highlighter { highlight(text: string): string; } /** Interface for the metadata storage, which holds `EntityMetadata` for all discovered entities. */ export interface IMetadataStorage { getAll(): Map; get(entity: EntityName, init?: boolean, validate?: boolean): EntityMetadata; find(entity: EntityName): EntityMetadata | undefined; has(entity: EntityName): boolean; set(entity: EntityName, meta: EntityMetadata): EntityMetadata; reset(entity: EntityName): void; } /** Interface for entity hydrators, which populate entity instances from raw database data. */ export interface IHydrator { /** * Hydrates the whole entity. This process handles custom type conversions, creating missing Collection instances, * mapping FKs to entity instances, as well as merging those entities. */ hydrate(entity: T, meta: EntityMetadata, data: EntityData, factory: EntityFactory, type: 'full' | 'reference', newEntity?: boolean, convertCustomTypes?: boolean, schema?: string, parentSchema?: string, normalizeAccessors?: boolean): void; /** * Hydrates primary keys only */ hydrateReference(entity: T, meta: EntityMetadata, data: EntityData, factory: EntityFactory, convertCustomTypes?: boolean, schema?: string, parentSchema?: string, normalizeAccessors?: boolean): void; isRunning(): boolean; } /** Constructor signature for hydrator implementations. */ export interface HydratorConstructor { new (metadata: MetadataStorage, platform: Platform, config: Configuration): IHydrator; } /** Interface for the seed manager, which runs database seeders. */ export interface ISeedManager { seed(...classNames: Constructor[]): Promise; /** @internal */ seedString(...classNames: string[]): Promise; create(className: string): Promise; } /** Interface that all seeder classes must implement. The `run` method receives an EntityManager. */ export interface Seeder { run(em: EntityManager, context?: T): void | Promise; } /** A named seeder class reference, used for inline seeder registration. */ export interface SeederObject { name: string; class: Constructor; } /** Discriminator for read vs write database connections in read-replica setups. */ export type ConnectionType = 'read' | 'write'; /** Callback for processing entity metadata during discovery or entity generation. */ export type MetadataProcessor = (metadata: EntityMetadata[], platform: Platform) => MaybePromise; /** Extracts the return type if `T` is a function, otherwise returns `T` as-is. */ export type MaybeReturnType = T extends (...args: any[]) => infer R ? R : T; /** * Extended `EntitySchema` interface that carries additional type-level metadata (entity name, properties, table name). * Returned by `defineEntity()` to provide strong type inference without explicit generics. */ export interface EntitySchemaWithMeta = Record, TClass extends EntityCtor = EntityCtor> extends EntitySchema { readonly name: TName; readonly properties: TProperties; readonly tableName: TTableName; /** @internal Direct entity type access - avoids expensive pattern matching */ readonly '~entity': TEntity; /** @internal */ readonly class: TClass & { '~entityName'?: TName; }; } /** * Extracts the entity type from an `EntitySchema`, `EntitySchemaWithMeta`, or entity class. * Uses a fast-path direct property access when available, falling back to generic inference. */ export type InferEntity = Schema extends { '~entity': infer E; } ? E : Schema extends EntitySchema ? Entity : Schema extends EntityClass ? Entity : Schema;