@mikro-orm/core 7.0.0-dev.1 → 7.0.0-dev.100
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 +96 -58
- package/EntityManager.js +465 -395
- package/MikroORM.d.ts +45 -35
- package/MikroORM.js +109 -160
- package/README.md +3 -2
- package/cache/CacheAdapter.js +1 -2
- package/cache/FileCacheAdapter.d.ts +2 -2
- package/cache/FileCacheAdapter.js +20 -27
- package/cache/GeneratedCacheAdapter.d.ts +2 -3
- package/cache/GeneratedCacheAdapter.js +1 -7
- package/cache/MemoryCacheAdapter.d.ts +1 -1
- package/cache/MemoryCacheAdapter.js +1 -5
- package/cache/NullCacheAdapter.d.ts +1 -1
- package/cache/NullCacheAdapter.js +1 -5
- package/cache/index.d.ts +4 -5
- package/cache/index.js +4 -21
- package/connections/Connection.d.ts +22 -14
- package/connections/Connection.js +27 -23
- package/connections/index.d.ts +1 -1
- package/connections/index.js +1 -17
- package/drivers/DatabaseDriver.d.ts +25 -15
- package/drivers/DatabaseDriver.js +77 -64
- package/drivers/IDatabaseDriver.d.ts +40 -16
- package/drivers/IDatabaseDriver.js +1 -4
- package/drivers/index.d.ts +2 -2
- package/drivers/index.js +2 -18
- package/entity/BaseEntity.d.ts +6 -7
- package/entity/BaseEntity.js +16 -23
- package/entity/Collection.d.ts +98 -34
- package/entity/Collection.js +466 -131
- package/entity/EntityAssigner.d.ts +3 -3
- package/entity/EntityAssigner.js +67 -64
- package/entity/EntityFactory.d.ts +10 -3
- package/entity/EntityFactory.js +112 -91
- package/entity/EntityHelper.d.ts +2 -2
- package/entity/EntityHelper.js +66 -53
- package/entity/EntityIdentifier.d.ts +1 -1
- package/entity/EntityIdentifier.js +1 -5
- package/entity/EntityLoader.d.ts +8 -7
- package/entity/EntityLoader.js +161 -128
- package/entity/EntityRepository.d.ts +8 -8
- package/entity/EntityRepository.js +7 -11
- package/entity/Reference.d.ts +10 -13
- package/entity/Reference.js +64 -46
- package/entity/WrappedEntity.d.ts +12 -17
- package/entity/WrappedEntity.js +22 -31
- package/entity/defineEntity.d.ts +568 -0
- package/entity/defineEntity.js +529 -0
- package/entity/index.d.ts +14 -13
- package/entity/index.js +14 -29
- package/entity/utils.d.ts +8 -1
- package/entity/utils.js +22 -13
- package/entity/validators.d.ts +11 -0
- package/entity/validators.js +65 -0
- package/entity/wrap.d.ts +1 -1
- package/entity/wrap.js +2 -6
- package/enums.d.ts +24 -9
- package/enums.js +50 -41
- package/errors.d.ts +11 -3
- package/errors.js +42 -32
- package/events/EventManager.d.ts +5 -4
- package/events/EventManager.js +26 -22
- package/events/EventSubscriber.d.ts +8 -5
- package/events/EventSubscriber.js +1 -2
- package/events/TransactionEventBroadcaster.d.ts +3 -3
- package/events/TransactionEventBroadcaster.js +1 -5
- package/events/index.d.ts +3 -3
- package/events/index.js +3 -19
- package/exceptions.js +18 -39
- package/hydration/Hydrator.d.ts +5 -5
- package/hydration/Hydrator.js +2 -6
- package/hydration/ObjectHydrator.d.ts +7 -7
- package/hydration/ObjectHydrator.js +58 -50
- package/hydration/index.d.ts +2 -2
- package/hydration/index.js +2 -18
- package/index.d.ts +21 -21
- package/index.js +20 -46
- package/logging/DefaultLogger.d.ts +2 -2
- package/logging/DefaultLogger.js +10 -13
- package/logging/Logger.d.ts +1 -1
- package/logging/Logger.js +1 -2
- package/logging/SimpleLogger.d.ts +3 -3
- package/logging/SimpleLogger.js +2 -6
- package/logging/colors.js +1 -5
- package/logging/index.d.ts +5 -4
- package/logging/index.js +5 -20
- package/logging/inspect.d.ts +2 -0
- package/logging/inspect.js +16 -0
- package/metadata/EntitySchema.d.ts +14 -10
- package/metadata/EntitySchema.js +78 -64
- package/metadata/MetadataDiscovery.d.ts +11 -14
- package/metadata/MetadataDiscovery.js +278 -317
- package/metadata/MetadataProvider.d.ts +13 -4
- package/metadata/MetadataProvider.js +47 -8
- package/metadata/MetadataStorage.d.ts +2 -7
- package/metadata/MetadataStorage.js +19 -35
- package/metadata/MetadataValidator.d.ts +3 -10
- package/metadata/MetadataValidator.js +51 -64
- package/metadata/discover-entities.d.ts +5 -0
- package/metadata/discover-entities.js +40 -0
- package/metadata/index.d.ts +6 -6
- package/metadata/index.js +6 -22
- package/metadata/types.d.ts +480 -0
- package/metadata/types.js +1 -0
- package/naming-strategy/AbstractNamingStrategy.d.ts +7 -3
- package/naming-strategy/AbstractNamingStrategy.js +11 -9
- package/naming-strategy/EntityCaseNamingStrategy.d.ts +1 -1
- package/naming-strategy/EntityCaseNamingStrategy.js +2 -6
- package/naming-strategy/MongoNamingStrategy.d.ts +1 -1
- package/naming-strategy/MongoNamingStrategy.js +2 -6
- package/naming-strategy/NamingStrategy.d.ts +12 -2
- package/naming-strategy/NamingStrategy.js +1 -2
- package/naming-strategy/UnderscoreNamingStrategy.d.ts +1 -1
- package/naming-strategy/UnderscoreNamingStrategy.js +2 -6
- package/naming-strategy/index.d.ts +5 -5
- package/naming-strategy/index.js +5 -21
- package/not-supported.d.ts +2 -0
- package/not-supported.js +4 -0
- package/package.json +19 -20
- package/platforms/ExceptionConverter.d.ts +2 -2
- package/platforms/ExceptionConverter.js +4 -8
- package/platforms/Platform.d.ts +15 -22
- package/platforms/Platform.js +58 -88
- package/platforms/index.d.ts +2 -2
- package/platforms/index.js +2 -18
- package/serialization/EntitySerializer.d.ts +4 -2
- package/serialization/EntitySerializer.js +64 -51
- package/serialization/EntityTransformer.d.ts +1 -1
- package/serialization/EntityTransformer.js +48 -42
- package/serialization/SerializationContext.d.ts +2 -2
- package/serialization/SerializationContext.js +24 -25
- package/serialization/index.d.ts +3 -3
- package/serialization/index.js +3 -19
- package/types/ArrayType.d.ts +3 -3
- package/types/ArrayType.js +6 -11
- package/types/BigIntType.d.ts +12 -9
- package/types/BigIntType.js +6 -6
- package/types/BlobType.d.ts +3 -4
- package/types/BlobType.js +2 -11
- package/types/BooleanType.d.ts +5 -4
- package/types/BooleanType.js +5 -6
- package/types/CharacterType.d.ts +3 -3
- package/types/CharacterType.js +2 -6
- package/types/DateTimeType.d.ts +3 -3
- package/types/DateTimeType.js +2 -6
- package/types/DateType.d.ts +3 -3
- package/types/DateType.js +2 -6
- package/types/DecimalType.d.ts +9 -7
- package/types/DecimalType.js +5 -8
- package/types/DoubleType.d.ts +3 -3
- package/types/DoubleType.js +4 -7
- package/types/EnumArrayType.d.ts +4 -4
- package/types/EnumArrayType.js +4 -10
- package/types/EnumType.d.ts +3 -3
- package/types/EnumType.js +2 -6
- package/types/FloatType.d.ts +3 -3
- package/types/FloatType.js +2 -6
- package/types/IntegerType.d.ts +3 -3
- package/types/IntegerType.js +2 -6
- package/types/IntervalType.d.ts +3 -3
- package/types/IntervalType.js +2 -6
- package/types/JsonType.d.ts +4 -4
- package/types/JsonType.js +9 -8
- package/types/MediumIntType.d.ts +3 -3
- package/types/MediumIntType.js +2 -6
- package/types/SmallIntType.d.ts +3 -3
- package/types/SmallIntType.js +2 -6
- package/types/StringType.d.ts +3 -3
- package/types/StringType.js +2 -6
- package/types/TextType.d.ts +3 -3
- package/types/TextType.js +2 -6
- package/types/TimeType.d.ts +3 -3
- package/types/TimeType.js +4 -8
- package/types/TinyIntType.d.ts +3 -3
- package/types/TinyIntType.js +3 -6
- package/types/Type.d.ts +4 -6
- package/types/Type.js +6 -10
- package/types/Uint8ArrayType.d.ts +3 -4
- package/types/Uint8ArrayType.js +3 -12
- package/types/UnknownType.d.ts +3 -3
- package/types/UnknownType.js +2 -6
- package/types/UuidType.d.ts +3 -3
- package/types/UuidType.js +2 -6
- package/types/index.d.ts +25 -25
- package/types/index.js +52 -79
- package/typings.d.ts +134 -93
- package/typings.js +67 -65
- package/unit-of-work/ChangeSet.d.ts +1 -4
- package/unit-of-work/ChangeSet.js +13 -17
- package/unit-of-work/ChangeSetComputer.d.ts +8 -9
- package/unit-of-work/ChangeSetComputer.js +36 -38
- package/unit-of-work/ChangeSetPersister.d.ts +11 -9
- package/unit-of-work/ChangeSetPersister.js +100 -65
- package/unit-of-work/CommitOrderCalculator.d.ts +1 -1
- package/unit-of-work/CommitOrderCalculator.js +6 -10
- package/unit-of-work/IdentityMap.d.ts +1 -1
- package/unit-of-work/IdentityMap.js +1 -5
- package/unit-of-work/UnitOfWork.d.ts +16 -8
- package/unit-of-work/UnitOfWork.js +266 -209
- package/unit-of-work/index.d.ts +6 -6
- package/unit-of-work/index.js +6 -22
- package/utils/AbstractSchemaGenerator.d.ts +11 -11
- package/utils/AbstractSchemaGenerator.js +21 -20
- package/utils/Configuration.d.ts +774 -224
- package/utils/Configuration.js +166 -216
- package/utils/ConfigurationLoader.d.ts +1 -53
- package/utils/ConfigurationLoader.js +1 -367
- package/utils/Cursor.d.ts +6 -9
- package/utils/Cursor.js +25 -25
- package/utils/DataloaderUtils.d.ts +18 -8
- package/utils/DataloaderUtils.js +63 -21
- package/utils/EntityComparator.d.ts +9 -5
- package/utils/EntityComparator.js +155 -108
- package/utils/NullHighlighter.d.ts +1 -1
- package/utils/NullHighlighter.js +1 -5
- package/utils/QueryHelper.d.ts +12 -4
- package/utils/QueryHelper.js +110 -53
- package/utils/RawQueryFragment.d.ts +37 -14
- package/utils/RawQueryFragment.js +50 -33
- package/utils/RequestContext.d.ts +2 -2
- package/utils/RequestContext.js +3 -7
- package/utils/TransactionContext.d.ts +1 -1
- package/utils/TransactionContext.js +4 -8
- package/utils/TransactionManager.d.ts +65 -0
- package/utils/TransactionManager.js +223 -0
- package/utils/Utils.d.ts +16 -100
- package/utils/Utils.js +114 -332
- package/utils/clone.js +7 -11
- package/utils/env-vars.d.ts +3 -0
- package/utils/env-vars.js +87 -0
- package/utils/fs-utils.d.ts +12 -0
- package/utils/fs-utils.js +97 -0
- package/utils/index.d.ts +14 -13
- package/utils/index.js +14 -29
- package/utils/upsert-utils.d.ts +8 -3
- package/utils/upsert-utils.js +57 -10
- package/decorators/Check.d.ts +0 -3
- package/decorators/Check.js +0 -16
- package/decorators/CreateRequestContext.d.ts +0 -3
- package/decorators/CreateRequestContext.js +0 -33
- package/decorators/Embeddable.d.ts +0 -8
- package/decorators/Embeddable.js +0 -14
- package/decorators/Embedded.d.ts +0 -18
- package/decorators/Embedded.js +0 -20
- package/decorators/Entity.d.ts +0 -18
- package/decorators/Entity.js +0 -16
- package/decorators/Enum.d.ts +0 -9
- package/decorators/Enum.js +0 -19
- package/decorators/Filter.d.ts +0 -2
- package/decorators/Filter.js +0 -11
- package/decorators/Formula.d.ts +0 -5
- package/decorators/Formula.js +0 -18
- package/decorators/Indexed.d.ts +0 -17
- package/decorators/Indexed.js +0 -24
- package/decorators/ManyToMany.d.ts +0 -40
- package/decorators/ManyToMany.js +0 -16
- package/decorators/ManyToOne.d.ts +0 -30
- package/decorators/ManyToOne.js +0 -16
- package/decorators/OneToMany.d.ts +0 -28
- package/decorators/OneToMany.js +0 -20
- package/decorators/OneToOne.d.ts +0 -24
- package/decorators/OneToOne.js +0 -10
- package/decorators/PrimaryKey.d.ts +0 -9
- package/decorators/PrimaryKey.js +0 -23
- package/decorators/Property.d.ts +0 -250
- package/decorators/Property.js +0 -34
- package/decorators/Transactional.d.ts +0 -13
- package/decorators/Transactional.js +0 -31
- package/decorators/hooks.d.ts +0 -16
- package/decorators/hooks.js +0 -59
- package/decorators/index.d.ts +0 -17
- package/decorators/index.js +0 -36
- package/entity/ArrayCollection.d.ts +0 -116
- package/entity/ArrayCollection.js +0 -399
- package/entity/EntityValidator.d.ts +0 -19
- package/entity/EntityValidator.js +0 -154
- package/index.mjs +0 -199
- package/metadata/ReflectMetadataProvider.d.ts +0 -8
- package/metadata/ReflectMetadataProvider.js +0 -48
- package/utils/resolveContextProvider.d.ts +0 -10
- package/utils/resolveContextProvider.js +0 -31
package/entity/EntityFactory.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const EntityHelper_1 = require("./EntityHelper");
|
|
10
|
-
class EntityFactory {
|
|
1
|
+
import { Utils } from '../utils/Utils.js';
|
|
2
|
+
import { QueryHelper } from '../utils/QueryHelper.js';
|
|
3
|
+
import { EventType, ReferenceKind } from '../enums.js';
|
|
4
|
+
import { Reference } from './Reference.js';
|
|
5
|
+
import { helper } from './wrap.js';
|
|
6
|
+
import { EntityHelper } from './EntityHelper.js';
|
|
7
|
+
import { JsonType } from '../types/JsonType.js';
|
|
8
|
+
export class EntityFactory {
|
|
11
9
|
em;
|
|
12
10
|
driver;
|
|
13
11
|
platform;
|
|
@@ -27,12 +25,12 @@ class EntityFactory {
|
|
|
27
25
|
this.comparator = this.em.getComparator();
|
|
28
26
|
}
|
|
29
27
|
create(entityName, data, options = {}) {
|
|
30
|
-
data =
|
|
28
|
+
data = Reference.unwrapReference(data);
|
|
31
29
|
options.initialized ??= true;
|
|
32
30
|
if (data.__entity) {
|
|
33
31
|
return data;
|
|
34
32
|
}
|
|
35
|
-
entityName =
|
|
33
|
+
entityName = Utils.className(entityName);
|
|
36
34
|
const meta = this.metadata.get(entityName);
|
|
37
35
|
if (meta.virtual) {
|
|
38
36
|
data = { ...data };
|
|
@@ -40,14 +38,15 @@ class EntityFactory {
|
|
|
40
38
|
this.hydrate(entity, meta, data, options);
|
|
41
39
|
return entity;
|
|
42
40
|
}
|
|
43
|
-
if (
|
|
44
|
-
|
|
41
|
+
if (meta.serializedPrimaryKey) {
|
|
42
|
+
this.denormalizePrimaryKey(meta, data);
|
|
45
43
|
}
|
|
46
44
|
const meta2 = this.processDiscriminatorColumn(meta, data);
|
|
47
45
|
const exists = this.findEntity(data, meta2, options);
|
|
48
|
-
let wrapped = exists &&
|
|
46
|
+
let wrapped = exists && helper(exists);
|
|
49
47
|
if (wrapped && !options.refresh) {
|
|
50
48
|
wrapped.__processing = true;
|
|
49
|
+
Utils.dropUndefinedProperties(data);
|
|
51
50
|
this.mergeData(meta2, exists, data, options);
|
|
52
51
|
wrapped.__processing = false;
|
|
53
52
|
if (wrapped.isInitialized()) {
|
|
@@ -56,12 +55,12 @@ class EntityFactory {
|
|
|
56
55
|
}
|
|
57
56
|
data = { ...data };
|
|
58
57
|
const entity = exists ?? this.createEntity(data, meta2, options);
|
|
59
|
-
wrapped =
|
|
58
|
+
wrapped = helper(entity);
|
|
60
59
|
wrapped.__processing = true;
|
|
61
60
|
wrapped.__initialized = options.initialized;
|
|
62
61
|
if (options.newEntity || meta.forceConstructor || meta.virtual) {
|
|
63
62
|
const tmp = { ...data };
|
|
64
|
-
meta.constructorParams
|
|
63
|
+
meta.constructorParams?.forEach(prop => delete tmp[prop]);
|
|
65
64
|
this.hydrate(entity, meta2, tmp, options);
|
|
66
65
|
// since we now process only a copy of the `data` via hydrator, but later we register the state with the full snapshot,
|
|
67
66
|
// we need to go through all props with custom types that have `ensureComparable: true` and ensure they are comparable
|
|
@@ -69,13 +68,15 @@ class EntityFactory {
|
|
|
69
68
|
if (options.convertCustomTypes) {
|
|
70
69
|
for (const prop of meta.props) {
|
|
71
70
|
if (prop.customType?.ensureComparable(meta, prop) && data[prop.name]) {
|
|
72
|
-
if ([
|
|
71
|
+
if ([ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind)) {
|
|
73
72
|
continue;
|
|
74
73
|
}
|
|
75
|
-
if ([
|
|
76
|
-
data[prop.name] =
|
|
74
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name])) {
|
|
75
|
+
data[prop.name] = Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta, true);
|
|
76
|
+
}
|
|
77
|
+
if (prop.customType instanceof JsonType && this.platform.convertsJsonAutomatically()) {
|
|
78
|
+
data[prop.name] = prop.customType.convertToDatabaseValue(data[prop.name], this.platform, { key: prop.name, mode: 'hydration' });
|
|
77
79
|
}
|
|
78
|
-
data[prop.name] = prop.customType.convertToDatabaseValue(data[prop.name], this.platform, { key: prop.name, mode: 'hydration' });
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
82
|
}
|
|
@@ -83,13 +84,14 @@ class EntityFactory {
|
|
|
83
84
|
else {
|
|
84
85
|
this.hydrate(entity, meta2, data, options);
|
|
85
86
|
}
|
|
86
|
-
wrapped.__touched = false;
|
|
87
87
|
if (exists && meta.discriminatorColumn && !(entity instanceof meta2.class)) {
|
|
88
88
|
Object.setPrototypeOf(entity, meta2.prototype);
|
|
89
89
|
}
|
|
90
90
|
if (options.merge && wrapped.hasPrimaryKey()) {
|
|
91
91
|
this.unitOfWork.register(entity, data, {
|
|
92
|
-
refresh
|
|
92
|
+
// Always refresh to ensure the payload is in correct shape for joined strategy. When loading nested relations,
|
|
93
|
+
// they will be created early without `Type.ensureComparable` being properly handled, resulting in extra updates.
|
|
94
|
+
refresh: options.initialized,
|
|
93
95
|
newEntity: options.newEntity,
|
|
94
96
|
loaded: options.initialized,
|
|
95
97
|
});
|
|
@@ -97,26 +99,26 @@ class EntityFactory {
|
|
|
97
99
|
wrapped.__originalEntityData = this.comparator.prepareEntity(entity);
|
|
98
100
|
}
|
|
99
101
|
}
|
|
100
|
-
if (this.eventManager.hasListeners(
|
|
101
|
-
this.eventManager.dispatchEvent(
|
|
102
|
+
if (this.eventManager.hasListeners(EventType.onInit, meta2)) {
|
|
103
|
+
this.eventManager.dispatchEvent(EventType.onInit, { entity, meta: meta2, em: this.em });
|
|
102
104
|
}
|
|
103
105
|
wrapped.__processing = false;
|
|
104
106
|
return entity;
|
|
105
107
|
}
|
|
106
108
|
mergeData(meta, entity, data, options = {}) {
|
|
107
109
|
// merge unchanged properties automatically
|
|
108
|
-
data =
|
|
110
|
+
data = QueryHelper.processParams(data);
|
|
109
111
|
const existsData = this.comparator.prepareEntity(entity);
|
|
110
|
-
const originalEntityData =
|
|
112
|
+
const originalEntityData = helper(entity).__originalEntityData ?? {};
|
|
111
113
|
const diff = this.comparator.diffEntities(meta.className, originalEntityData, existsData);
|
|
112
114
|
// version properties are not part of entity snapshots
|
|
113
115
|
if (meta.versionProperty && data[meta.versionProperty] && data[meta.versionProperty] !== originalEntityData[meta.versionProperty]) {
|
|
114
116
|
diff[meta.versionProperty] = data[meta.versionProperty];
|
|
115
117
|
}
|
|
116
|
-
const diff2 = this.comparator.diffEntities(meta.className, existsData, data);
|
|
118
|
+
const diff2 = this.comparator.diffEntities(meta.className, existsData, data, { includeInverseSides: true });
|
|
117
119
|
// do not override values changed by user
|
|
118
|
-
|
|
119
|
-
|
|
120
|
+
Utils.keys(diff).forEach(key => delete diff2[key]);
|
|
121
|
+
Utils.keys(diff2).filter(key => {
|
|
120
122
|
// ignore null values if there is already present non-null value
|
|
121
123
|
if (existsData[key] != null) {
|
|
122
124
|
return diff2[key] == null;
|
|
@@ -124,40 +126,44 @@ class EntityFactory {
|
|
|
124
126
|
return diff2[key] === undefined;
|
|
125
127
|
}).forEach(key => delete diff2[key]);
|
|
126
128
|
// but always add collection properties and formulas if they are part of the `data`
|
|
127
|
-
|
|
128
|
-
.filter(key => meta.properties[key]?.formula || [
|
|
129
|
+
Utils.keys(data)
|
|
130
|
+
.filter(key => meta.properties[key]?.formula || [ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(meta.properties[key]?.kind))
|
|
129
131
|
.forEach(key => diff2[key] = data[key]);
|
|
130
132
|
// rehydrated with the new values, skip those changed by user
|
|
131
133
|
this.hydrate(entity, meta, diff2, options);
|
|
132
134
|
// we need to update the entity data only with keys that were not present before
|
|
133
135
|
const nullVal = this.config.get('forceUndefined') ? undefined : null;
|
|
134
|
-
|
|
136
|
+
Utils.keys(diff2).forEach(key => {
|
|
135
137
|
const prop = meta.properties[key];
|
|
136
|
-
if ([
|
|
137
|
-
diff2[key] = entity[prop.name] ?
|
|
138
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name])) {
|
|
139
|
+
diff2[key] = entity[prop.name] ? helper(entity[prop.name]).getPrimaryKey(options.convertCustomTypes) : null;
|
|
140
|
+
}
|
|
141
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE, ReferenceKind.SCALAR].includes(prop.kind) && prop.customType?.ensureComparable(meta, prop) && diff2[key] != null) {
|
|
142
|
+
const converted = prop.customType.convertToJSValue(diff2[key], this.platform, { force: true });
|
|
143
|
+
diff2[key] = prop.customType.convertToDatabaseValue(converted, this.platform, { fromQuery: true });
|
|
138
144
|
}
|
|
139
145
|
originalEntityData[key] = diff2[key] === null ? nullVal : diff2[key];
|
|
140
|
-
|
|
146
|
+
helper(entity).__loadedProperties.add(key);
|
|
141
147
|
});
|
|
142
148
|
// in case of joined loading strategy, we need to cascade the merging to possibly loaded relations manually
|
|
143
149
|
meta.relations.forEach(prop => {
|
|
144
|
-
if ([
|
|
150
|
+
if ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop.kind) && Array.isArray(data[prop.name])) {
|
|
145
151
|
// instead of trying to match the collection items (which could easily fail if the collection was loaded with different ordering),
|
|
146
152
|
// we just create the entity from scratch, which will automatically pick the right one from the identity map and call `mergeData` on it
|
|
147
153
|
data[prop.name]
|
|
148
|
-
.filter(child =>
|
|
154
|
+
.filter(child => Utils.isPlainObject(child)) // objects with prototype can be PKs (e.g. `ObjectId`)
|
|
149
155
|
.forEach(child => this.create(prop.type, child, options)); // we can ignore the value, we just care about the `mergeData` call
|
|
150
156
|
return;
|
|
151
157
|
}
|
|
152
|
-
if ([
|
|
158
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name]) && entity[prop.name] && helper(entity[prop.name]).__initialized) {
|
|
153
159
|
this.create(prop.type, data[prop.name], options); // we can ignore the value, we just care about the `mergeData` call
|
|
154
160
|
}
|
|
155
161
|
});
|
|
156
|
-
(
|
|
162
|
+
this.unitOfWork.normalizeEntityData(meta, originalEntityData);
|
|
157
163
|
}
|
|
158
164
|
createReference(entityName, id, options = {}) {
|
|
159
165
|
options.convertCustomTypes ??= true;
|
|
160
|
-
entityName =
|
|
166
|
+
entityName = Utils.className(entityName);
|
|
161
167
|
const meta = this.metadata.get(entityName);
|
|
162
168
|
const schema = this.driver.getSchemaName(meta, options);
|
|
163
169
|
if (meta.simplePK) {
|
|
@@ -165,24 +171,24 @@ class EntityFactory {
|
|
|
165
171
|
if (exists) {
|
|
166
172
|
return exists;
|
|
167
173
|
}
|
|
168
|
-
const data =
|
|
174
|
+
const data = Utils.isPlainObject(id) ? id : { [meta.primaryKeys[0]]: Array.isArray(id) ? id[0] : id };
|
|
169
175
|
return this.create(entityName, data, { ...options, initialized: false });
|
|
170
176
|
}
|
|
171
177
|
if (Array.isArray(id)) {
|
|
172
|
-
id =
|
|
178
|
+
id = Utils.getPrimaryKeyCondFromArray(id, meta);
|
|
173
179
|
}
|
|
174
|
-
const pks =
|
|
175
|
-
const exists = this.unitOfWork.getById(entityName, pks, schema);
|
|
180
|
+
const pks = Utils.getOrderedPrimaryKeys(id, meta, this.platform);
|
|
181
|
+
const exists = this.unitOfWork.getById(entityName, pks, schema, options.convertCustomTypes);
|
|
176
182
|
if (exists) {
|
|
177
183
|
return exists;
|
|
178
184
|
}
|
|
179
|
-
if (
|
|
185
|
+
if (Utils.isPrimaryKey(id)) {
|
|
180
186
|
id = { [meta.primaryKeys[0]]: id };
|
|
181
187
|
}
|
|
182
188
|
return this.create(entityName, id, { ...options, initialized: false });
|
|
183
189
|
}
|
|
184
190
|
createEmbeddable(entityName, data, options = {}) {
|
|
185
|
-
entityName =
|
|
191
|
+
entityName = Utils.className(entityName);
|
|
186
192
|
data = { ...data };
|
|
187
193
|
const meta = this.metadata.get(entityName);
|
|
188
194
|
const meta2 = this.processDiscriminatorColumn(meta, data);
|
|
@@ -211,37 +217,48 @@ class EntityFactory {
|
|
|
211
217
|
if (meta.virtual) {
|
|
212
218
|
return entity;
|
|
213
219
|
}
|
|
214
|
-
|
|
220
|
+
helper(entity).__schema = schema;
|
|
215
221
|
if (options.initialized) {
|
|
216
|
-
|
|
222
|
+
EntityHelper.ensurePropagation(entity);
|
|
217
223
|
}
|
|
218
224
|
return entity;
|
|
219
225
|
}
|
|
220
226
|
// creates new entity instance, bypassing constructor call as its already persisted entity
|
|
221
227
|
const entity = Object.create(meta.class.prototype);
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
228
|
+
helper(entity).__managed = true;
|
|
229
|
+
helper(entity).__processing = !meta.embeddable && !meta.virtual;
|
|
230
|
+
helper(entity).__schema = schema;
|
|
225
231
|
if (options.merge && !options.newEntity) {
|
|
226
232
|
this.hydrator.hydrateReference(entity, meta, data, this, options.convertCustomTypes, options.schema, options.parentSchema);
|
|
227
233
|
this.unitOfWork.register(entity);
|
|
228
234
|
}
|
|
229
235
|
if (options.initialized) {
|
|
230
|
-
|
|
236
|
+
EntityHelper.ensurePropagation(entity);
|
|
231
237
|
}
|
|
232
238
|
return entity;
|
|
233
239
|
}
|
|
240
|
+
assignDefaultValues(entity, meta) {
|
|
241
|
+
for (const prop of meta.props) {
|
|
242
|
+
if (prop.onCreate) {
|
|
243
|
+
entity[prop.name] ??= prop.onCreate(entity, this.em);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
234
247
|
hydrate(entity, meta, data, options) {
|
|
235
248
|
if (options.initialized) {
|
|
236
|
-
this.hydrator.hydrate(entity, meta, data, this, 'full', options.newEntity, options.convertCustomTypes, options.schema, this.driver.getSchemaName(meta, options));
|
|
249
|
+
this.hydrator.hydrate(entity, meta, data, this, 'full', options.newEntity, options.convertCustomTypes, options.schema, this.driver.getSchemaName(meta, options), options.normalizeAccessors);
|
|
237
250
|
}
|
|
238
251
|
else {
|
|
239
|
-
this.hydrator.hydrateReference(entity, meta, data, this, options.convertCustomTypes, options.schema, this.driver.getSchemaName(meta, options));
|
|
252
|
+
this.hydrator.hydrateReference(entity, meta, data, this, options.convertCustomTypes, options.schema, this.driver.getSchemaName(meta, options), options.normalizeAccessors);
|
|
240
253
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
254
|
+
Utils.keys(data).forEach(key => {
|
|
255
|
+
helper(entity)?.__loadedProperties.add(key);
|
|
256
|
+
helper(entity)?.__serializationContext.fields?.add(key);
|
|
244
257
|
});
|
|
258
|
+
const processOnCreateHooksEarly = options.processOnCreateHooksEarly ?? this.config.get('processOnCreateHooksEarly');
|
|
259
|
+
if (options.newEntity && processOnCreateHooksEarly) {
|
|
260
|
+
this.assignDefaultValues(entity, meta);
|
|
261
|
+
}
|
|
245
262
|
}
|
|
246
263
|
findEntity(data, meta, options) {
|
|
247
264
|
const schema = this.driver.getSchemaName(meta, options);
|
|
@@ -251,7 +268,7 @@ class EntityFactory {
|
|
|
251
268
|
if (!Array.isArray(data) && meta.primaryKeys.some(pk => data[pk] == null)) {
|
|
252
269
|
return undefined;
|
|
253
270
|
}
|
|
254
|
-
const pks =
|
|
271
|
+
const pks = Utils.getOrderedPrimaryKeys(data, meta, this.platform, options.convertCustomTypes);
|
|
255
272
|
return this.unitOfWork.getById(meta.className, pks, schema);
|
|
256
273
|
}
|
|
257
274
|
processDiscriminatorColumn(meta, data) {
|
|
@@ -267,69 +284,73 @@ class EntityFactory {
|
|
|
267
284
|
/**
|
|
268
285
|
* denormalize PK to value required by driver (e.g. ObjectId)
|
|
269
286
|
*/
|
|
270
|
-
denormalizePrimaryKey(
|
|
271
|
-
const pk =
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
data[
|
|
287
|
+
denormalizePrimaryKey(meta, data) {
|
|
288
|
+
const pk = meta.getPrimaryProp();
|
|
289
|
+
const spk = meta.properties[meta.serializedPrimaryKey];
|
|
290
|
+
if (!spk?.serializedPrimaryKey) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
if (pk.type === 'ObjectId' && (data[pk.name] != null || data[spk.name] != null)) {
|
|
294
|
+
data[pk.name] = this.platform.denormalizePrimaryKey((data[spk.name] || data[pk.name]));
|
|
295
|
+
delete data[spk.name];
|
|
279
296
|
}
|
|
280
297
|
}
|
|
281
298
|
/**
|
|
282
299
|
* returns parameters for entity constructor, creating references from plain ids
|
|
283
300
|
*/
|
|
284
301
|
extractConstructorParams(meta, data, options) {
|
|
302
|
+
if (!meta.constructorParams) {
|
|
303
|
+
return [data];
|
|
304
|
+
}
|
|
285
305
|
return meta.constructorParams.map(k => {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
306
|
+
const prop = meta.properties[k];
|
|
307
|
+
const value = data[k];
|
|
308
|
+
if (prop && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && value) {
|
|
309
|
+
const pk = Reference.unwrapReference(value);
|
|
310
|
+
const entity = this.unitOfWork.getById(prop.type, pk, options.schema, true);
|
|
289
311
|
if (entity) {
|
|
290
312
|
return entity;
|
|
291
313
|
}
|
|
292
|
-
if (
|
|
293
|
-
return
|
|
314
|
+
if (Utils.isEntity(value)) {
|
|
315
|
+
return value;
|
|
294
316
|
}
|
|
295
|
-
const nakedPk =
|
|
296
|
-
if (
|
|
297
|
-
return this.create(
|
|
317
|
+
const nakedPk = Utils.extractPK(value, prop.targetMeta, true);
|
|
318
|
+
if (Utils.isObject(value) && !nakedPk) {
|
|
319
|
+
return this.create(prop.type, value, options);
|
|
298
320
|
}
|
|
299
321
|
const { newEntity, initialized, ...rest } = options;
|
|
300
|
-
const target = this.createReference(
|
|
301
|
-
return
|
|
322
|
+
const target = this.createReference(prop.type, nakedPk, rest);
|
|
323
|
+
return Reference.wrapReference(target, prop);
|
|
302
324
|
}
|
|
303
|
-
if (
|
|
304
|
-
/*
|
|
305
|
-
if (
|
|
306
|
-
return
|
|
325
|
+
if (prop?.kind === ReferenceKind.EMBEDDED && value) {
|
|
326
|
+
/* v8 ignore next */
|
|
327
|
+
if (Utils.isEntity(value)) {
|
|
328
|
+
return value;
|
|
307
329
|
}
|
|
308
|
-
return this.createEmbeddable(
|
|
330
|
+
return this.createEmbeddable(prop.type, value, options);
|
|
309
331
|
}
|
|
310
|
-
if (!
|
|
332
|
+
if (!prop) {
|
|
311
333
|
const tmp = { ...data };
|
|
312
334
|
for (const prop of meta.props) {
|
|
313
335
|
if (!options.convertCustomTypes || !prop.customType || tmp[prop.name] == null) {
|
|
314
336
|
continue;
|
|
315
337
|
}
|
|
316
|
-
if ([
|
|
317
|
-
tmp[prop.name] =
|
|
338
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(tmp[prop.name]) && !Utils.extractPK(tmp[prop.name], meta.properties[prop.name].targetMeta, true)) {
|
|
339
|
+
tmp[prop.name] = Reference.wrapReference(this.create(meta.properties[prop.name].type, tmp[prop.name], options), prop);
|
|
318
340
|
}
|
|
319
|
-
else if (prop.kind ===
|
|
341
|
+
else if (prop.kind === ReferenceKind.SCALAR) {
|
|
320
342
|
tmp[prop.name] = prop.customType.convertToJSValue(tmp[prop.name], this.platform);
|
|
321
343
|
}
|
|
322
344
|
}
|
|
323
345
|
return tmp;
|
|
324
346
|
}
|
|
325
|
-
if (options.convertCustomTypes &&
|
|
326
|
-
return
|
|
347
|
+
if (options.convertCustomTypes && prop.customType && value != null) {
|
|
348
|
+
return prop.customType.convertToJSValue(value, this.platform);
|
|
327
349
|
}
|
|
328
|
-
return
|
|
350
|
+
return value;
|
|
329
351
|
});
|
|
330
352
|
}
|
|
331
353
|
get unitOfWork() {
|
|
332
354
|
return this.em.getUnitOfWork(false);
|
|
333
355
|
}
|
|
334
356
|
}
|
|
335
|
-
exports.EntityFactory = EntityFactory;
|
package/entity/EntityHelper.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { EntityManager } from '../EntityManager';
|
|
2
|
-
import { type EntityMetadata, type EntityProperty, type IHydrator } from '../typings';
|
|
1
|
+
import type { EntityManager } from '../EntityManager.js';
|
|
2
|
+
import { type EntityMetadata, type EntityProperty, type IHydrator } from '../typings.js';
|
|
3
3
|
/**
|
|
4
4
|
* @internal
|
|
5
5
|
*/
|