@mikro-orm/core 7.0.0-dev.3 → 7.0.0-dev.300
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 +114 -63
- package/EntityManager.js +385 -310
- package/MikroORM.d.ts +44 -35
- package/MikroORM.js +109 -143
- package/README.md +3 -2
- package/cache/FileCacheAdapter.d.ts +1 -1
- package/cache/FileCacheAdapter.js +17 -8
- package/cache/GeneratedCacheAdapter.d.ts +0 -1
- package/cache/GeneratedCacheAdapter.js +0 -2
- package/cache/index.d.ts +0 -1
- package/cache/index.js +0 -1
- package/connections/Connection.d.ts +16 -7
- package/connections/Connection.js +23 -14
- package/drivers/DatabaseDriver.d.ts +25 -16
- package/drivers/DatabaseDriver.js +119 -36
- package/drivers/IDatabaseDriver.d.ts +125 -23
- package/entity/BaseEntity.d.ts +63 -4
- package/entity/BaseEntity.js +0 -3
- package/entity/Collection.d.ts +102 -31
- package/entity/Collection.js +446 -108
- package/entity/EntityAssigner.d.ts +1 -1
- package/entity/EntityAssigner.js +26 -18
- package/entity/EntityFactory.d.ts +13 -1
- package/entity/EntityFactory.js +106 -60
- package/entity/EntityHelper.d.ts +2 -2
- package/entity/EntityHelper.js +65 -20
- package/entity/EntityLoader.d.ts +13 -11
- package/entity/EntityLoader.js +257 -107
- 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 +9 -12
- package/entity/Reference.js +34 -9
- package/entity/WrappedEntity.d.ts +3 -8
- package/entity/WrappedEntity.js +3 -8
- package/entity/defineEntity.d.ts +753 -0
- package/entity/defineEntity.js +537 -0
- package/entity/index.d.ts +4 -2
- package/entity/index.js +4 -2
- package/entity/utils.d.ts +13 -1
- package/entity/utils.js +49 -4
- package/entity/validators.d.ts +11 -0
- package/entity/validators.js +65 -0
- package/enums.d.ts +23 -8
- package/enums.js +15 -1
- package/errors.d.ts +25 -9
- package/errors.js +67 -21
- package/events/EventManager.d.ts +2 -1
- package/events/EventManager.js +19 -11
- package/events/EventSubscriber.d.ts +3 -1
- package/hydration/Hydrator.js +1 -2
- package/hydration/ObjectHydrator.d.ts +4 -4
- package/hydration/ObjectHydrator.js +89 -36
- package/index.d.ts +2 -2
- package/index.js +1 -2
- package/logging/DefaultLogger.d.ts +1 -1
- package/logging/DefaultLogger.js +1 -0
- package/logging/SimpleLogger.d.ts +1 -1
- package/logging/colors.d.ts +1 -1
- package/logging/colors.js +7 -6
- package/logging/index.d.ts +1 -0
- package/logging/index.js +1 -0
- package/logging/inspect.d.ts +2 -0
- package/logging/inspect.js +11 -0
- package/metadata/EntitySchema.d.ts +53 -27
- package/metadata/EntitySchema.js +125 -52
- package/metadata/MetadataDiscovery.d.ts +64 -10
- package/metadata/MetadataDiscovery.js +823 -344
- package/metadata/MetadataProvider.d.ts +11 -2
- package/metadata/MetadataProvider.js +66 -2
- package/metadata/MetadataStorage.d.ts +13 -11
- package/metadata/MetadataStorage.js +71 -38
- package/metadata/MetadataValidator.d.ts +32 -9
- package/metadata/MetadataValidator.js +198 -42
- 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 +1 -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 +20 -2
- 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/not-supported.d.ts +2 -0
- package/not-supported.js +4 -0
- package/package.json +22 -11
- package/platforms/ExceptionConverter.js +1 -1
- package/platforms/Platform.d.ts +14 -16
- package/platforms/Platform.js +24 -44
- package/serialization/EntitySerializer.d.ts +8 -3
- package/serialization/EntitySerializer.js +47 -27
- package/serialization/EntityTransformer.js +33 -21
- package/serialization/SerializationContext.d.ts +6 -6
- package/serialization/SerializationContext.js +16 -13
- package/types/ArrayType.d.ts +1 -1
- package/types/ArrayType.js +2 -3
- package/types/BigIntType.d.ts +9 -6
- package/types/BigIntType.js +4 -1
- package/types/BlobType.d.ts +0 -1
- package/types/BlobType.js +0 -3
- package/types/BooleanType.d.ts +2 -1
- package/types/BooleanType.js +3 -0
- package/types/DecimalType.d.ts +6 -4
- package/types/DecimalType.js +3 -3
- package/types/DoubleType.js +2 -2
- 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/index.d.ts +1 -1
- package/typings.d.ts +469 -175
- package/typings.js +120 -45
- package/unit-of-work/ChangeSet.d.ts +4 -6
- package/unit-of-work/ChangeSet.js +4 -5
- package/unit-of-work/ChangeSetComputer.d.ts +3 -8
- package/unit-of-work/ChangeSetComputer.js +44 -21
- package/unit-of-work/ChangeSetPersister.d.ts +15 -12
- package/unit-of-work/ChangeSetPersister.js +113 -45
- package/unit-of-work/CommitOrderCalculator.d.ts +12 -10
- package/unit-of-work/CommitOrderCalculator.js +13 -13
- package/unit-of-work/IdentityMap.d.ts +12 -0
- package/unit-of-work/IdentityMap.js +39 -1
- package/unit-of-work/UnitOfWork.d.ts +28 -3
- package/unit-of-work/UnitOfWork.js +315 -110
- package/utils/AbstractMigrator.d.ts +101 -0
- package/utils/AbstractMigrator.js +305 -0
- package/utils/AbstractSchemaGenerator.d.ts +5 -5
- package/utils/AbstractSchemaGenerator.js +32 -18
- package/utils/AsyncContext.d.ts +6 -0
- package/utils/AsyncContext.js +42 -0
- package/utils/Configuration.d.ts +801 -207
- package/utils/Configuration.js +150 -191
- package/utils/ConfigurationLoader.d.ts +1 -54
- package/utils/ConfigurationLoader.js +1 -352
- package/utils/Cursor.d.ts +3 -6
- package/utils/Cursor.js +27 -11
- package/utils/DataloaderUtils.d.ts +15 -5
- package/utils/DataloaderUtils.js +65 -17
- package/utils/EntityComparator.d.ts +21 -10
- package/utils/EntityComparator.js +243 -106
- package/utils/QueryHelper.d.ts +24 -6
- package/utils/QueryHelper.js +122 -26
- package/utils/RawQueryFragment.d.ts +60 -32
- package/utils/RawQueryFragment.js +69 -66
- package/utils/RequestContext.js +2 -2
- package/utils/TransactionContext.js +2 -2
- package/utils/TransactionManager.d.ts +65 -0
- package/utils/TransactionManager.js +223 -0
- package/utils/Utils.d.ts +15 -122
- package/utils/Utils.js +108 -376
- package/utils/clone.js +8 -23
- package/utils/env-vars.d.ts +7 -0
- package/utils/env-vars.js +97 -0
- package/utils/fs-utils.d.ts +34 -0
- package/utils/fs-utils.js +196 -0
- package/utils/index.d.ts +2 -3
- package/utils/index.js +2 -3
- package/utils/upsert-utils.d.ts +9 -4
- package/utils/upsert-utils.js +55 -4
- 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 -18
- package/decorators/Embedded.js +0 -18
- package/decorators/Entity.d.ts +0 -18
- package/decorators/Entity.js +0 -13
- 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 -5
- package/decorators/Formula.js +0 -15
- package/decorators/Indexed.d.ts +0 -17
- package/decorators/Indexed.js +0 -20
- package/decorators/ManyToMany.d.ts +0 -40
- package/decorators/ManyToMany.js +0 -14
- package/decorators/ManyToOne.d.ts +0 -30
- 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 -24
- package/decorators/OneToOne.js +0 -7
- package/decorators/PrimaryKey.d.ts +0 -9
- 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 -13
- 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 -116
- package/entity/ArrayCollection.js +0 -395
- 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
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 });
|
|
@@ -34,29 +33,13 @@ export class EntitySchema {
|
|
|
34
33
|
return schema;
|
|
35
34
|
}
|
|
36
35
|
addProperty(name, type, options = {}) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// @ts-ignore
|
|
40
|
-
options[to] = [options[from]];
|
|
41
|
-
// @ts-ignore
|
|
42
|
-
delete options[from];
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
if (name !== options.name) {
|
|
46
|
-
Utils.renameKey(options, 'name', 'fieldName');
|
|
47
|
-
}
|
|
48
|
-
rename(options, 'fieldName', 'fieldNames');
|
|
49
|
-
rename(options, 'ref', 'ref');
|
|
50
|
-
rename(options, 'joinColumn', 'joinColumns');
|
|
51
|
-
rename(options, 'inverseJoinColumn', 'inverseJoinColumns');
|
|
52
|
-
rename(options, 'referenceColumnName', 'referencedColumnNames');
|
|
53
|
-
rename(options, 'columnType', 'columnTypes');
|
|
54
|
-
const prop = { name, kind: ReferenceKind.SCALAR, ...options, type: this.normalizeType(options, type) };
|
|
36
|
+
this.renameCompositeOptions(name, options);
|
|
37
|
+
const prop = { name, kind: ReferenceKind.SCALAR, ...options, ...this.normalizeType(options, type) };
|
|
55
38
|
if (type && Type.isMappedType(type.prototype)) {
|
|
56
39
|
prop.type = type;
|
|
57
40
|
}
|
|
58
|
-
if (
|
|
59
|
-
const formula = prop.formula;
|
|
41
|
+
if (typeof prop.formula === 'string') {
|
|
42
|
+
const formula = prop.formula;
|
|
60
43
|
prop.formula = () => formula;
|
|
61
44
|
}
|
|
62
45
|
if (prop.formula) {
|
|
@@ -91,17 +74,18 @@ export class EntitySchema {
|
|
|
91
74
|
}
|
|
92
75
|
addSerializedPrimaryKey(name, type, options = {}) {
|
|
93
76
|
this._meta.serializedPrimaryKey = name;
|
|
94
|
-
this.addProperty(name, type, options);
|
|
77
|
+
this.addProperty(name, type, { serializedPrimaryKey: true, ...options });
|
|
95
78
|
}
|
|
96
79
|
addEmbedded(name, options) {
|
|
80
|
+
this.renameCompositeOptions(name, options);
|
|
97
81
|
Utils.defaultValue(options, 'prefix', true);
|
|
98
82
|
if (options.array) {
|
|
99
83
|
options.object = true; // force object mode for arrays
|
|
100
84
|
}
|
|
101
85
|
this._meta.properties[name] = {
|
|
102
86
|
name,
|
|
103
|
-
type: this.normalizeType(options),
|
|
104
87
|
kind: ReferenceKind.EMBEDDED,
|
|
88
|
+
...this.normalizeType(options),
|
|
105
89
|
...options,
|
|
106
90
|
};
|
|
107
91
|
}
|
|
@@ -114,6 +98,8 @@ export class EntitySchema {
|
|
|
114
98
|
if (prop.fieldNames && !prop.joinColumns) {
|
|
115
99
|
prop.joinColumns = prop.fieldNames;
|
|
116
100
|
}
|
|
101
|
+
// By default, the foreign key constraint is created on the relation
|
|
102
|
+
Utils.defaultValue(prop, 'createForeignKeyConstraint', true);
|
|
117
103
|
this.addProperty(name, type, prop);
|
|
118
104
|
}
|
|
119
105
|
addManyToMany(name, type, options) {
|
|
@@ -123,6 +109,8 @@ export class EntitySchema {
|
|
|
123
109
|
}
|
|
124
110
|
if (options.owner) {
|
|
125
111
|
Utils.renameKey(options, 'mappedBy', 'inversedBy');
|
|
112
|
+
// By default, the foreign key constraint is created on the relation
|
|
113
|
+
Utils.defaultValue(options, 'createForeignKeyConstraint', true);
|
|
126
114
|
}
|
|
127
115
|
const prop = this.createProperty(ReferenceKind.MANY_TO_MANY, options);
|
|
128
116
|
this.addProperty(name, type, prop);
|
|
@@ -135,8 +123,12 @@ export class EntitySchema {
|
|
|
135
123
|
const prop = this.createProperty(ReferenceKind.ONE_TO_ONE, options);
|
|
136
124
|
Utils.defaultValue(prop, 'owner', !!prop.inversedBy || !prop.mappedBy);
|
|
137
125
|
Utils.defaultValue(prop, 'unique', prop.owner);
|
|
138
|
-
if (prop.owner
|
|
139
|
-
|
|
126
|
+
if (prop.owner) {
|
|
127
|
+
if (options.mappedBy) {
|
|
128
|
+
Utils.renameKey(prop, 'mappedBy', 'inversedBy');
|
|
129
|
+
}
|
|
130
|
+
// By default, the foreign key constraint is created on the relation
|
|
131
|
+
Utils.defaultValue(prop, 'createForeignKeyConstraint', true);
|
|
140
132
|
}
|
|
141
133
|
if (prop.joinColumns && !prop.fieldNames) {
|
|
142
134
|
prop.fieldNames = prop.joinColumns;
|
|
@@ -158,21 +150,29 @@ export class EntitySchema {
|
|
|
158
150
|
setExtends(base) {
|
|
159
151
|
this._meta.extends = base;
|
|
160
152
|
}
|
|
161
|
-
setClass(
|
|
162
|
-
const
|
|
163
|
-
this._meta.class
|
|
164
|
-
this._meta.
|
|
165
|
-
this._meta.
|
|
153
|
+
setClass(cls) {
|
|
154
|
+
const oldClass = this._meta.class;
|
|
155
|
+
const sameClass = this._meta.class === cls;
|
|
156
|
+
this._meta.class = cls;
|
|
157
|
+
this._meta.prototype = cls.prototype;
|
|
158
|
+
this._meta.className = this._meta.name ?? cls.name;
|
|
166
159
|
if (!sameClass || !this._meta.constructorParams) {
|
|
167
|
-
|
|
168
|
-
this._meta.constructorParams = Utils.getParamNames(tokens, 'constructor');
|
|
169
|
-
this._meta.toJsonParams = Utils.getParamNames(tokens, 'toJSON').filter(p => p !== '...args');
|
|
160
|
+
this._meta.constructorParams = Utils.getConstructorParams(cls);
|
|
170
161
|
}
|
|
171
162
|
if (!this.internal) {
|
|
172
|
-
|
|
163
|
+
// Remove old class from registry if it's being replaced with a different class
|
|
164
|
+
if (oldClass && oldClass !== cls && EntitySchema.REGISTRY.get(oldClass) === this) {
|
|
165
|
+
EntitySchema.REGISTRY.delete(oldClass);
|
|
166
|
+
}
|
|
167
|
+
EntitySchema.REGISTRY.set(cls, this);
|
|
173
168
|
}
|
|
174
|
-
|
|
175
|
-
|
|
169
|
+
const base = Object.getPrototypeOf(cls);
|
|
170
|
+
// Only set extends if the parent is NOT the auto-generated class for this same entity.
|
|
171
|
+
// When the user extends the auto-generated class (from defineEntity without a class option)
|
|
172
|
+
// and registers their custom class via setClass, we don't want to discover the
|
|
173
|
+
// auto-generated class as a separate parent entity.
|
|
174
|
+
if (base !== BaseEntity && base.name !== this._meta.className) {
|
|
175
|
+
this._meta.extends ??= base.name ? base : undefined;
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
get meta() {
|
|
@@ -181,6 +181,18 @@ export class EntitySchema {
|
|
|
181
181
|
get name() {
|
|
182
182
|
return this._meta.className;
|
|
183
183
|
}
|
|
184
|
+
get tableName() {
|
|
185
|
+
return this._meta.tableName;
|
|
186
|
+
}
|
|
187
|
+
get class() {
|
|
188
|
+
return this._meta.class;
|
|
189
|
+
}
|
|
190
|
+
get properties() {
|
|
191
|
+
return this._meta.properties;
|
|
192
|
+
}
|
|
193
|
+
new(...params) {
|
|
194
|
+
return new this._meta.class(...params);
|
|
195
|
+
}
|
|
184
196
|
/**
|
|
185
197
|
* @internal
|
|
186
198
|
*/
|
|
@@ -188,19 +200,16 @@ export class EntitySchema {
|
|
|
188
200
|
if (this.initialized) {
|
|
189
201
|
return this;
|
|
190
202
|
}
|
|
191
|
-
if (!this._meta.class) {
|
|
192
|
-
const name = this.name;
|
|
193
|
-
this._meta.class = ({ [name]: class {
|
|
194
|
-
} })[name];
|
|
195
|
-
}
|
|
196
203
|
this.setClass(this._meta.class);
|
|
197
|
-
|
|
204
|
+
// Abstract TPT entities keep their name because they have their own table
|
|
205
|
+
const isTPT = this._meta.inheritance === 'tpt' || this.isPartOfTPTHierarchy();
|
|
206
|
+
if (this._meta.abstract && !this._meta.discriminatorColumn && !isTPT) {
|
|
198
207
|
delete this._meta.name;
|
|
199
208
|
}
|
|
200
209
|
const tableName = this._meta.collection ?? this._meta.tableName;
|
|
201
210
|
if (tableName?.includes('.') && !this._meta.schema) {
|
|
202
211
|
this._meta.schema = tableName.substring(0, tableName.indexOf('.'));
|
|
203
|
-
this._meta.
|
|
212
|
+
this._meta.tableName = tableName.substring(tableName.indexOf('.') + 1);
|
|
204
213
|
}
|
|
205
214
|
this.initProperties();
|
|
206
215
|
this.initPrimaryKeys();
|
|
@@ -209,6 +218,24 @@ export class EntitySchema {
|
|
|
209
218
|
this.initialized = true;
|
|
210
219
|
return this;
|
|
211
220
|
}
|
|
221
|
+
/**
|
|
222
|
+
* Check if this entity is part of a TPT hierarchy by walking up the extends chain.
|
|
223
|
+
* This handles mid-level abstract entities (e.g., Animal -> Mammal -> Dog where Mammal is abstract).
|
|
224
|
+
*/
|
|
225
|
+
isPartOfTPTHierarchy() {
|
|
226
|
+
let parent = this._meta.extends;
|
|
227
|
+
while (parent) {
|
|
228
|
+
const parentSchema = parent instanceof EntitySchema ? parent : EntitySchema.REGISTRY.get(parent);
|
|
229
|
+
if (!parentSchema) {
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
if (parentSchema._meta.inheritance === 'tpt') {
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
parent = parentSchema._meta.extends;
|
|
236
|
+
}
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
212
239
|
initProperties() {
|
|
213
240
|
Utils.entries(this._meta.properties).forEach(([name, options]) => {
|
|
214
241
|
if (Type.isMappedType(options.type)) {
|
|
@@ -266,12 +293,15 @@ export class EntitySchema {
|
|
|
266
293
|
}
|
|
267
294
|
normalizeType(options, type) {
|
|
268
295
|
if ('entity' in options) {
|
|
269
|
-
|
|
270
|
-
|
|
296
|
+
/* v8 ignore next */
|
|
297
|
+
if (typeof options.entity === 'string') {
|
|
298
|
+
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}.`);
|
|
271
299
|
}
|
|
272
300
|
else if (options.entity) {
|
|
273
301
|
const tmp = options.entity();
|
|
274
302
|
type = options.type = Array.isArray(tmp) ? tmp.map(t => Utils.className(t)).sort().join(' | ') : Utils.className(tmp);
|
|
303
|
+
const target = tmp instanceof EntitySchema ? tmp.meta.class : tmp;
|
|
304
|
+
return { type, target };
|
|
275
305
|
}
|
|
276
306
|
}
|
|
277
307
|
if (type instanceof Function) {
|
|
@@ -280,7 +310,7 @@ export class EntitySchema {
|
|
|
280
310
|
if (['String', 'Number', 'Boolean', 'Array'].includes(type)) {
|
|
281
311
|
type = type.toLowerCase();
|
|
282
312
|
}
|
|
283
|
-
return type;
|
|
313
|
+
return { type };
|
|
284
314
|
}
|
|
285
315
|
createProperty(kind, options) {
|
|
286
316
|
return {
|
|
@@ -289,4 +319,47 @@ export class EntitySchema {
|
|
|
289
319
|
...options,
|
|
290
320
|
};
|
|
291
321
|
}
|
|
322
|
+
rename(data, from, to) {
|
|
323
|
+
if (from in data && !(to in data)) {
|
|
324
|
+
// @ts-ignore
|
|
325
|
+
data[to] = [data[from]];
|
|
326
|
+
// @ts-ignore
|
|
327
|
+
delete data[from];
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
renameCompositeOptions(name, options = {}) {
|
|
331
|
+
if (name !== options.name && !options.fieldNames) {
|
|
332
|
+
Utils.renameKey(options, 'name', 'fieldName');
|
|
333
|
+
}
|
|
334
|
+
else if (options.name && (options.fieldNames?.length ?? 0) > 1) {
|
|
335
|
+
delete options.name;
|
|
336
|
+
}
|
|
337
|
+
this.rename(options, 'fieldName', 'fieldNames');
|
|
338
|
+
this.rename(options, 'joinColumn', 'joinColumns');
|
|
339
|
+
this.rename(options, 'inverseJoinColumn', 'inverseJoinColumns');
|
|
340
|
+
this.rename(options, 'referenceColumnName', 'referencedColumnNames');
|
|
341
|
+
this.rename(options, 'columnType', 'columnTypes');
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Adds a lifecycle hook handler to the entity schema.
|
|
345
|
+
* This method allows registering hooks after the entity is defined,
|
|
346
|
+
* which can be useful for avoiding circular type references.
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* ```ts
|
|
350
|
+
* export const Article = defineEntity({
|
|
351
|
+
* name: 'Article',
|
|
352
|
+
* properties: { ... },
|
|
353
|
+
* });
|
|
354
|
+
*
|
|
355
|
+
* Article.addHook('beforeCreate', async args => {
|
|
356
|
+
* args.entity.slug = args.entity.title.toLowerCase();
|
|
357
|
+
* });
|
|
358
|
+
* ```
|
|
359
|
+
*/
|
|
360
|
+
addHook(event, handler) {
|
|
361
|
+
this._meta.hooks[event] ??= [];
|
|
362
|
+
this._meta.hooks[event].push(handler);
|
|
363
|
+
return this;
|
|
364
|
+
}
|
|
292
365
|
}
|
|
@@ -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,18 +42,74 @@ 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
|
-
private createColumnMappingObject;
|
|
58
113
|
private getDefaultVersionValue;
|
|
59
114
|
private inferDefaultValue;
|
|
60
115
|
private initDefaultValue;
|
|
@@ -67,6 +122,5 @@ export declare class MetadataDiscovery {
|
|
|
67
122
|
private getPrefix;
|
|
68
123
|
private initUnsigned;
|
|
69
124
|
private initIndexes;
|
|
70
|
-
private getEntityClassOrSchema;
|
|
71
125
|
private shouldForceConstructorUsage;
|
|
72
126
|
}
|