@mikro-orm/core 7.0.0-dev.32 → 7.0.0-dev.321
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 +71 -63
- package/EntityManager.js +365 -283
- package/MikroORM.d.ts +44 -35
- package/MikroORM.js +109 -142
- package/README.md +7 -4
- package/cache/FileCacheAdapter.d.ts +1 -2
- package/cache/FileCacheAdapter.js +19 -14
- package/cache/GeneratedCacheAdapter.d.ts +0 -1
- package/cache/GeneratedCacheAdapter.js +0 -2
- package/cache/index.d.ts +1 -2
- package/cache/index.js +0 -2
- package/connections/Connection.d.ts +12 -5
- package/connections/Connection.js +37 -15
- package/drivers/DatabaseDriver.d.ts +25 -18
- package/drivers/DatabaseDriver.js +144 -45
- package/drivers/IDatabaseDriver.d.ts +118 -23
- package/entity/BaseEntity.d.ts +63 -4
- package/entity/BaseEntity.js +0 -3
- package/entity/Collection.d.ts +101 -29
- package/entity/Collection.js +473 -115
- package/entity/EntityAssigner.js +37 -25
- package/entity/EntityFactory.d.ts +7 -1
- package/entity/EntityFactory.js +116 -64
- package/entity/EntityHelper.d.ts +2 -2
- package/entity/EntityHelper.js +69 -27
- package/entity/EntityLoader.d.ts +11 -10
- package/entity/EntityLoader.js +264 -102
- package/entity/EntityRepository.d.ts +28 -8
- package/entity/EntityRepository.js +8 -2
- package/entity/PolymorphicRef.d.ts +12 -0
- package/entity/PolymorphicRef.js +18 -0
- package/entity/Reference.d.ts +2 -6
- package/entity/Reference.js +52 -19
- package/entity/WrappedEntity.d.ts +3 -8
- package/entity/WrappedEntity.js +6 -7
- package/entity/defineEntity.d.ts +525 -311
- package/entity/defineEntity.js +134 -290
- package/entity/index.d.ts +2 -2
- package/entity/index.js +2 -2
- package/entity/utils.d.ts +6 -1
- package/entity/utils.js +46 -11
- package/entity/validators.d.ts +11 -0
- package/entity/validators.js +66 -0
- package/enums.d.ts +8 -6
- package/enums.js +13 -17
- package/errors.d.ts +20 -10
- package/errors.js +63 -31
- package/events/EventManager.d.ts +2 -1
- package/events/EventManager.js +24 -13
- package/events/index.d.ts +1 -1
- package/events/index.js +0 -1
- package/exceptions.js +9 -2
- package/hydration/Hydrator.js +1 -2
- package/hydration/ObjectHydrator.d.ts +4 -4
- package/hydration/ObjectHydrator.js +105 -46
- package/index.d.ts +2 -2
- package/index.js +1 -2
- package/logging/DefaultLogger.d.ts +1 -1
- package/logging/DefaultLogger.js +3 -4
- package/logging/SimpleLogger.d.ts +1 -1
- package/logging/colors.d.ts +1 -1
- package/logging/colors.js +5 -7
- package/logging/index.d.ts +2 -1
- package/logging/index.js +1 -1
- package/logging/inspect.d.ts +2 -0
- package/logging/inspect.js +11 -0
- package/metadata/EntitySchema.d.ts +47 -23
- package/metadata/EntitySchema.js +103 -34
- package/metadata/MetadataDiscovery.d.ts +64 -9
- package/metadata/MetadataDiscovery.js +867 -354
- package/metadata/MetadataProvider.d.ts +11 -2
- package/metadata/MetadataProvider.js +71 -2
- package/metadata/MetadataStorage.d.ts +13 -11
- package/metadata/MetadataStorage.js +72 -41
- package/metadata/MetadataValidator.d.ts +32 -9
- package/metadata/MetadataValidator.js +214 -44
- package/metadata/discover-entities.d.ts +5 -0
- package/metadata/discover-entities.js +40 -0
- package/metadata/index.d.ts +1 -1
- package/metadata/index.js +0 -1
- package/metadata/types.d.ts +577 -0
- package/metadata/types.js +1 -0
- package/naming-strategy/AbstractNamingStrategy.d.ts +16 -4
- package/naming-strategy/AbstractNamingStrategy.js +26 -5
- package/naming-strategy/EntityCaseNamingStrategy.d.ts +3 -3
- package/naming-strategy/EntityCaseNamingStrategy.js +6 -5
- package/naming-strategy/MongoNamingStrategy.d.ts +3 -3
- package/naming-strategy/MongoNamingStrategy.js +6 -6
- package/naming-strategy/NamingStrategy.d.ts +28 -4
- package/naming-strategy/UnderscoreNamingStrategy.d.ts +3 -3
- package/naming-strategy/UnderscoreNamingStrategy.js +6 -6
- package/naming-strategy/index.d.ts +1 -1
- package/naming-strategy/index.js +0 -1
- package/not-supported.d.ts +2 -0
- package/not-supported.js +8 -0
- package/package.json +47 -36
- package/platforms/ExceptionConverter.js +1 -1
- package/platforms/Platform.d.ts +33 -15
- package/platforms/Platform.js +125 -69
- package/serialization/EntitySerializer.d.ts +6 -3
- package/serialization/EntitySerializer.js +53 -29
- package/serialization/EntityTransformer.js +33 -21
- package/serialization/SerializationContext.d.ts +6 -6
- package/serialization/SerializationContext.js +4 -4
- package/types/ArrayType.d.ts +1 -1
- package/types/ArrayType.js +2 -3
- package/types/BigIntType.js +1 -1
- package/types/BlobType.d.ts +0 -1
- package/types/BlobType.js +0 -3
- package/types/BooleanType.d.ts +1 -0
- package/types/BooleanType.js +3 -0
- package/types/DecimalType.js +2 -2
- package/types/DoubleType.js +1 -1
- package/types/EnumArrayType.js +1 -2
- package/types/JsonType.d.ts +1 -1
- package/types/JsonType.js +7 -2
- package/types/TinyIntType.js +1 -1
- package/types/Type.d.ts +2 -4
- package/types/Type.js +3 -3
- package/types/Uint8ArrayType.d.ts +0 -1
- package/types/Uint8ArrayType.js +1 -4
- package/types/UuidType.d.ts +2 -0
- package/types/UuidType.js +14 -2
- package/types/index.d.ts +3 -2
- package/typings.d.ts +427 -170
- package/typings.js +100 -45
- package/unit-of-work/ChangeSet.d.ts +4 -6
- package/unit-of-work/ChangeSet.js +8 -9
- package/unit-of-work/ChangeSetComputer.d.ts +3 -8
- package/unit-of-work/ChangeSetComputer.js +49 -26
- package/unit-of-work/ChangeSetPersister.d.ts +13 -12
- package/unit-of-work/ChangeSetPersister.js +107 -44
- package/unit-of-work/CommitOrderCalculator.d.ts +12 -10
- package/unit-of-work/CommitOrderCalculator.js +17 -15
- package/unit-of-work/IdentityMap.d.ts +12 -0
- package/unit-of-work/IdentityMap.js +39 -1
- package/unit-of-work/UnitOfWork.d.ts +34 -4
- package/unit-of-work/UnitOfWork.js +294 -107
- package/utils/AbstractMigrator.d.ts +101 -0
- package/utils/AbstractMigrator.js +303 -0
- package/utils/AbstractSchemaGenerator.d.ts +5 -5
- package/utils/AbstractSchemaGenerator.js +30 -18
- package/utils/AsyncContext.d.ts +6 -0
- package/utils/AsyncContext.js +42 -0
- package/utils/Configuration.d.ts +796 -211
- package/utils/Configuration.js +160 -197
- package/utils/ConfigurationLoader.d.ts +1 -52
- package/utils/ConfigurationLoader.js +1 -330
- package/utils/Cursor.d.ts +0 -3
- package/utils/Cursor.js +29 -14
- package/utils/DataloaderUtils.d.ts +10 -5
- package/utils/DataloaderUtils.js +42 -22
- package/utils/EntityComparator.d.ts +16 -9
- package/utils/EntityComparator.js +202 -96
- package/utils/QueryHelper.d.ts +34 -7
- package/utils/QueryHelper.js +183 -72
- package/utils/RawQueryFragment.d.ts +28 -34
- package/utils/RawQueryFragment.js +37 -72
- package/utils/RequestContext.js +2 -2
- package/utils/TransactionContext.js +2 -2
- package/utils/TransactionManager.js +11 -7
- package/utils/Utils.d.ts +16 -127
- package/utils/Utils.js +106 -401
- package/utils/clone.js +13 -23
- package/utils/env-vars.d.ts +7 -0
- package/utils/env-vars.js +98 -0
- package/utils/fs-utils.d.ts +34 -0
- package/utils/fs-utils.js +193 -0
- package/utils/index.d.ts +1 -3
- package/utils/index.js +1 -3
- package/utils/upsert-utils.d.ts +9 -4
- package/utils/upsert-utils.js +51 -5
- package/decorators/Check.d.ts +0 -3
- package/decorators/Check.js +0 -13
- package/decorators/CreateRequestContext.d.ts +0 -3
- package/decorators/CreateRequestContext.js +0 -32
- package/decorators/Embeddable.d.ts +0 -8
- package/decorators/Embeddable.js +0 -11
- package/decorators/Embedded.d.ts +0 -12
- package/decorators/Embedded.js +0 -18
- package/decorators/Entity.d.ts +0 -33
- package/decorators/Entity.js +0 -12
- package/decorators/Enum.d.ts +0 -9
- package/decorators/Enum.js +0 -16
- package/decorators/Filter.d.ts +0 -2
- package/decorators/Filter.js +0 -8
- package/decorators/Formula.d.ts +0 -4
- package/decorators/Formula.js +0 -15
- package/decorators/Indexed.d.ts +0 -19
- package/decorators/Indexed.js +0 -20
- package/decorators/ManyToMany.d.ts +0 -42
- package/decorators/ManyToMany.js +0 -14
- package/decorators/ManyToOne.d.ts +0 -34
- package/decorators/ManyToOne.js +0 -14
- package/decorators/OneToMany.d.ts +0 -28
- package/decorators/OneToMany.js +0 -17
- package/decorators/OneToOne.d.ts +0 -28
- package/decorators/OneToOne.js +0 -7
- package/decorators/PrimaryKey.d.ts +0 -8
- package/decorators/PrimaryKey.js +0 -20
- package/decorators/Property.d.ts +0 -250
- package/decorators/Property.js +0 -32
- package/decorators/Transactional.d.ts +0 -14
- package/decorators/Transactional.js +0 -28
- package/decorators/hooks.d.ts +0 -16
- package/decorators/hooks.js +0 -47
- package/decorators/index.d.ts +0 -17
- package/decorators/index.js +0 -17
- package/entity/ArrayCollection.d.ts +0 -118
- package/entity/ArrayCollection.js +0 -407
- package/entity/EntityValidator.d.ts +0 -19
- package/entity/EntityValidator.js +0 -150
- package/metadata/ReflectMetadataProvider.d.ts +0 -8
- package/metadata/ReflectMetadataProvider.js +0 -44
- package/utils/resolveContextProvider.d.ts +0 -10
- package/utils/resolveContextProvider.js +0 -28
|
@@ -1,25 +1,18 @@
|
|
|
1
|
-
import { EntityMetadata, type AnyEntity, type EntityKey, type Constructor, type DeepPartial, type EntityName, type EntityProperty, type CleanKeys, type ExpandProperty, type IsNever, type
|
|
2
|
-
import type
|
|
3
|
-
import type {
|
|
4
|
-
import type { IndexOptions, UniqueOptions } from '../decorators/Indexed.js';
|
|
5
|
-
import type { ManyToManyOptions } from '../decorators/ManyToMany.js';
|
|
6
|
-
import type { ManyToOneOptions } from '../decorators/ManyToOne.js';
|
|
7
|
-
import type { OneToManyOptions } from '../decorators/OneToMany.js';
|
|
8
|
-
import type { OneToOneOptions } from '../decorators/OneToOne.js';
|
|
9
|
-
import type { PrimaryKeyOptions, SerializedPrimaryKeyOptions } from '../decorators/PrimaryKey.js';
|
|
10
|
-
import type { PropertyOptions } from '../decorators/Property.js';
|
|
11
|
-
import { ReferenceKind } from '../enums.js';
|
|
1
|
+
import { EntityMetadata, type AnyEntity, type EntityKey, type Constructor, type DeepPartial, type EntityName, type EntityProperty, type CleanKeys, type ExpandProperty, type IsNever, type EntityCtor } from '../typings.js';
|
|
2
|
+
import { type EventType, ReferenceKind } from '../enums.js';
|
|
3
|
+
import type { EventArgs } from '../events/EventSubscriber.js';
|
|
12
4
|
import { Type } from '../types/Type.js';
|
|
5
|
+
import type { PropertyOptions, ManyToOneOptions, OneToOneOptions, OneToManyOptions, ManyToManyOptions, EmbeddedOptions, EnumOptions, PrimaryKeyOptions, SerializedPrimaryKeyOptions, IndexOptions, UniqueOptions } from './types.js';
|
|
13
6
|
type TypeType = string | NumberConstructor | StringConstructor | BooleanConstructor | DateConstructor | ArrayConstructor | Constructor<Type<any>> | Type<any>;
|
|
14
7
|
type TypeDef<Target> = {
|
|
15
8
|
type: TypeType;
|
|
16
9
|
} | {
|
|
17
|
-
entity:
|
|
10
|
+
entity: () => EntityName<Target> | EntityName[];
|
|
18
11
|
};
|
|
19
12
|
type EmbeddedTypeDef<Target> = {
|
|
20
13
|
type: TypeType;
|
|
21
14
|
} | {
|
|
22
|
-
entity:
|
|
15
|
+
entity: () => EntityName<Target> | EntityName[];
|
|
23
16
|
};
|
|
24
17
|
export type EntitySchemaProperty<Target, Owner> = ({
|
|
25
18
|
kind: ReferenceKind.MANY_TO_ONE | 'm:1';
|
|
@@ -35,28 +28,32 @@ export type EntitySchemaProperty<Target, Owner> = ({
|
|
|
35
28
|
enum: true;
|
|
36
29
|
} & EnumOptions<Owner>) | (TypeDef<Target> & PropertyOptions<Owner>);
|
|
37
30
|
type OmitBaseProps<Entity, Base> = IsNever<Base> extends true ? Entity : Omit<Entity, keyof Base>;
|
|
38
|
-
export type EntitySchemaMetadata<Entity, Base = never
|
|
31
|
+
export type EntitySchemaMetadata<Entity, Base = never, Class extends EntityCtor = EntityCtor<Entity>> = Omit<Partial<EntityMetadata<Entity>>, 'name' | 'properties' | 'extends'> & ({
|
|
39
32
|
name: string;
|
|
40
33
|
} | {
|
|
41
|
-
class:
|
|
34
|
+
class: Class;
|
|
42
35
|
name?: string;
|
|
43
36
|
}) & {
|
|
44
|
-
extends?:
|
|
37
|
+
extends?: EntityName<Base>;
|
|
45
38
|
} & {
|
|
46
39
|
properties?: {
|
|
47
40
|
[Key in keyof OmitBaseProps<Entity, Base> as CleanKeys<OmitBaseProps<Entity, Base>, Key>]-?: EntitySchemaProperty<ExpandProperty<NonNullable<Entity[Key]>>, Entity>;
|
|
48
41
|
};
|
|
42
|
+
} & {
|
|
43
|
+
inheritance?: 'tpt';
|
|
49
44
|
};
|
|
50
|
-
export declare class EntitySchema<Entity = any, Base = never
|
|
45
|
+
export declare class EntitySchema<Entity = any, Base = never, Class extends EntityCtor = EntityCtor<Entity>> {
|
|
51
46
|
/**
|
|
52
47
|
* When schema links the entity class via `class` option, this registry allows the lookup from opposite side,
|
|
53
48
|
* so we can use the class in `entities` option just like the EntitySchema instance.
|
|
54
49
|
*/
|
|
55
|
-
static REGISTRY: Map<Partial<any>, EntitySchema<any, never
|
|
50
|
+
static REGISTRY: Map<Partial<any>, EntitySchema<any, never, EntityCtor<any>>>;
|
|
51
|
+
/** @internal Type-level marker for fast entity type inference */
|
|
52
|
+
readonly '~entity': Entity;
|
|
56
53
|
private readonly _meta;
|
|
57
54
|
private internal;
|
|
58
55
|
private initialized;
|
|
59
|
-
constructor(meta: EntitySchemaMetadata<Entity, Base>);
|
|
56
|
+
constructor(meta: EntitySchemaMetadata<Entity, Base, Class>);
|
|
60
57
|
static fromMetadata<T = AnyEntity, U = never>(meta: EntityMetadata<T> | DeepPartial<EntityMetadata<T>>): EntitySchema<T, U>;
|
|
61
58
|
addProperty(name: EntityKey<Entity>, type?: TypeType, options?: PropertyOptions<Entity> | EntityProperty<Entity>): void;
|
|
62
59
|
addEnum(name: EntityKey<Entity>, type?: TypeType, options?: EnumOptions<Entity>): void;
|
|
@@ -71,19 +68,46 @@ export declare class EntitySchema<Entity = any, Base = never> {
|
|
|
71
68
|
addIndex<Key extends string>(options: IndexOptions<Entity, Key>): void;
|
|
72
69
|
addUnique<Key extends string>(options: UniqueOptions<Entity, Key>): void;
|
|
73
70
|
setCustomRepository(repository: () => Constructor): void;
|
|
74
|
-
setExtends(base:
|
|
75
|
-
setClass(
|
|
76
|
-
get meta(): EntityMetadata<Entity>;
|
|
77
|
-
get name(): EntityName<Entity>;
|
|
71
|
+
setExtends(base: EntityName): void;
|
|
72
|
+
setClass(cls: Class): void;
|
|
73
|
+
get meta(): EntityMetadata<Entity, Class>;
|
|
74
|
+
get name(): string | EntityName<Entity>;
|
|
75
|
+
get tableName(): string;
|
|
76
|
+
get class(): Class;
|
|
77
|
+
get properties(): Record<string, any>;
|
|
78
|
+
new(...params: ConstructorParameters<Class>): Entity;
|
|
78
79
|
/**
|
|
79
80
|
* @internal
|
|
80
81
|
*/
|
|
81
82
|
init(): this;
|
|
83
|
+
/**
|
|
84
|
+
* Check if this entity is part of a TPT hierarchy by walking up the extends chain.
|
|
85
|
+
* This handles mid-level abstract entities (e.g., Animal -> Mammal -> Dog where Mammal is abstract).
|
|
86
|
+
*/
|
|
87
|
+
private isPartOfTPTHierarchy;
|
|
82
88
|
private initProperties;
|
|
83
89
|
private initPrimaryKeys;
|
|
84
90
|
private normalizeType;
|
|
85
91
|
private createProperty;
|
|
86
92
|
private rename;
|
|
87
93
|
private renameCompositeOptions;
|
|
94
|
+
/**
|
|
95
|
+
* Adds a lifecycle hook handler to the entity schema.
|
|
96
|
+
* This method allows registering hooks after the entity is defined,
|
|
97
|
+
* which can be useful for avoiding circular type references.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* export const Article = defineEntity({
|
|
102
|
+
* name: 'Article',
|
|
103
|
+
* properties: { ... },
|
|
104
|
+
* });
|
|
105
|
+
*
|
|
106
|
+
* Article.addHook('beforeCreate', async args => {
|
|
107
|
+
* args.entity.slug = args.entity.title.toLowerCase();
|
|
108
|
+
* });
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
addHook<T extends Entity = Entity>(event: EventType | `${EventType}`, handler: (args: EventArgs<T>) => void | Promise<void>): this;
|
|
88
112
|
}
|
|
89
113
|
export {};
|
package/metadata/EntitySchema.js
CHANGED
|
@@ -10,7 +10,7 @@ export class EntitySchema {
|
|
|
10
10
|
* so we can use the class in `entities` option just like the EntitySchema instance.
|
|
11
11
|
*/
|
|
12
12
|
static REGISTRY = new Map();
|
|
13
|
-
_meta
|
|
13
|
+
_meta;
|
|
14
14
|
internal = false;
|
|
15
15
|
initialized = false;
|
|
16
16
|
constructor(meta) {
|
|
@@ -18,15 +18,14 @@ export class EntitySchema {
|
|
|
18
18
|
if (meta.name) {
|
|
19
19
|
meta.abstract ??= false;
|
|
20
20
|
}
|
|
21
|
+
this._meta = new EntityMetadata({
|
|
22
|
+
className: meta.name,
|
|
23
|
+
...meta,
|
|
24
|
+
});
|
|
25
|
+
this._meta.root ??= this._meta;
|
|
21
26
|
if (meta.class && !meta.internal) {
|
|
22
27
|
EntitySchema.REGISTRY.set(meta.class, this);
|
|
23
28
|
}
|
|
24
|
-
if (meta.tableName || meta.collection) {
|
|
25
|
-
Utils.renameKey(meta, 'tableName', 'collection');
|
|
26
|
-
meta.tableName = meta.collection;
|
|
27
|
-
}
|
|
28
|
-
Object.assign(this._meta, { className: meta.name }, meta);
|
|
29
|
-
this._meta.root ??= this._meta;
|
|
30
29
|
}
|
|
31
30
|
static fromMetadata(meta) {
|
|
32
31
|
const schema = new EntitySchema({ ...meta, internal: true });
|
|
@@ -35,12 +34,17 @@ export class EntitySchema {
|
|
|
35
34
|
}
|
|
36
35
|
addProperty(name, type, options = {}) {
|
|
37
36
|
this.renameCompositeOptions(name, options);
|
|
38
|
-
const prop = {
|
|
37
|
+
const prop = {
|
|
38
|
+
name,
|
|
39
|
+
kind: ReferenceKind.SCALAR,
|
|
40
|
+
...options,
|
|
41
|
+
...this.normalizeType(options, type),
|
|
42
|
+
};
|
|
39
43
|
if (type && Type.isMappedType(type.prototype)) {
|
|
40
44
|
prop.type = type;
|
|
41
45
|
}
|
|
42
|
-
if (
|
|
43
|
-
const formula = prop.formula;
|
|
46
|
+
if (typeof prop.formula === 'string') {
|
|
47
|
+
const formula = prop.formula;
|
|
44
48
|
prop.formula = () => formula;
|
|
45
49
|
}
|
|
46
50
|
if (prop.formula) {
|
|
@@ -75,7 +79,7 @@ export class EntitySchema {
|
|
|
75
79
|
}
|
|
76
80
|
addSerializedPrimaryKey(name, type, options = {}) {
|
|
77
81
|
this._meta.serializedPrimaryKey = name;
|
|
78
|
-
this.addProperty(name, type, options);
|
|
82
|
+
this.addProperty(name, type, { serializedPrimaryKey: true, ...options });
|
|
79
83
|
}
|
|
80
84
|
addEmbedded(name, options) {
|
|
81
85
|
this.renameCompositeOptions(name, options);
|
|
@@ -85,8 +89,8 @@ export class EntitySchema {
|
|
|
85
89
|
}
|
|
86
90
|
this._meta.properties[name] = {
|
|
87
91
|
name,
|
|
88
|
-
type: this.normalizeType(options),
|
|
89
92
|
kind: ReferenceKind.EMBEDDED,
|
|
93
|
+
...this.normalizeType(options),
|
|
90
94
|
...options,
|
|
91
95
|
};
|
|
92
96
|
}
|
|
@@ -151,21 +155,29 @@ export class EntitySchema {
|
|
|
151
155
|
setExtends(base) {
|
|
152
156
|
this._meta.extends = base;
|
|
153
157
|
}
|
|
154
|
-
setClass(
|
|
155
|
-
const
|
|
156
|
-
this._meta.class
|
|
157
|
-
this._meta.
|
|
158
|
-
this._meta.
|
|
158
|
+
setClass(cls) {
|
|
159
|
+
const oldClass = this._meta.class;
|
|
160
|
+
const sameClass = this._meta.class === cls;
|
|
161
|
+
this._meta.class = cls;
|
|
162
|
+
this._meta.prototype = cls.prototype;
|
|
163
|
+
this._meta.className = this._meta.name ?? cls.name;
|
|
159
164
|
if (!sameClass || !this._meta.constructorParams) {
|
|
160
|
-
|
|
161
|
-
this._meta.constructorParams = Utils.getParamNames(tokens, 'constructor');
|
|
162
|
-
this._meta.toJsonParams = Utils.getParamNames(tokens, 'toJSON').filter(p => p !== '...args');
|
|
165
|
+
this._meta.constructorParams = Utils.getConstructorParams(cls);
|
|
163
166
|
}
|
|
164
167
|
if (!this.internal) {
|
|
165
|
-
|
|
168
|
+
// Remove old class from registry if it's being replaced with a different class
|
|
169
|
+
if (oldClass && oldClass !== cls && EntitySchema.REGISTRY.get(oldClass) === this) {
|
|
170
|
+
EntitySchema.REGISTRY.delete(oldClass);
|
|
171
|
+
}
|
|
172
|
+
EntitySchema.REGISTRY.set(cls, this);
|
|
166
173
|
}
|
|
167
|
-
|
|
168
|
-
|
|
174
|
+
const base = Object.getPrototypeOf(cls);
|
|
175
|
+
// Only set extends if the parent is NOT the auto-generated class for this same entity.
|
|
176
|
+
// When the user extends the auto-generated class (from defineEntity without a class option)
|
|
177
|
+
// and registers their custom class via setClass, we don't want to discover the
|
|
178
|
+
// auto-generated class as a separate parent entity.
|
|
179
|
+
if (base !== BaseEntity && base.name !== this._meta.className) {
|
|
180
|
+
this._meta.extends ??= base.name ? base : undefined;
|
|
169
181
|
}
|
|
170
182
|
}
|
|
171
183
|
get meta() {
|
|
@@ -174,6 +186,18 @@ export class EntitySchema {
|
|
|
174
186
|
get name() {
|
|
175
187
|
return this._meta.className;
|
|
176
188
|
}
|
|
189
|
+
get tableName() {
|
|
190
|
+
return this._meta.tableName;
|
|
191
|
+
}
|
|
192
|
+
get class() {
|
|
193
|
+
return this._meta.class;
|
|
194
|
+
}
|
|
195
|
+
get properties() {
|
|
196
|
+
return this._meta.properties;
|
|
197
|
+
}
|
|
198
|
+
new(...params) {
|
|
199
|
+
return new this._meta.class(...params);
|
|
200
|
+
}
|
|
177
201
|
/**
|
|
178
202
|
* @internal
|
|
179
203
|
*/
|
|
@@ -181,19 +205,16 @@ export class EntitySchema {
|
|
|
181
205
|
if (this.initialized) {
|
|
182
206
|
return this;
|
|
183
207
|
}
|
|
184
|
-
if (!this._meta.class) {
|
|
185
|
-
const name = this.name;
|
|
186
|
-
this._meta.class = ({ [name]: class {
|
|
187
|
-
} })[name];
|
|
188
|
-
}
|
|
189
208
|
this.setClass(this._meta.class);
|
|
190
|
-
|
|
209
|
+
// Abstract TPT entities keep their name because they have their own table
|
|
210
|
+
const isTPT = this._meta.inheritance === 'tpt' || this.isPartOfTPTHierarchy();
|
|
211
|
+
if (this._meta.abstract && !this._meta.discriminatorColumn && !isTPT) {
|
|
191
212
|
delete this._meta.name;
|
|
192
213
|
}
|
|
193
214
|
const tableName = this._meta.collection ?? this._meta.tableName;
|
|
194
215
|
if (tableName?.includes('.') && !this._meta.schema) {
|
|
195
216
|
this._meta.schema = tableName.substring(0, tableName.indexOf('.'));
|
|
196
|
-
this._meta.
|
|
217
|
+
this._meta.tableName = tableName.substring(tableName.indexOf('.') + 1);
|
|
197
218
|
}
|
|
198
219
|
this.initProperties();
|
|
199
220
|
this.initPrimaryKeys();
|
|
@@ -202,6 +223,24 @@ export class EntitySchema {
|
|
|
202
223
|
this.initialized = true;
|
|
203
224
|
return this;
|
|
204
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Check if this entity is part of a TPT hierarchy by walking up the extends chain.
|
|
228
|
+
* This handles mid-level abstract entities (e.g., Animal -> Mammal -> Dog where Mammal is abstract).
|
|
229
|
+
*/
|
|
230
|
+
isPartOfTPTHierarchy() {
|
|
231
|
+
let parent = this._meta.extends;
|
|
232
|
+
while (parent) {
|
|
233
|
+
const parentSchema = parent instanceof EntitySchema ? parent : EntitySchema.REGISTRY.get(parent);
|
|
234
|
+
if (!parentSchema) {
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
if (parentSchema._meta.inheritance === 'tpt') {
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
parent = parentSchema._meta.extends;
|
|
241
|
+
}
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
205
244
|
initProperties() {
|
|
206
245
|
Utils.entries(this._meta.properties).forEach(([name, options]) => {
|
|
207
246
|
if (Type.isMappedType(options.type)) {
|
|
@@ -259,12 +298,20 @@ export class EntitySchema {
|
|
|
259
298
|
}
|
|
260
299
|
normalizeType(options, type) {
|
|
261
300
|
if ('entity' in options) {
|
|
262
|
-
|
|
263
|
-
|
|
301
|
+
/* v8 ignore next */
|
|
302
|
+
if (typeof options.entity === 'string') {
|
|
303
|
+
throw new Error(`Relation target needs to be an entity class or EntitySchema instance, string '${options.entity}' given instead for ${this._meta.className}.${options.name}.`);
|
|
264
304
|
}
|
|
265
305
|
else if (options.entity) {
|
|
266
306
|
const tmp = options.entity();
|
|
267
|
-
type = options.type = Array.isArray(tmp)
|
|
307
|
+
type = options.type = Array.isArray(tmp)
|
|
308
|
+
? tmp
|
|
309
|
+
.map(t => Utils.className(t))
|
|
310
|
+
.sort()
|
|
311
|
+
.join(' | ')
|
|
312
|
+
: Utils.className(tmp);
|
|
313
|
+
const target = tmp instanceof EntitySchema ? tmp.meta.class : tmp;
|
|
314
|
+
return { type, target };
|
|
268
315
|
}
|
|
269
316
|
}
|
|
270
317
|
if (type instanceof Function) {
|
|
@@ -273,7 +320,7 @@ export class EntitySchema {
|
|
|
273
320
|
if (['String', 'Number', 'Boolean', 'Array'].includes(type)) {
|
|
274
321
|
type = type.toLowerCase();
|
|
275
322
|
}
|
|
276
|
-
return type;
|
|
323
|
+
return { type };
|
|
277
324
|
}
|
|
278
325
|
createProperty(kind, options) {
|
|
279
326
|
return {
|
|
@@ -303,4 +350,26 @@ export class EntitySchema {
|
|
|
303
350
|
this.rename(options, 'referenceColumnName', 'referencedColumnNames');
|
|
304
351
|
this.rename(options, 'columnType', 'columnTypes');
|
|
305
352
|
}
|
|
353
|
+
/**
|
|
354
|
+
* Adds a lifecycle hook handler to the entity schema.
|
|
355
|
+
* This method allows registering hooks after the entity is defined,
|
|
356
|
+
* which can be useful for avoiding circular type references.
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* ```ts
|
|
360
|
+
* export const Article = defineEntity({
|
|
361
|
+
* name: 'Article',
|
|
362
|
+
* properties: { ... },
|
|
363
|
+
* });
|
|
364
|
+
*
|
|
365
|
+
* Article.addHook('beforeCreate', async args => {
|
|
366
|
+
* args.entity.slug = args.entity.title.toLowerCase();
|
|
367
|
+
* });
|
|
368
|
+
* ```
|
|
369
|
+
*/
|
|
370
|
+
addHook(event, handler) {
|
|
371
|
+
this._meta.hooks[event] ??= [];
|
|
372
|
+
this._meta.hooks[event].push(handler);
|
|
373
|
+
return this;
|
|
374
|
+
}
|
|
306
375
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type EntityClass, EntityMetadata, type EntityName } from '../typings.js';
|
|
2
2
|
import type { Configuration } from '../utils/Configuration.js';
|
|
3
3
|
import { MetadataStorage } from './MetadataStorage.js';
|
|
4
4
|
import { EntitySchema } from './EntitySchema.js';
|
|
@@ -9,26 +9,24 @@ export declare class MetadataDiscovery {
|
|
|
9
9
|
private readonly config;
|
|
10
10
|
private readonly namingStrategy;
|
|
11
11
|
private readonly metadataProvider;
|
|
12
|
-
private readonly cache;
|
|
13
12
|
private readonly logger;
|
|
14
13
|
private readonly schemaHelper;
|
|
15
14
|
private readonly validator;
|
|
16
15
|
private readonly discovered;
|
|
17
16
|
constructor(metadata: MetadataStorage, platform: Platform, config: Configuration);
|
|
18
17
|
discover(preferTs?: boolean): Promise<MetadataStorage>;
|
|
19
|
-
discoverSync(
|
|
18
|
+
discoverSync(): MetadataStorage;
|
|
20
19
|
private mapDiscoveredEntities;
|
|
20
|
+
private initAccessors;
|
|
21
21
|
processDiscoveredEntities(discovered: EntityMetadata[]): EntityMetadata[];
|
|
22
22
|
private findEntities;
|
|
23
23
|
private discoverMissingTargets;
|
|
24
24
|
private tryDiscoverTargets;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
reset(className: string): void;
|
|
28
|
-
private prepare;
|
|
25
|
+
discoverReferences<T>(refs: Iterable<EntityClass<T> | EntitySchema<T>>, validate?: boolean): EntityMetadata<T>[];
|
|
26
|
+
reset<T>(entityName: EntityName<T>): void;
|
|
29
27
|
private getSchema;
|
|
28
|
+
private getRootEntity;
|
|
30
29
|
private discoverEntity;
|
|
31
|
-
private saveToCache;
|
|
32
30
|
private initNullability;
|
|
33
31
|
private applyNamingStrategy;
|
|
34
32
|
private initOwnColumns;
|
|
@@ -36,6 +34,7 @@ export declare class MetadataDiscovery {
|
|
|
36
34
|
private initManyToOneFieldName;
|
|
37
35
|
private initManyToManyFieldName;
|
|
38
36
|
private initManyToManyFields;
|
|
37
|
+
private isExplicitTableName;
|
|
39
38
|
private initManyToOneFields;
|
|
40
39
|
private initOneToManyFields;
|
|
41
40
|
private processEntity;
|
|
@@ -43,15 +42,72 @@ export declare class MetadataDiscovery {
|
|
|
43
42
|
private initFactoryField;
|
|
44
43
|
private ensureCorrectFKOrderInPivotEntity;
|
|
45
44
|
private definePivotTableEntity;
|
|
45
|
+
/**
|
|
46
|
+
* Create a scalar property for a pivot table column.
|
|
47
|
+
*/
|
|
48
|
+
private createPivotScalarProperty;
|
|
49
|
+
/**
|
|
50
|
+
* Get column types for an entity's primary keys, initializing them if needed.
|
|
51
|
+
*/
|
|
52
|
+
private getPrimaryKeyColumnTypes;
|
|
53
|
+
/**
|
|
54
|
+
* Add missing FK columns for a polymorphic entity to an existing pivot table.
|
|
55
|
+
*/
|
|
56
|
+
private addPolymorphicPivotColumns;
|
|
57
|
+
/**
|
|
58
|
+
* Define properties for a polymorphic pivot table.
|
|
59
|
+
*/
|
|
60
|
+
private definePolymorphicPivotProperties;
|
|
61
|
+
/**
|
|
62
|
+
* Create a virtual M:1 relation from pivot to a polymorphic owner entity.
|
|
63
|
+
* This enables single-query join loading for inverse-side polymorphic M:N.
|
|
64
|
+
*/
|
|
65
|
+
private definePolymorphicOwnerRelation;
|
|
46
66
|
private defineFixedOrderProperty;
|
|
47
67
|
private definePivotProperty;
|
|
48
68
|
private autoWireBidirectionalProperties;
|
|
49
69
|
private defineBaseEntityProperties;
|
|
50
70
|
private initPolyEmbeddables;
|
|
71
|
+
private initPolymorphicRelation;
|
|
51
72
|
private initEmbeddables;
|
|
52
73
|
private initSingleTableInheritance;
|
|
74
|
+
/**
|
|
75
|
+
* First pass of TPT initialization: sets up hierarchy relationships
|
|
76
|
+
* (inheritanceType, tptParent, tptChildren) before properties have fieldNames.
|
|
77
|
+
*/
|
|
78
|
+
private initTPTRelationships;
|
|
79
|
+
/**
|
|
80
|
+
* Second pass of TPT initialization: re-resolves metadata references after fieldNames
|
|
81
|
+
* are set, syncs to registry metadata, and sets up discriminators.
|
|
82
|
+
*/
|
|
83
|
+
private finalizeTPTInheritance;
|
|
84
|
+
/**
|
|
85
|
+
* Initialize TPT discriminator map and virtual discriminator property.
|
|
86
|
+
* Unlike STI where the discriminator is a persisted column, TPT discriminator is computed
|
|
87
|
+
* at query time using CASE WHEN expressions based on which child table has data.
|
|
88
|
+
*/
|
|
89
|
+
private initTPTDiscriminator;
|
|
90
|
+
/**
|
|
91
|
+
* Recursively collect all TPT descendants (children, grandchildren, etc.)
|
|
92
|
+
*/
|
|
93
|
+
private collectAllTPTDescendants;
|
|
94
|
+
/**
|
|
95
|
+
* Computes ownProps for TPT entities - only properties defined in THIS entity,
|
|
96
|
+
* not inherited from parent. Also creates synthetic join properties for parent/child relationships.
|
|
97
|
+
*
|
|
98
|
+
* Called multiple times during discovery as metadata is progressively built.
|
|
99
|
+
* Each pass overwrites earlier results to reflect the final state of properties.
|
|
100
|
+
*/
|
|
101
|
+
private computeTPTOwnProps;
|
|
102
|
+
/** Returns the depth of a TPT entity in its hierarchy (0 for root). */
|
|
103
|
+
private getTPTDepth;
|
|
104
|
+
/**
|
|
105
|
+
* Find the direct TPT parent entity for the given entity.
|
|
106
|
+
*/
|
|
107
|
+
private getTPTParent;
|
|
53
108
|
private createDiscriminatorProperty;
|
|
54
109
|
private initAutoincrement;
|
|
110
|
+
private createSchemaTable;
|
|
55
111
|
private initCheckConstraints;
|
|
56
112
|
private initGeneratedColumn;
|
|
57
113
|
private getDefaultVersionValue;
|
|
@@ -66,6 +122,5 @@ export declare class MetadataDiscovery {
|
|
|
66
122
|
private getPrefix;
|
|
67
123
|
private initUnsigned;
|
|
68
124
|
private initIndexes;
|
|
69
|
-
private getEntityClassOrSchema;
|
|
70
125
|
private shouldForceConstructorUsage;
|
|
71
126
|
}
|