@mikro-orm/core 7.1.0-dev.4 → 7.1.0-dev.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/EntityManager.d.ts +63 -12
- package/EntityManager.js +221 -40
- package/README.md +2 -1
- package/connections/Connection.d.ts +29 -0
- package/drivers/IDatabaseDriver.d.ts +45 -7
- package/entity/BaseEntity.d.ts +68 -1
- package/entity/BaseEntity.js +18 -0
- package/entity/Collection.d.ts +6 -3
- package/entity/Collection.js +15 -4
- package/entity/EntityFactory.js +20 -1
- package/entity/EntityLoader.d.ts +8 -1
- package/entity/EntityLoader.js +89 -28
- package/entity/EntityRepository.d.ts +27 -9
- package/entity/EntityRepository.js +12 -0
- package/entity/Reference.d.ts +42 -1
- package/entity/Reference.js +9 -0
- package/entity/defineEntity.d.ts +99 -21
- package/entity/defineEntity.js +17 -6
- package/entity/utils.js +4 -5
- package/enums.d.ts +8 -1
- package/errors.d.ts +2 -0
- package/errors.js +4 -0
- package/index.d.ts +2 -2
- package/index.js +1 -1
- package/metadata/EntitySchema.js +3 -0
- package/metadata/MetadataDiscovery.d.ts +12 -0
- package/metadata/MetadataDiscovery.js +166 -20
- package/metadata/MetadataValidator.d.ts +24 -0
- package/metadata/MetadataValidator.js +202 -1
- package/metadata/types.d.ts +71 -4
- package/naming-strategy/AbstractNamingStrategy.d.ts +1 -1
- package/naming-strategy/NamingStrategy.d.ts +1 -1
- package/package.json +1 -1
- package/platforms/Platform.d.ts +18 -3
- package/platforms/Platform.js +58 -6
- package/serialization/EntitySerializer.js +2 -1
- package/typings.d.ts +202 -22
- package/typings.js +51 -14
- package/unit-of-work/UnitOfWork.js +15 -4
- package/utils/AbstractMigrator.d.ts +20 -5
- package/utils/AbstractMigrator.js +263 -28
- package/utils/AbstractSchemaGenerator.d.ts +1 -1
- package/utils/AbstractSchemaGenerator.js +4 -1
- package/utils/Configuration.d.ts +25 -0
- package/utils/Configuration.js +1 -0
- package/utils/DataloaderUtils.d.ts +10 -1
- package/utils/DataloaderUtils.js +78 -0
- package/utils/EntityComparator.js +1 -1
- package/utils/QueryHelper.d.ts +16 -0
- package/utils/QueryHelper.js +15 -0
- package/utils/TransactionManager.js +2 -0
- package/utils/Utils.js +1 -1
- package/utils/fs-utils.d.ts +2 -0
- package/utils/fs-utils.js +7 -1
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- package/utils/partition-utils.d.ts +17 -0
- package/utils/partition-utils.js +79 -0
- package/utils/upsert-utils.d.ts +2 -0
- package/utils/upsert-utils.js +26 -1
package/typings.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import type { SerializationContext } from './serialization/SerializationContext.
|
|
|
11
11
|
import type { SerializeOptions } from './serialization/EntitySerializer.js';
|
|
12
12
|
import type { MetadataStorage } from './metadata/MetadataStorage.js';
|
|
13
13
|
import type { EntitySchema } from './metadata/EntitySchema.js';
|
|
14
|
-
import type { IndexColumnOptions } from './metadata/types.js';
|
|
14
|
+
import type { EntityPartitionBy, IndexColumnOptions } from './metadata/types.js';
|
|
15
15
|
import type { Type, types } from './types/index.js';
|
|
16
16
|
import type { Platform } from './platforms/Platform.js';
|
|
17
17
|
import type { Configuration } from './utils/Configuration.js';
|
|
@@ -47,7 +47,7 @@ export type AsyncFunction<R = any, T = Dictionary> = (args: T) => Promise<T>;
|
|
|
47
47
|
export type Compute<T> = {
|
|
48
48
|
[K in keyof T]: T[K];
|
|
49
49
|
} & {};
|
|
50
|
-
type InternalKeys = 'EntityRepositoryType' | 'PrimaryKeyProp' | 'OptionalProps' | 'EagerProps' | 'HiddenProps' | '__selectedType' | '__loadedType';
|
|
50
|
+
type InternalKeys = 'EntityRepositoryType' | 'PrimaryKeyProp' | 'OptionalProps' | 'EagerProps' | 'HiddenProps' | 'IndexHints' | '__selectedType' | '__loadedType';
|
|
51
51
|
/** Filters out function, symbol, and internal keys from an entity type. When `B = true`, also excludes scalar keys. */
|
|
52
52
|
export type CleanKeys<T, K extends keyof T, B extends boolean = false> = T[K] & {} extends Function ? never : K extends symbol | InternalKeys ? never : B extends true ? T[K] & {} extends Scalar ? never : K : K;
|
|
53
53
|
/** Extracts keys of `T` whose values are functions. */
|
|
@@ -113,7 +113,7 @@ type LoadedReferenceShape<T = any> = ReferenceShape & {
|
|
|
113
113
|
* Using this instead of `Loadable<any>` in conditional type checks prevents
|
|
114
114
|
* TypeScript from evaluating the full Collection/Reference interfaces.
|
|
115
115
|
*/
|
|
116
|
-
type LoadableShape = CollectionShape | ReferenceShape | readonly any[];
|
|
116
|
+
type LoadableShape = CollectionShape | ReferenceShape | LazyRef.Brand<any> | readonly any[];
|
|
117
117
|
/** Gets all keys from all members of a union type (distributes over the union). */
|
|
118
118
|
export type UnionKeys<T> = T extends any ? keyof T : never;
|
|
119
119
|
/** Gets the type of a property from all union members that have it (distributes over the union). */
|
|
@@ -150,6 +150,44 @@ export declare const EntityName: unique symbol;
|
|
|
150
150
|
export type InferEntityName<T> = T extends {
|
|
151
151
|
[EntityName]?: infer Name;
|
|
152
152
|
} ? (Name extends string ? Name : never) : never;
|
|
153
|
+
/**
|
|
154
|
+
* Symbol used to declare index-to-column mappings on an entity type.
|
|
155
|
+
* For decorator entities, declare as a phantom property:
|
|
156
|
+
* ```typescript
|
|
157
|
+
* [IndexHints]?: { idx_email: 'email'; idx_name_age: 'name' | 'age' };
|
|
158
|
+
* ```
|
|
159
|
+
* For `defineEntity` entities, index hints are inferred automatically from
|
|
160
|
+
* named indexes (property-level `.index('name')` and entity-level `indexes`/`uniques`).
|
|
161
|
+
*/
|
|
162
|
+
export declare const IndexHints: unique symbol;
|
|
163
|
+
/**
|
|
164
|
+
* Extracts the index hints map from an entity type. Returns `never` when no hints are declared.
|
|
165
|
+
* For decorator entities, `[IndexHints]` contains a pre-computed `{ idxName: 'prop' }` map.
|
|
166
|
+
* For `defineEntity` entities, `[IndexHints]` contains `[Properties]` (a tuple wrapping the
|
|
167
|
+
* raw property builders), which is lazily converted to the index map when first accessed.
|
|
168
|
+
*/
|
|
169
|
+
export type ExtractIndexHints<T> = T extends {
|
|
170
|
+
[IndexHints]?: infer H;
|
|
171
|
+
} ? H extends [infer P extends Record<string, any>] ? InferPropertyIndexMap<P> : H : never;
|
|
172
|
+
/**
|
|
173
|
+
* Extracts `{ indexName: propertyKey }` from property builder options.
|
|
174
|
+
* Checks `.index('name')` and `.unique('name')` on each property in a single pass.
|
|
175
|
+
*/
|
|
176
|
+
export type InferPropertyIndexMap<Properties extends Record<string, any>> = {
|
|
177
|
+
[K in keyof Properties as MaybeReturnType<Properties[K]> extends {
|
|
178
|
+
'~options': {
|
|
179
|
+
index: infer N extends string;
|
|
180
|
+
};
|
|
181
|
+
} ? N : MaybeReturnType<Properties[K]> extends {
|
|
182
|
+
'~options': {
|
|
183
|
+
unique: infer N extends string;
|
|
184
|
+
};
|
|
185
|
+
} ? N : never]: K & string;
|
|
186
|
+
};
|
|
187
|
+
/** Union of declared index names on an entity. Falls back to `string` when no `[IndexHints]` are declared. */
|
|
188
|
+
export type IndexName<T> = [ExtractIndexHints<T>] extends [never] ? string : (keyof ExtractIndexHints<T> & string) | (string & {});
|
|
189
|
+
/** Properties covered by the named index on entity T. Falls back to all entity keys when the index is unknown. */
|
|
190
|
+
export type IndexColumns<T, Name extends string> = ExtractIndexHints<T> extends Record<Name, infer Cols> ? Cols & string : EntityKey<T>;
|
|
153
191
|
/**
|
|
154
192
|
* Branded type that marks a property as optional in `em.create()`.
|
|
155
193
|
* Use as a property type wrapper: `createdAt: Opt<Date>` instead of listing in `[OptionalProps]`.
|
|
@@ -328,6 +366,18 @@ export type ObjectQuery<T> = OperatorMap<T> & FilterObject<T>;
|
|
|
328
366
|
* Accepts an object query, a primary key value, entity props with operators, or an array of filters.
|
|
329
367
|
*/
|
|
330
368
|
export type FilterQuery<T> = ObjectQuery<T> | NonNullable<ExpandScalar<Primary<T>>> | NonNullable<EntityProps<T> & OperatorMap<T>> | FilterQuery<T>[];
|
|
369
|
+
/**
|
|
370
|
+
* `FilterQuery` restricted to only properties covered by the specified index(es).
|
|
371
|
+
* Used when `using` option is set in `FindOptions` to enforce type-safe index usage.
|
|
372
|
+
*/
|
|
373
|
+
export type IndexFilterQuery<T, Using extends string> = [Using] extends [never] ? FilterQuery<T> : (OperatorMap<T> & {
|
|
374
|
+
-readonly [K in Extract<EntityKey<T>, IndexColumns<T, Using>>]?: ExpandQuery<ExpandProperty<FilterObjectProp<T, K>>> | ExpandQueryMerged<ExpandProperty<FilterObjectProp<T, K>>> | FilterValue<ExpandProperty<FilterObjectProp<T, K>>> | ElemMatchFilter<FilterObjectProp<T, K>> | null;
|
|
375
|
+
}) | NonNullable<ExpandScalar<Primary<T>>> | IndexFilterQuery<T, Using>[];
|
|
376
|
+
/** Replaces `where` and `using` on an options type with index-aware variants when `Using` is specified. */
|
|
377
|
+
export type WithUsingOptions<Opts, Entity, Using extends string> = Omit<Opts, 'where' | 'using'> & {
|
|
378
|
+
using?: Using | Using[];
|
|
379
|
+
where?: [Using] extends [never] ? FilterQuery<Entity> : IndexFilterQuery<Entity, Using>;
|
|
380
|
+
};
|
|
331
381
|
/** Public interface for the entity wrapper, accessible via `wrap(entity)`. Provides helper methods for entity state management. */
|
|
332
382
|
export interface IWrappedEntity<Entity extends object> {
|
|
333
383
|
isInitialized(): boolean;
|
|
@@ -417,12 +467,12 @@ type NonArrayObject = object & {
|
|
|
417
467
|
export type EntityDataProp<T, C extends boolean> = T extends Date ? string | Date : T extends Scalar ? T : T extends ScalarReference<infer U> ? EntityDataProp<U, C> : T extends {
|
|
418
468
|
__runtime?: infer Runtime;
|
|
419
469
|
__raw?: infer Raw;
|
|
420
|
-
} ? C extends true ? Raw : Runtime : T extends ReferenceShape<infer U> ? EntityDataNested<U, C> : T extends CollectionShape<infer U> ? U | U[] | EntityDataNested<U & object, C> | EntityDataNested<U & object, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | EntityDataNested<U, C> | EntityDataNested<U, C>[] : U[] | EntityDataNested<U, C>[] : EntityDataNested<T, C>;
|
|
470
|
+
} ? C extends true ? Raw : Runtime : T extends LazyRef.Brand<infer U> ? EntityDataNested<U, C> : T extends ReferenceShape<infer U> ? EntityDataNested<U, C> : T extends CollectionShape<infer U> ? U | U[] | EntityDataNested<U & object, C> | EntityDataNested<U & object, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | EntityDataNested<U, C> | EntityDataNested<U, C>[] : U[] | EntityDataNested<U, C>[] : EntityDataNested<T, C>;
|
|
421
471
|
/** Like `EntityDataProp` but used in `RequiredEntityData` context with required/optional key distinction. */
|
|
422
472
|
export type RequiredEntityDataProp<T, O, C extends boolean> = T extends Date ? string | Date : Exclude<T, null> extends RequiredNullable.Brand ? T | null : T extends Scalar ? T : T extends ScalarReference<infer U> ? RequiredEntityDataProp<U, O, C> : T extends {
|
|
423
473
|
__runtime?: infer Runtime;
|
|
424
474
|
__raw?: infer Raw;
|
|
425
|
-
} ? C extends true ? Raw : Runtime : T extends ReferenceShape<infer U> ? RequiredEntityDataNested<U, O, C> : T extends CollectionShape<infer U> ? U | U[] | RequiredEntityDataNested<U & object, O, C> | RequiredEntityDataNested<U & object, O, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | RequiredEntityDataNested<U, O, C> | RequiredEntityDataNested<U, O, C>[] : U[] | RequiredEntityDataNested<U, O, C>[] : RequiredEntityDataNested<T, O, C>;
|
|
475
|
+
} ? C extends true ? Raw : Runtime : T extends LazyRef.Brand<infer U> ? RequiredEntityDataNested<U, O, C> : T extends ReferenceShape<infer U> ? RequiredEntityDataNested<U, O, C> : T extends CollectionShape<infer U> ? U | U[] | RequiredEntityDataNested<U & object, O, C> | RequiredEntityDataNested<U & object, O, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | RequiredEntityDataNested<U, O, C> | RequiredEntityDataNested<U, O, C>[] : U[] | RequiredEntityDataNested<U, O, C>[] : RequiredEntityDataNested<T, O, C>;
|
|
426
476
|
/** Nested entity data shape for embedded or related entities within `EntityData`. */
|
|
427
477
|
export type EntityDataNested<T, C extends boolean = false> = T extends undefined ? never : T extends any[] ? Readonly<T> : EntityData<T, C> | ExpandEntityProp<T, C>;
|
|
428
478
|
type UnwrapScalarRef<T> = T extends ScalarReference<infer U> ? U : T;
|
|
@@ -471,6 +521,35 @@ type Relation<T> = {
|
|
|
471
521
|
export type Rel<T> = T;
|
|
472
522
|
/** Alias for `ScalarReference` (see {@apilink Ref}). */
|
|
473
523
|
export type ScalarRef<T> = ScalarReference<T>;
|
|
524
|
+
/**
|
|
525
|
+
* Type-level marker for a to-one relation that is **direct at runtime** (no `Reference` wrapper) but
|
|
526
|
+
* **restricted at compile time** until narrowed via `Loaded<>`.
|
|
527
|
+
*
|
|
528
|
+
* Use as the property type on a `@ManyToOne`/`@OneToOne` relation that does **not** have `ref: true`:
|
|
529
|
+
*
|
|
530
|
+
* ```ts
|
|
531
|
+
* @ManyToOne(() => User)
|
|
532
|
+
* author!: LazyRef<User>;
|
|
533
|
+
* ```
|
|
534
|
+
*
|
|
535
|
+
* Semantics:
|
|
536
|
+
* - **Runtime**: identical to a plain direct relation — `article.author` is a `User` instance (stub or hydrated),
|
|
537
|
+
* `article.author instanceof User` is `true`, no `Reference` object is created.
|
|
538
|
+
* - **Type (unloaded view)**: only the primary key is accessible. Accessing other properties is a compile error.
|
|
539
|
+
* - **Type (loaded view)**: once the relation is in the populate hint of a `Loaded<Entity, 'author'>`, it narrows
|
|
540
|
+
* back to the full entity — no `.$` or `.get()` indirection needed.
|
|
541
|
+
*
|
|
542
|
+
* Note: the safety is purely compile-time. JS code or `as any` casts bypass it.
|
|
543
|
+
*/
|
|
544
|
+
export type LazyRef<T extends object> = IsAny<T> extends true ? LazyRef.Brand<T> : {
|
|
545
|
+
[K in PrimaryProperty<T> & keyof T]: T[K];
|
|
546
|
+
} & LazyRef.Brand<T>;
|
|
547
|
+
export declare namespace LazyRef {
|
|
548
|
+
const __lazyRef: unique symbol;
|
|
549
|
+
interface Brand<T> {
|
|
550
|
+
[__lazyRef]?: (arg: T) => T;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
474
553
|
/** Alias for `Reference<T> & { id: number }` (see {@apilink Ref}). */
|
|
475
554
|
export type EntityRef<T extends object> = true extends IsUnknown<PrimaryProperty<T>> ? Reference<T> : IsAny<T> extends true ? Reference<T> : {
|
|
476
555
|
[K in PrimaryProperty<T> & keyof T]: T[K];
|
|
@@ -594,19 +673,39 @@ export type SchemaTable = {
|
|
|
594
673
|
export type FormulaColumns<T> = Record<PropertyName<T>, string> & {
|
|
595
674
|
toString(): string;
|
|
596
675
|
};
|
|
676
|
+
/**
|
|
677
|
+
* Column reference for schema callbacks. Behaves like a string (coercible via `toString()`),
|
|
678
|
+
* with arbitrary nested property access for embedded sub-columns (e.g. `cols.address.city`).
|
|
679
|
+
*/
|
|
680
|
+
export type SchemaColumnRef = string & {
|
|
681
|
+
readonly [key: string]: SchemaColumnRef;
|
|
682
|
+
};
|
|
597
683
|
/**
|
|
598
684
|
* Column mapping for schema callbacks (indexes, checks, generated columns).
|
|
599
685
|
* Maps property names to field names. For TPT entities, only includes properties
|
|
600
686
|
* that belong to the current table (not inherited properties from parent tables).
|
|
687
|
+
* Embedded properties expose their sub-columns via nested access (e.g. `cols.address.city`),
|
|
688
|
+
* while coercing to the embedded property's own column name via `toString()` (matches the
|
|
689
|
+
* pre-7712 behaviour, regardless of any custom `prefix`).
|
|
690
|
+
*/
|
|
691
|
+
export type SchemaColumns<T> = Record<PropertyName<T>, SchemaColumnRef>;
|
|
692
|
+
/**
|
|
693
|
+
* Callback for custom index expressions. Receives column mappings, table info, and the index name.
|
|
694
|
+
* The runtime `columns` object includes nested entries for embedded properties (see `SchemaColumnRef`);
|
|
695
|
+
* cast to `SchemaColumns<T>` if you need typed nested access.
|
|
601
696
|
*/
|
|
602
|
-
export type SchemaColumns<T> = Record<PropertyName<T>, string>;
|
|
603
|
-
/** Callback for custom index expressions. Receives column mappings, table info, and the index name. */
|
|
604
697
|
export type IndexCallback<T> = (columns: Record<PropertyName<T>, string>, table: SchemaTable, indexName: string) => string | Raw;
|
|
605
698
|
/** Callback for computed (formula) properties. Receives column mappings and table info, returns a SQL expression. */
|
|
606
699
|
export type FormulaCallback<T> = (columns: FormulaColumns<T>, table: FormulaTable) => string | Raw;
|
|
607
700
|
/** Callback for CHECK constraint expressions. Receives column mappings and table info. */
|
|
608
|
-
export type CheckCallback<T> = (columns:
|
|
609
|
-
/** Callback for
|
|
701
|
+
export type CheckCallback<T> = (columns: SchemaColumns<T>, table: SchemaTable) => string | Raw;
|
|
702
|
+
/** Callback for trigger body expressions. Receives column mappings and table info. */
|
|
703
|
+
export type TriggerCallback<T> = (columns: Record<PropertyName<T>, string>, table: SchemaTable) => string | Raw;
|
|
704
|
+
/**
|
|
705
|
+
* Callback for generated (computed) column expressions. Receives column mappings and table info.
|
|
706
|
+
* The runtime `columns` object includes nested entries for embedded properties (see `SchemaColumnRef`);
|
|
707
|
+
* cast to `SchemaColumns<T>` if you need typed nested access.
|
|
708
|
+
*/
|
|
610
709
|
export type GeneratedColumnCallback<T> = (columns: Record<PropertyName<T>, string>, table: SchemaTable) => string | Raw;
|
|
611
710
|
/** Definition of a CHECK constraint on a table or property. */
|
|
612
711
|
export interface CheckConstraint<T = any> {
|
|
@@ -614,6 +713,23 @@ export interface CheckConstraint<T = any> {
|
|
|
614
713
|
property?: string;
|
|
615
714
|
expression: string | Raw | CheckCallback<T>;
|
|
616
715
|
}
|
|
716
|
+
/** Definition of a database trigger on a table. */
|
|
717
|
+
export interface TriggerDef<T = any> {
|
|
718
|
+
/** Trigger name. Auto-generated if omitted. */
|
|
719
|
+
name?: string;
|
|
720
|
+
/** When the trigger fires relative to the event. */
|
|
721
|
+
timing: 'before' | 'after' | 'instead of';
|
|
722
|
+
/** Which DML events activate the trigger. */
|
|
723
|
+
events: ('insert' | 'update' | 'delete' | 'truncate')[];
|
|
724
|
+
/** Whether the trigger fires once per row or per statement. Defaults to `'row'`. */
|
|
725
|
+
forEach?: 'row' | 'statement';
|
|
726
|
+
/** SQL body of the trigger. Can be a string, Raw query, or callback receiving column name mappings. */
|
|
727
|
+
body?: string | Raw | TriggerCallback<T>;
|
|
728
|
+
/** Optional SQL WHEN condition for the trigger. */
|
|
729
|
+
when?: string;
|
|
730
|
+
/** Raw DDL escape hatch — full CREATE TRIGGER statement. Mutually exclusive with `body`. */
|
|
731
|
+
expression?: string;
|
|
732
|
+
}
|
|
617
733
|
/** Branded string that accepts any string value while preserving autocompletion for known literals. */
|
|
618
734
|
export type AnyString = string & {};
|
|
619
735
|
/** Describes a single property (column, relation, or embedded) within an entity's metadata. */
|
|
@@ -711,11 +827,12 @@ export interface EntityProperty<Owner = any, Target = any> {
|
|
|
711
827
|
serializer?: (value: any, options?: SerializeOptions<any>) => any;
|
|
712
828
|
serializedName?: string;
|
|
713
829
|
comment?: string;
|
|
830
|
+
collation?: string;
|
|
714
831
|
/** mysql only */
|
|
715
832
|
extra?: string;
|
|
716
833
|
userDefined?: boolean;
|
|
717
834
|
optional?: boolean;
|
|
718
|
-
ignoreSchemaChanges?: ('type' | 'extra' | 'default')[];
|
|
835
|
+
ignoreSchemaChanges?: ('type' | 'extra' | 'default' | 'collation')[];
|
|
719
836
|
deferMode?: DeferMode;
|
|
720
837
|
createForeignKeyConstraint: boolean;
|
|
721
838
|
foreignKeyName?: string;
|
|
@@ -743,8 +860,12 @@ export declare class EntityMetadata<Entity = any, Class extends EntityCtor<Entit
|
|
|
743
860
|
/**
|
|
744
861
|
* Creates a column mapping for schema callbacks (indexes, checks, generated columns).
|
|
745
862
|
* For TPT entities, only includes properties that belong to the current table (ownProps).
|
|
863
|
+
* Embedded properties expose their sub-columns via nested access (e.g. `cols.address.city`),
|
|
864
|
+
* while still coercing to the embedded column prefix when used as a string (GH #7712).
|
|
746
865
|
*/
|
|
747
866
|
createSchemaColumnMappingObject(): SchemaColumns<Entity>;
|
|
867
|
+
/** @internal Recursively builds a column mapping for an embedded property's sub-columns. */
|
|
868
|
+
private static buildEmbeddedColumnMapping;
|
|
748
869
|
get tableName(): string;
|
|
749
870
|
set tableName(name: string);
|
|
750
871
|
get uniqueName(): string;
|
|
@@ -763,7 +884,6 @@ export type EntityCtor<T = any> = abstract new (...args: any[]) => T;
|
|
|
763
884
|
export interface EntityMetadata<Entity = any, Class extends EntityCtor<Entity> = EntityCtor<Entity>> {
|
|
764
885
|
name?: string;
|
|
765
886
|
className: string;
|
|
766
|
-
tableName: string;
|
|
767
887
|
schema?: string;
|
|
768
888
|
pivotTable?: boolean;
|
|
769
889
|
virtual?: boolean;
|
|
@@ -776,6 +896,8 @@ export interface EntityMetadata<Entity = any, Class extends EntityCtor<Entity> =
|
|
|
776
896
|
materialized?: boolean;
|
|
777
897
|
/** For materialized views, whether data is populated on creation. Defaults to true. */
|
|
778
898
|
withData?: boolean;
|
|
899
|
+
/** PostgreSQL partitioning definition for this table. */
|
|
900
|
+
partitionBy?: EntityPartitionBy<Entity>;
|
|
779
901
|
expression?: string | ((em: any, where: ObjectQuery<Entity>, options: FindOptions<Entity, any, any, any>, stream?: boolean) => MaybePromise<Raw | object | string>);
|
|
780
902
|
discriminatorColumn?: EntityKey<Entity> | AnyString;
|
|
781
903
|
discriminatorValue?: number | string;
|
|
@@ -814,6 +936,7 @@ export interface EntityMetadata<Entity = any, Class extends EntityCtor<Entity> =
|
|
|
814
936
|
type?: string;
|
|
815
937
|
options?: Dictionary;
|
|
816
938
|
expression?: string | IndexCallback<Entity>;
|
|
939
|
+
where?: string | FilterQuery<Entity>;
|
|
817
940
|
columns?: IndexColumnOptions[];
|
|
818
941
|
include?: EntityKey<Entity> | EntityKey<Entity>[];
|
|
819
942
|
fillFactor?: number;
|
|
@@ -826,6 +949,7 @@ export interface EntityMetadata<Entity = any, Class extends EntityCtor<Entity> =
|
|
|
826
949
|
name?: string;
|
|
827
950
|
options?: Dictionary;
|
|
828
951
|
expression?: string | IndexCallback<Entity>;
|
|
952
|
+
where?: string | FilterQuery<Entity>;
|
|
829
953
|
deferMode?: DeferMode | `${DeferMode}`;
|
|
830
954
|
columns?: IndexColumnOptions[];
|
|
831
955
|
include?: EntityKey<Entity> | EntityKey<Entity>[];
|
|
@@ -833,6 +957,7 @@ export interface EntityMetadata<Entity = any, Class extends EntityCtor<Entity> =
|
|
|
833
957
|
disabled?: boolean;
|
|
834
958
|
}[];
|
|
835
959
|
checks: CheckConstraint<Entity>[];
|
|
960
|
+
triggers: TriggerDef<Entity>[];
|
|
836
961
|
repositoryClass?: string;
|
|
837
962
|
repository: () => EntityClass<EntityRepository<any>>;
|
|
838
963
|
hooks: {
|
|
@@ -853,6 +978,8 @@ export interface EntityMetadata<Entity = any, Class extends EntityCtor<Entity> =
|
|
|
853
978
|
polymorphicDiscriminatorMap?: Dictionary<EntityClass>;
|
|
854
979
|
/** Inheritance type: 'sti' (Single Table Inheritance) or 'tpt' (Table-Per-Type). Only set on root entities. */
|
|
855
980
|
inheritanceType?: 'sti' | 'tpt';
|
|
981
|
+
/** Legacy alias populated from `EntityOptions.inheritance`; mirrored to `inheritanceType` during discovery. */
|
|
982
|
+
inheritance?: 'tpt';
|
|
856
983
|
/** For TPT: direct parent entity metadata (the entity this one extends). */
|
|
857
984
|
tptParent?: EntityMetadata;
|
|
858
985
|
/** For TPT: direct child entities (entities that extend this one). */
|
|
@@ -880,6 +1007,11 @@ export interface EntityMetadata<Entity = any, Class extends EntityCtor<Entity> =
|
|
|
880
1007
|
export interface CreateSchemaOptions {
|
|
881
1008
|
wrap?: boolean;
|
|
882
1009
|
schema?: string;
|
|
1010
|
+
/**
|
|
1011
|
+
* When true, entities with a wildcard schema (`schema: '*'`) are included in the generated DDL.
|
|
1012
|
+
* Without this, wildcard tables are skipped.
|
|
1013
|
+
*/
|
|
1014
|
+
includeWildcardSchema?: boolean;
|
|
883
1015
|
}
|
|
884
1016
|
/** Options for `ISchemaGenerator.clear()` to truncate/clear database tables. */
|
|
885
1017
|
export interface ClearDatabaseOptions {
|
|
@@ -909,6 +1041,13 @@ export interface UpdateSchemaOptions<DatabaseSchema = unknown> {
|
|
|
909
1041
|
dropTables?: boolean;
|
|
910
1042
|
schema?: string;
|
|
911
1043
|
fromSchema?: DatabaseSchema;
|
|
1044
|
+
/**
|
|
1045
|
+
* When true, entities with a wildcard schema (`schema: '*'`) are included in the diff so migrations
|
|
1046
|
+
* can be generated for them. The emitted SQL is unqualified — and therefore safe to apply against
|
|
1047
|
+
* any schema at runtime — only when neither `options.schema` nor `config.schema` is set; otherwise
|
|
1048
|
+
* wildcard tables inherit that schema qualifier.
|
|
1049
|
+
*/
|
|
1050
|
+
includeWildcardSchema?: boolean;
|
|
912
1051
|
}
|
|
913
1052
|
/** Options for `ISchemaGenerator.refresh()` which drops and recreates the schema. */
|
|
914
1053
|
export interface RefreshDatabaseOptions extends CreateSchemaOptions {
|
|
@@ -989,6 +1128,12 @@ export type MigrateOptions = {
|
|
|
989
1128
|
to?: string | number;
|
|
990
1129
|
migrations?: string[];
|
|
991
1130
|
transaction?: Transaction;
|
|
1131
|
+
/**
|
|
1132
|
+
* Target schema to run migrations against. Issues a driver-specific "set current schema"
|
|
1133
|
+
* statement (e.g. `SET search_path` on PostgreSQL) before each migration, and places the
|
|
1134
|
+
* tracking table in this schema. Overrides `migrations.schema` from config. Not supported on MSSQL.
|
|
1135
|
+
*/
|
|
1136
|
+
schema?: string;
|
|
992
1137
|
};
|
|
993
1138
|
/** Result of creating a new migration file, including the generated code and schema diff. */
|
|
994
1139
|
export type MigrationResult = {
|
|
@@ -1006,21 +1151,25 @@ export type MigrationRow = {
|
|
|
1006
1151
|
* @internal
|
|
1007
1152
|
*/
|
|
1008
1153
|
export interface IMigrationRunner {
|
|
1009
|
-
run(migration: Migration, method: 'up' | 'down'): Promise<void>;
|
|
1154
|
+
run(migration: Migration, method: 'up' | 'down', afterRun?: (tx?: Transaction) => Promise<void>): Promise<void>;
|
|
1010
1155
|
setMasterMigration(trx: Transaction): void;
|
|
1011
1156
|
unsetMasterMigration(): void;
|
|
1157
|
+
setRunSchema?(schema?: string): void;
|
|
1158
|
+
unsetRunSchema?(): void;
|
|
1012
1159
|
}
|
|
1013
1160
|
/**
|
|
1014
1161
|
* @internal
|
|
1015
1162
|
*/
|
|
1016
1163
|
export interface IMigratorStorage {
|
|
1017
1164
|
executed(): Promise<string[]>;
|
|
1018
|
-
logMigration(params: Dictionary): Promise<void>;
|
|
1019
|
-
unlogMigration(params: Dictionary): Promise<void>;
|
|
1165
|
+
logMigration(params: Dictionary, tx?: Transaction): Promise<void>;
|
|
1166
|
+
unlogMigration(params: Dictionary, tx?: Transaction): Promise<void>;
|
|
1020
1167
|
getExecutedMigrations(): Promise<MigrationRow[]>;
|
|
1021
1168
|
ensureTable?(): Promise<void>;
|
|
1022
1169
|
setMasterMigration(trx: Transaction): void;
|
|
1023
1170
|
unsetMasterMigration(): void;
|
|
1171
|
+
setRunSchema?(schema?: string): void;
|
|
1172
|
+
unsetRunSchema?(): void;
|
|
1024
1173
|
getMigrationName(name: string): string;
|
|
1025
1174
|
getTableName?(): {
|
|
1026
1175
|
schemaName?: string;
|
|
@@ -1047,11 +1196,15 @@ export interface IMigrator {
|
|
|
1047
1196
|
/**
|
|
1048
1197
|
* Returns list of already executed migrations.
|
|
1049
1198
|
*/
|
|
1050
|
-
getExecuted(
|
|
1199
|
+
getExecuted(options?: {
|
|
1200
|
+
schema?: string;
|
|
1201
|
+
}): Promise<MigrationRow[]>;
|
|
1051
1202
|
/**
|
|
1052
1203
|
* Returns list of pending (not yet executed) migrations found in the migration directory.
|
|
1053
1204
|
*/
|
|
1054
|
-
getPending(
|
|
1205
|
+
getPending(options?: {
|
|
1206
|
+
schema?: string;
|
|
1207
|
+
}): Promise<MigrationInfo[]>;
|
|
1055
1208
|
/**
|
|
1056
1209
|
* Executes specified migrations. Without parameter it will migrate up to the latest version.
|
|
1057
1210
|
*/
|
|
@@ -1060,6 +1213,11 @@ export interface IMigrator {
|
|
|
1060
1213
|
* Executes down migrations to the given point. Without parameter it will migrate one version down.
|
|
1061
1214
|
*/
|
|
1062
1215
|
down(options?: string | string[] | Omit<MigrateOptions, 'from'>): Promise<MigrationInfo[]>;
|
|
1216
|
+
/**
|
|
1217
|
+
* Combines multiple executed migrations into a single migration file.
|
|
1218
|
+
* Concatenates source code without touching the database schema.
|
|
1219
|
+
*/
|
|
1220
|
+
rollup(migrations?: string[]): Promise<MigrationResult>;
|
|
1063
1221
|
/**
|
|
1064
1222
|
* Registers event handler.
|
|
1065
1223
|
*/
|
|
@@ -1142,13 +1300,32 @@ export type PopulateOptions<T> = {
|
|
|
1142
1300
|
children?: PopulateOptions<T[keyof T]>[];
|
|
1143
1301
|
/** When true, ignores `mapToPk` on the property and returns full entity data instead of just PKs. */
|
|
1144
1302
|
dataOnly?: boolean;
|
|
1303
|
+
/** Limit the number of items loaded per parent entity. Collections will be marked as partial and readonly. */
|
|
1304
|
+
limit?: number;
|
|
1305
|
+
/** Offset for per-parent limiting (used with `limit`). */
|
|
1306
|
+
offset?: number;
|
|
1307
|
+
/** Order by clause for per-parent limiting. Takes precedence over nested `FindOptions.orderBy`. */
|
|
1308
|
+
orderBy?: QueryOrderMap<T[keyof T]>;
|
|
1145
1309
|
};
|
|
1146
1310
|
/** Inline options that can be appended to populate hint strings (e.g., strategy, join type). */
|
|
1147
1311
|
export type PopulateHintOptions = {
|
|
1148
1312
|
strategy?: LoadStrategy.JOINED | LoadStrategy.SELECT_IN | 'joined' | 'select-in';
|
|
1149
1313
|
joinType?: 'inner join' | 'left join';
|
|
1314
|
+
/** Limit the number of items loaded per parent entity. Collections will be marked as partial and readonly. */
|
|
1315
|
+
limit?: number;
|
|
1316
|
+
/** Offset for per-parent limiting (used with `limit`). */
|
|
1317
|
+
offset?: number;
|
|
1318
|
+
/** Order by clause for per-parent limiting. Takes precedence over nested `FindOptions.orderBy`. */
|
|
1319
|
+
orderBy?: QueryOrderMap<any>;
|
|
1150
1320
|
};
|
|
1151
1321
|
type ExtractType<T> = T extends CollectionShape<infer U> ? U : T extends ReferenceShape<infer U> ? U : T extends Ref<infer U> ? U : T extends readonly (infer U)[] ? U : T;
|
|
1322
|
+
/**
|
|
1323
|
+
* Like {@link ExtractType} but also unwraps {@link LazyRef}. Kept separate so {@link ExtractType}'s
|
|
1324
|
+
* hot path (used by `IsOptional`, `EntityData`, `RequiredEntityData`) doesn't pay the cost of the
|
|
1325
|
+
* extra branch — those contexts handle `LazyRef` in their own earlier branches (see
|
|
1326
|
+
* `EntityDataProp` / `RequiredEntityDataProp`) before delegating to `ExtractType`.
|
|
1327
|
+
*/
|
|
1328
|
+
type ExtractTypeWithLazyRef<T> = T extends LazyRef.Brand<infer U> ? U : ExtractType<T>;
|
|
1152
1329
|
type ExtractStringKeys<T> = {
|
|
1153
1330
|
[K in keyof T]-?: CleanKeys<T, K>;
|
|
1154
1331
|
}[keyof T] & {};
|
|
@@ -1156,8 +1333,8 @@ type ExtractStringKeys<T> = {
|
|
|
1156
1333
|
* Extracts string keys from an entity type, handling Collection/Reference wrappers.
|
|
1157
1334
|
* Simplified to just check `T extends object` since ExtractType handles the unwrapping.
|
|
1158
1335
|
*/
|
|
1159
|
-
type StringKeys<T, E extends string = never> = T extends object ? ExtractStringKeys<
|
|
1160
|
-
type GetStringKey<T, K extends StringKeys<T, string>, E extends string> = K extends keyof T ?
|
|
1336
|
+
type StringKeys<T, E extends string = never> = T extends object ? ExtractStringKeys<ExtractTypeWithLazyRef<T>> | E : never;
|
|
1337
|
+
type GetStringKey<T, K extends StringKeys<T, string>, E extends string> = K extends keyof T ? ExtractTypeWithLazyRef<T[K]> : K extends E ? keyof T : never;
|
|
1161
1338
|
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
1162
1339
|
type RelationKeys<T> = T extends object ? {
|
|
1163
1340
|
[K in keyof T]-?: CleanKeys<T, K, true>;
|
|
@@ -1172,8 +1349,8 @@ export type UnboxArray<T> = T extends any[] ? ArrayElement<T> : T;
|
|
|
1172
1349
|
/** Extracts the element type from an array type. */
|
|
1173
1350
|
export type ArrayElement<ArrayType extends unknown[]> = ArrayType extends (infer ElementType)[] ? ElementType : never;
|
|
1174
1351
|
/** Unwraps a property type from its wrapper (Reference, Collection, or array) to the inner entity type. */
|
|
1175
|
-
export type ExpandProperty<T> = T extends ReferenceShape<infer U> ? NonNullable<U> : T extends CollectionShape<infer U> ? NonNullable<U> : T extends (infer U)[] ? NonNullable<U> : NonNullable<T>;
|
|
1176
|
-
type LoadedLoadable<T, E extends object> = T extends CollectionShape ? LoadedCollection<E> : T extends ScalarReference<infer U> ? LoadedScalarReference<U> : T extends ReferenceShape ? T & LoadedReference<E> : T extends Scalar ? T : T extends (infer U)[] ? U extends Scalar ? T : E[] : E;
|
|
1352
|
+
export type ExpandProperty<T> = T extends LazyRef.Brand<infer U> ? NonNullable<U> : T extends ReferenceShape<infer U> ? NonNullable<U> : T extends CollectionShape<infer U> ? NonNullable<U> : T extends (infer U)[] ? NonNullable<U> : NonNullable<T>;
|
|
1353
|
+
type LoadedLoadable<T, E extends object> = T extends CollectionShape ? LoadedCollection<E> : T extends ScalarReference<infer U> ? LoadedScalarReference<U> : T extends LazyRef.Brand<any> ? E : T extends ReferenceShape ? T & LoadedReference<E> : T extends Scalar ? T : T extends (infer U)[] ? U extends Scalar ? T : E[] : E;
|
|
1177
1354
|
type IsTrue<T> = IsNever<T> extends true ? false : T extends boolean ? (T extends true ? true : false) : false;
|
|
1178
1355
|
type StringLiteral<T> = T extends string ? (string extends T ? never : T) : never;
|
|
1179
1356
|
type Prefix<T, K> = K extends `${infer S}.${string}` ? S : K extends '*' ? keyof T : K;
|
|
@@ -1207,7 +1384,7 @@ export type MergeSelected<T, U, F extends string> = IsLoadedType<T> extends true
|
|
|
1207
1384
|
export type MergeLoaded<T, U, P extends string, F extends string, E extends string, R extends boolean = false> = IsLoadedType<T> extends true ? T & Loaded<U, P, F, E> : Loaded<T, P, F, E>;
|
|
1208
1385
|
/** Extracts the nullability modifiers (`null`, `undefined`, or both) from a type `T`. */
|
|
1209
1386
|
export type AddOptional<T> = undefined | null extends T ? null | undefined : null extends T ? null : undefined extends T ? undefined : never;
|
|
1210
|
-
type LoadedProp<T, L extends string = never, F extends string = '*', E extends string = never> = LoadedLoadable<T, Loaded<
|
|
1387
|
+
type LoadedProp<T, L extends string = never, F extends string = '*', E extends string = never> = LoadedLoadable<T, Loaded<ExtractTypeWithLazyRef<T>, L, F, E>>;
|
|
1211
1388
|
/** Extracts the eager-loaded property names declared via `[EagerProps]` as a string union. */
|
|
1212
1389
|
export type AddEager<T> = ExtractEagerProps<T> & string;
|
|
1213
1390
|
/** Combines an explicit populate hint `L` with the entity's eagerly loaded properties. */
|
|
@@ -1322,15 +1499,18 @@ export type MaybeReturnType<T> = T extends (...args: any[]) => infer R ? R : T;
|
|
|
1322
1499
|
* Extended `EntitySchema` interface that carries additional type-level metadata (entity name, properties, table name).
|
|
1323
1500
|
* Returned by `defineEntity()` to provide strong type inference without explicit generics.
|
|
1324
1501
|
*/
|
|
1325
|
-
export interface EntitySchemaWithMeta<TName extends string = string, TTableName extends string = string, TEntity = any, TBase = never, TProperties extends Record<string, any> = Record<string, any>, TClass extends EntityCtor = EntityCtor<TEntity
|
|
1502
|
+
export interface EntitySchemaWithMeta<TName extends string = string, TTableName extends string = string, TEntity = any, TBase = never, TProperties extends Record<string, any> = Record<string, any>, TClass extends EntityCtor = EntityCtor<TEntity>, TDiscriminatorColumn extends string | undefined = undefined> extends EntitySchema<TEntity, TBase, TClass> {
|
|
1326
1503
|
readonly name: TName;
|
|
1327
1504
|
readonly properties: TProperties;
|
|
1328
1505
|
readonly tableName: TTableName;
|
|
1329
1506
|
/** @internal Direct entity type access - avoids expensive pattern matching */
|
|
1330
1507
|
readonly '~entity': TEntity;
|
|
1508
|
+
/** @internal Type-level marker carrying the discriminator column name, used by `defineEntity()` to narrow inherited discriminator properties to the literal `discriminatorValue` of each child schema. */
|
|
1509
|
+
readonly '~discriminatorColumn'?: TDiscriminatorColumn;
|
|
1331
1510
|
/** @internal */
|
|
1332
1511
|
readonly class: TClass & {
|
|
1333
1512
|
'~entityName'?: TName;
|
|
1513
|
+
'~discriminatorColumn'?: TDiscriminatorColumn;
|
|
1334
1514
|
};
|
|
1335
1515
|
}
|
|
1336
1516
|
/**
|
package/typings.js
CHANGED
|
@@ -4,7 +4,6 @@ import { EntityHelper } from './entity/EntityHelper.js';
|
|
|
4
4
|
import { helper } from './entity/wrap.js';
|
|
5
5
|
import { Utils } from './utils/Utils.js';
|
|
6
6
|
import { EntityComparator } from './utils/EntityComparator.js';
|
|
7
|
-
import { BaseEntity } from './entity/BaseEntity.js';
|
|
8
7
|
/** Symbol used to declare a custom repository type on an entity class (e.g., `[EntityRepositoryType]?: BookRepository`). */
|
|
9
8
|
export const EntityRepositoryType = Symbol('EntityRepositoryType');
|
|
10
9
|
/** Symbol used to declare the primary key property name(s) on an entity (e.g., `[PrimaryKeyProp]?: 'id'`). */
|
|
@@ -22,6 +21,16 @@ export const Config = Symbol('Config');
|
|
|
22
21
|
/** Symbol used to declare the entity name as a string literal type (used by `defineEntity`). */
|
|
23
22
|
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
24
23
|
export const EntityName = Symbol('EntityName');
|
|
24
|
+
/**
|
|
25
|
+
* Symbol used to declare index-to-column mappings on an entity type.
|
|
26
|
+
* For decorator entities, declare as a phantom property:
|
|
27
|
+
* ```typescript
|
|
28
|
+
* [IndexHints]?: { idx_email: 'email'; idx_name_age: 'name' | 'age' };
|
|
29
|
+
* ```
|
|
30
|
+
* For `defineEntity` entities, index hints are inferred automatically from
|
|
31
|
+
* named indexes (property-level `.index('name')` and entity-level `indexes`/`uniques`).
|
|
32
|
+
*/
|
|
33
|
+
export const IndexHints = Symbol('IndexHints');
|
|
25
34
|
/**
|
|
26
35
|
* Runtime metadata for an entity, holding its properties, relations, indexes, hooks, and more.
|
|
27
36
|
* Created during metadata discovery and used throughout the ORM lifecycle.
|
|
@@ -39,12 +48,20 @@ export class EntityMetadata {
|
|
|
39
48
|
this.indexes = [];
|
|
40
49
|
this.uniques = [];
|
|
41
50
|
this.checks = [];
|
|
51
|
+
this.triggers = [];
|
|
42
52
|
this.referencingProperties = [];
|
|
43
53
|
this.concurrencyCheckKeys = new Set();
|
|
44
54
|
Object.assign(this, meta);
|
|
45
55
|
const name = meta.className ?? meta.name;
|
|
46
56
|
if (!this.class && name) {
|
|
47
|
-
|
|
57
|
+
let Parent;
|
|
58
|
+
if (typeof this.extends === 'function') {
|
|
59
|
+
Parent = this.extends;
|
|
60
|
+
}
|
|
61
|
+
else if (this.extends != null && typeof this.extends.class === 'function') {
|
|
62
|
+
Parent = this.extends.class;
|
|
63
|
+
}
|
|
64
|
+
const Class = Parent ? { [name]: class extends Parent {
|
|
48
65
|
} }[name] : { [name]: class {
|
|
49
66
|
} }[name];
|
|
50
67
|
this.class = Class;
|
|
@@ -116,16 +133,37 @@ export class EntityMetadata {
|
|
|
116
133
|
/**
|
|
117
134
|
* Creates a column mapping for schema callbacks (indexes, checks, generated columns).
|
|
118
135
|
* For TPT entities, only includes properties that belong to the current table (ownProps).
|
|
136
|
+
* Embedded properties expose their sub-columns via nested access (e.g. `cols.address.city`),
|
|
137
|
+
* while still coercing to the embedded column prefix when used as a string (GH #7712).
|
|
119
138
|
*/
|
|
120
139
|
createSchemaColumnMappingObject() {
|
|
121
140
|
// For TPT entities, only include properties that belong to this entity's table
|
|
122
141
|
const props = this.inheritanceType === 'tpt' && this.ownProps ? this.ownProps : Object.values(this.properties);
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
142
|
+
const result = {};
|
|
143
|
+
for (const prop of props) {
|
|
144
|
+
if (!prop.fieldNames) {
|
|
145
|
+
continue;
|
|
126
146
|
}
|
|
127
|
-
|
|
128
|
-
|
|
147
|
+
if (prop.kind === ReferenceKind.EMBEDDED && prop.embeddedProps) {
|
|
148
|
+
result[prop.name] = EntityMetadata.buildEmbeddedColumnMapping(prop);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
result[prop.name] = prop.fieldNames[0];
|
|
152
|
+
}
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
/** @internal Recursively builds a column mapping for an embedded property's sub-columns. */
|
|
156
|
+
static buildEmbeddedColumnMapping(embeddedProp) {
|
|
157
|
+
const result = {};
|
|
158
|
+
for (const [name, sub] of Object.entries(embeddedProp.embeddedProps)) {
|
|
159
|
+
result[name] =
|
|
160
|
+
sub.kind === ReferenceKind.EMBEDDED && sub.embeddedProps
|
|
161
|
+
? EntityMetadata.buildEmbeddedColumnMapping(sub)
|
|
162
|
+
: sub.fieldNames[0];
|
|
163
|
+
}
|
|
164
|
+
const prefix = embeddedProp.fieldNames[0];
|
|
165
|
+
Object.defineProperty(result, 'toString', { value: () => prefix, enumerable: false });
|
|
166
|
+
return result;
|
|
129
167
|
}
|
|
130
168
|
get tableName() {
|
|
131
169
|
return this.collection;
|
|
@@ -149,7 +187,7 @@ export class EntityMetadata {
|
|
|
149
187
|
if (prop.inherited || (prop.persist === false && prop.userDefined !== false)) {
|
|
150
188
|
return false;
|
|
151
189
|
}
|
|
152
|
-
return prop.kind === ReferenceKind.SCALAR && ['string', 'number', 'boolean', 'Date'].includes(prop.type);
|
|
190
|
+
return (prop.kind === ReferenceKind.SCALAR && !prop.array && ['string', 'number', 'boolean', 'Date'].includes(prop.type));
|
|
153
191
|
});
|
|
154
192
|
this.hydrateProps = this.props.filter(prop => {
|
|
155
193
|
// `prop.userDefined` is either `undefined` or `false`
|
|
@@ -176,9 +214,10 @@ export class EntityMetadata {
|
|
|
176
214
|
// Virtual entities evaluate expressions at query time, view entities create actual database views.
|
|
177
215
|
this.virtual = !!this.expression && !this.view;
|
|
178
216
|
if (config) {
|
|
217
|
+
const platform = config.getPlatform();
|
|
179
218
|
for (const prop of this.props) {
|
|
180
219
|
if (prop.enum && !prop.nativeEnumName && prop.items?.every(item => typeof item === 'string')) {
|
|
181
|
-
const name =
|
|
220
|
+
const name = platform.getIndexName(this.tableName, prop.fieldNames, 'check');
|
|
182
221
|
const exists = this.checks.findIndex(check => check.name === name);
|
|
183
222
|
if (exists !== -1) {
|
|
184
223
|
this.checks.splice(exists, 1);
|
|
@@ -186,9 +225,7 @@ export class EntityMetadata {
|
|
|
186
225
|
this.checks.push({
|
|
187
226
|
name,
|
|
188
227
|
property: prop.name,
|
|
189
|
-
expression:
|
|
190
|
-
.getPlatform()
|
|
191
|
-
.getEnumCheckConstraintExpression(prop.fieldNames[0], prop.items),
|
|
228
|
+
expression: platform.getEnumCheckConstraintExpression(prop.fieldNames[0], prop.items),
|
|
192
229
|
});
|
|
193
230
|
}
|
|
194
231
|
}
|
|
@@ -244,8 +281,8 @@ export class EntityMetadata {
|
|
|
244
281
|
}, { __gettersDefined: { value: true, enumerable: false } });
|
|
245
282
|
}
|
|
246
283
|
initIndexes(prop) {
|
|
247
|
-
const simpleIndex = this.indexes.find(index => index.properties === prop.name && !index.options && !index.type && !index.expression);
|
|
248
|
-
const simpleUnique = this.uniques.find(index => index.properties === prop.name && !index.options);
|
|
284
|
+
const simpleIndex = this.indexes.find(index => index.properties === prop.name && !index.options && !index.type && !index.expression && index.where == null);
|
|
285
|
+
const simpleUnique = this.uniques.find(index => index.properties === prop.name && !index.options && !index.expression && index.where == null);
|
|
249
286
|
const owner = prop.kind === ReferenceKind.MANY_TO_ONE;
|
|
250
287
|
if (!prop.index && simpleIndex) {
|
|
251
288
|
Utils.defaultValue(simpleIndex, 'name', true);
|