@mikro-orm/core 7.0.0-dev.1 → 7.0.0-dev.11
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 +25 -16
- package/EntityManager.js +219 -209
- package/MikroORM.d.ts +7 -6
- package/MikroORM.js +33 -45
- package/cache/CacheAdapter.js +1 -2
- package/cache/FileCacheAdapter.d.ts +1 -1
- package/cache/FileCacheAdapter.js +18 -26
- package/cache/GeneratedCacheAdapter.d.ts +2 -2
- package/cache/GeneratedCacheAdapter.js +1 -5
- 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 +5 -5
- package/cache/index.js +5 -21
- package/connections/Connection.d.ts +7 -7
- package/connections/Connection.js +8 -12
- package/connections/index.d.ts +1 -1
- package/connections/index.js +1 -17
- package/decorators/Check.d.ts +2 -2
- package/decorators/Check.js +5 -8
- package/decorators/CreateRequestContext.d.ts +1 -1
- package/decorators/CreateRequestContext.js +13 -14
- package/decorators/Embeddable.d.ts +5 -5
- package/decorators/Embeddable.js +4 -7
- package/decorators/Embedded.d.ts +3 -3
- package/decorators/Embedded.js +10 -12
- package/decorators/Entity.d.ts +6 -6
- package/decorators/Entity.js +5 -9
- package/decorators/Enum.d.ts +3 -3
- package/decorators/Enum.js +7 -10
- package/decorators/Filter.d.ts +1 -1
- package/decorators/Filter.js +3 -6
- package/decorators/Formula.d.ts +2 -3
- package/decorators/Formula.js +7 -10
- package/decorators/Indexed.d.ts +10 -8
- package/decorators/Indexed.js +7 -11
- package/decorators/ManyToMany.d.ts +4 -4
- package/decorators/ManyToMany.js +10 -12
- package/decorators/ManyToOne.d.ts +4 -4
- package/decorators/ManyToOne.js +10 -12
- package/decorators/OneToMany.d.ts +6 -6
- package/decorators/OneToMany.js +11 -14
- package/decorators/OneToOne.d.ts +4 -4
- package/decorators/OneToOne.js +4 -7
- package/decorators/PrimaryKey.d.ts +3 -4
- package/decorators/PrimaryKey.js +10 -13
- package/decorators/Property.d.ts +6 -6
- package/decorators/Property.js +10 -12
- package/decorators/Transactional.d.ts +2 -2
- package/decorators/Transactional.js +7 -10
- package/decorators/hooks.js +23 -35
- package/decorators/index.d.ts +17 -17
- package/decorators/index.js +17 -36
- package/drivers/DatabaseDriver.d.ts +13 -12
- package/drivers/DatabaseDriver.js +60 -64
- package/drivers/IDatabaseDriver.d.ts +16 -13
- package/drivers/IDatabaseDriver.js +1 -4
- package/drivers/index.d.ts +2 -2
- package/drivers/index.js +2 -18
- package/entity/ArrayCollection.d.ts +3 -3
- package/entity/ArrayCollection.js +38 -35
- package/entity/BaseEntity.d.ts +6 -6
- package/entity/BaseEntity.js +17 -21
- package/entity/Collection.d.ts +6 -7
- package/entity/Collection.js +47 -51
- package/entity/EntityAssigner.d.ts +2 -2
- package/entity/EntityAssigner.js +58 -63
- package/entity/EntityFactory.d.ts +3 -3
- package/entity/EntityFactory.js +62 -63
- package/entity/EntityHelper.d.ts +2 -2
- package/entity/EntityHelper.js +44 -45
- package/entity/EntityIdentifier.d.ts +1 -1
- package/entity/EntityIdentifier.js +1 -5
- package/entity/EntityLoader.d.ts +5 -5
- package/entity/EntityLoader.js +106 -98
- package/entity/EntityRepository.d.ts +7 -7
- package/entity/EntityRepository.js +7 -11
- package/entity/EntityValidator.d.ts +1 -1
- package/entity/EntityValidator.js +25 -29
- package/entity/Reference.d.ts +4 -8
- package/entity/Reference.js +35 -42
- package/entity/WrappedEntity.d.ts +12 -12
- package/entity/WrappedEntity.js +23 -27
- package/entity/index.d.ts +13 -13
- package/entity/index.js +13 -29
- package/entity/utils.d.ts +1 -1
- package/entity/utils.js +9 -12
- package/entity/wrap.d.ts +1 -1
- package/entity/wrap.js +2 -6
- package/enums.d.ts +3 -3
- package/enums.js +37 -41
- package/errors.d.ts +1 -1
- package/errors.js +15 -24
- package/events/EventManager.d.ts +3 -3
- package/events/EventManager.js +8 -12
- 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 +3 -6
- package/hydration/ObjectHydrator.d.ts +3 -3
- package/hydration/ObjectHydrator.js +26 -28
- package/hydration/index.d.ts +2 -2
- package/hydration/index.js +2 -18
- package/index.d.ts +21 -21
- package/index.js +21 -46
- package/logging/DefaultLogger.d.ts +1 -1
- package/logging/DefaultLogger.js +9 -13
- package/logging/Logger.d.ts +1 -1
- package/logging/Logger.js +1 -2
- package/logging/SimpleLogger.d.ts +2 -2
- package/logging/SimpleLogger.js +2 -6
- package/logging/colors.js +1 -5
- package/logging/index.d.ts +4 -4
- package/logging/index.js +4 -20
- package/metadata/EntitySchema.d.ts +14 -6
- package/metadata/EntitySchema.js +41 -45
- package/metadata/MetadataDiscovery.d.ts +7 -7
- package/metadata/MetadataDiscovery.js +181 -180
- package/metadata/MetadataProvider.d.ts +2 -2
- package/metadata/MetadataProvider.js +4 -7
- package/metadata/MetadataStorage.d.ts +2 -2
- package/metadata/MetadataStorage.js +15 -19
- package/metadata/MetadataValidator.d.ts +4 -4
- package/metadata/MetadataValidator.js +52 -55
- package/metadata/ReflectMetadataProvider.d.ts +2 -2
- package/metadata/ReflectMetadataProvider.js +8 -12
- package/metadata/index.d.ts +6 -6
- package/metadata/index.js +6 -22
- package/naming-strategy/AbstractNamingStrategy.d.ts +2 -2
- package/naming-strategy/AbstractNamingStrategy.js +4 -8
- 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 +1 -1
- 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/package.json +6 -15
- package/platforms/ExceptionConverter.d.ts +2 -2
- package/platforms/ExceptionConverter.js +4 -8
- package/platforms/Platform.d.ts +10 -10
- package/platforms/Platform.js +57 -61
- package/platforms/index.d.ts +2 -2
- package/platforms/index.js +2 -18
- package/serialization/EntitySerializer.d.ts +2 -2
- package/serialization/EntitySerializer.js +36 -41
- package/serialization/EntityTransformer.d.ts +1 -1
- package/serialization/EntityTransformer.js +27 -31
- package/serialization/SerializationContext.d.ts +2 -2
- package/serialization/SerializationContext.js +10 -14
- package/serialization/index.d.ts +3 -3
- package/serialization/index.js +3 -19
- package/types/ArrayType.d.ts +3 -3
- package/types/ArrayType.js +7 -11
- package/types/BigIntType.d.ts +4 -3
- package/types/BigIntType.js +6 -6
- package/types/BlobType.d.ts +3 -3
- package/types/BlobType.js +2 -8
- package/types/BooleanType.d.ts +3 -3
- package/types/BooleanType.js +2 -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 +3 -3
- package/types/DecimalType.js +4 -7
- package/types/DoubleType.d.ts +3 -3
- package/types/DoubleType.js +3 -6
- package/types/EnumArrayType.d.ts +4 -4
- package/types/EnumArrayType.js +5 -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 +3 -3
- package/types/JsonType.js +2 -6
- 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 +2 -2
- package/types/Type.js +5 -9
- package/types/Uint8ArrayType.d.ts +3 -3
- package/types/Uint8ArrayType.js +3 -9
- 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 +33 -28
- package/typings.js +37 -38
- package/unit-of-work/ChangeSet.d.ts +1 -1
- package/unit-of-work/ChangeSet.js +13 -17
- package/unit-of-work/ChangeSetComputer.d.ts +8 -7
- package/unit-of-work/ChangeSetComputer.js +26 -30
- package/unit-of-work/ChangeSetPersister.d.ts +7 -6
- package/unit-of-work/ChangeSetPersister.js +51 -48
- 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 +8 -7
- package/unit-of-work/UnitOfWork.js +193 -178
- package/unit-of-work/index.d.ts +6 -6
- package/unit-of-work/index.js +6 -22
- package/utils/AbstractSchemaGenerator.d.ts +6 -6
- package/utils/AbstractSchemaGenerator.js +12 -13
- package/utils/Configuration.d.ts +26 -27
- package/utils/Configuration.js +50 -55
- package/utils/ConfigurationLoader.d.ts +9 -8
- package/utils/ConfigurationLoader.js +71 -86
- package/utils/Cursor.d.ts +6 -6
- package/utils/Cursor.js +22 -25
- package/utils/DataloaderUtils.d.ts +4 -4
- package/utils/DataloaderUtils.js +12 -16
- package/utils/EntityComparator.d.ts +2 -2
- package/utils/EntityComparator.js +109 -97
- package/utils/NullHighlighter.d.ts +1 -1
- package/utils/NullHighlighter.js +1 -5
- package/utils/QueryHelper.d.ts +3 -3
- package/utils/QueryHelper.js +47 -51
- package/utils/RawQueryFragment.d.ts +1 -1
- package/utils/RawQueryFragment.js +22 -25
- 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/Utils.d.ts +16 -12
- package/utils/Utils.js +96 -95
- package/utils/clone.js +8 -11
- package/utils/index.d.ts +13 -13
- package/utils/index.js +13 -29
- package/utils/resolveContextProvider.d.ts +3 -3
- package/utils/resolveContextProvider.js +9 -12
- package/utils/upsert-utils.d.ts +3 -3
- package/utils/upsert-utils.js +5 -9
- package/index.mjs +0 -199
package/entity/EntityAssigner.js
CHANGED
|
@@ -1,25 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
const EntityHelper_1 = require("./EntityHelper");
|
|
12
|
-
const validator = new EntityValidator_1.EntityValidator(false);
|
|
13
|
-
class EntityAssigner {
|
|
1
|
+
import { inspect } from 'node:util';
|
|
2
|
+
import { Collection } from './Collection.js';
|
|
3
|
+
import { Utils } from '../utils/Utils.js';
|
|
4
|
+
import { Reference } from './Reference.js';
|
|
5
|
+
import { ReferenceKind, SCALAR_TYPES } from '../enums.js';
|
|
6
|
+
import { EntityValidator } from './EntityValidator.js';
|
|
7
|
+
import { helper, wrap } from './wrap.js';
|
|
8
|
+
import { EntityHelper } from './EntityHelper.js';
|
|
9
|
+
const validator = new EntityValidator(false);
|
|
10
|
+
export class EntityAssigner {
|
|
14
11
|
static assign(entity, data, options = {}) {
|
|
15
12
|
let opts = options;
|
|
16
13
|
if (opts.visited?.has(entity)) {
|
|
17
14
|
return entity;
|
|
18
15
|
}
|
|
19
|
-
|
|
16
|
+
EntityHelper.ensurePropagation(entity);
|
|
20
17
|
opts.visited ??= new Set();
|
|
21
18
|
opts.visited.add(entity);
|
|
22
|
-
const wrapped =
|
|
19
|
+
const wrapped = helper(entity);
|
|
23
20
|
opts = {
|
|
24
21
|
...wrapped.__config.get('assign'),
|
|
25
22
|
schema: wrapped.__schema,
|
|
@@ -45,37 +42,37 @@ class EntityAssigner {
|
|
|
45
42
|
}
|
|
46
43
|
const prop = { ...props[propName], name: propName };
|
|
47
44
|
if (prop && options.onlyOwnProperties) {
|
|
48
|
-
if ([
|
|
45
|
+
if ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop.kind)) {
|
|
49
46
|
return;
|
|
50
47
|
}
|
|
51
|
-
if ([
|
|
52
|
-
value =
|
|
48
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
|
|
49
|
+
value = Utils.extractPK(value, prop.targetMeta);
|
|
53
50
|
}
|
|
54
51
|
}
|
|
55
52
|
if (propName in props && !prop.nullable && value == null) {
|
|
56
53
|
throw new Error(`You must pass a non-${value} value to the property ${propName} of entity ${entity.constructor.name}.`);
|
|
57
54
|
}
|
|
58
55
|
// create collection instance if its missing so old items can be deleted with orphan removal
|
|
59
|
-
if ([
|
|
60
|
-
entity[prop.name] =
|
|
56
|
+
if ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop?.kind) && entity[prop.name] == null) {
|
|
57
|
+
entity[prop.name] = Collection.create(entity, prop.name, undefined, helper(entity).isInitialized());
|
|
61
58
|
}
|
|
62
|
-
if (prop &&
|
|
59
|
+
if (prop && Utils.isCollection(entity[prop.name])) {
|
|
63
60
|
return EntityAssigner.assignCollection(entity, entity[prop.name], value, prop, options.em, options);
|
|
64
61
|
}
|
|
65
62
|
const customType = prop?.customType;
|
|
66
|
-
if (options.convertCustomTypes && customType && prop.kind ===
|
|
63
|
+
if (options.convertCustomTypes && customType && prop.kind === ReferenceKind.SCALAR && !Utils.isEntity(data)) {
|
|
67
64
|
value = customType.convertToJSValue(value, options.platform);
|
|
68
65
|
}
|
|
69
|
-
if ([
|
|
70
|
-
if (options.updateNestedEntities && Object.hasOwn(entity, propName) &&
|
|
71
|
-
const unwrappedEntity =
|
|
72
|
-
const wrapped =
|
|
66
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop?.kind) && value != null) {
|
|
67
|
+
if (options.updateNestedEntities && Object.hasOwn(entity, propName) && Utils.isEntity(entity[propName], true) && Utils.isPlainObject(value)) {
|
|
68
|
+
const unwrappedEntity = Reference.unwrapReference(entity[propName]);
|
|
69
|
+
const wrapped = helper(unwrappedEntity);
|
|
73
70
|
if (options.updateByPrimaryKey) {
|
|
74
|
-
const pk =
|
|
71
|
+
const pk = Utils.extractPK(value, prop.targetMeta);
|
|
75
72
|
if (pk) {
|
|
76
73
|
const ref = options.em.getReference(prop.type, pk, options);
|
|
77
74
|
// if the PK differs, we want to change the target entity, not update it
|
|
78
|
-
const wrappedChild =
|
|
75
|
+
const wrappedChild = helper(ref);
|
|
79
76
|
const sameTarget = wrappedChild.getSerializedPrimaryKey() === wrapped.getSerializedPrimaryKey();
|
|
80
77
|
if (wrappedChild.__managed && wrappedChild.isInitialized() && sameTarget) {
|
|
81
78
|
return EntityAssigner.assign(ref, value, options);
|
|
@@ -83,21 +80,21 @@ class EntityAssigner {
|
|
|
83
80
|
}
|
|
84
81
|
return EntityAssigner.assignReference(entity, value, prop, options.em, options);
|
|
85
82
|
}
|
|
86
|
-
if (wrapped.__managed &&
|
|
83
|
+
if (wrapped.__managed && wrap(unwrappedEntity).isInitialized()) {
|
|
87
84
|
return EntityAssigner.assign(unwrappedEntity, value, options);
|
|
88
85
|
}
|
|
89
86
|
}
|
|
90
87
|
return EntityAssigner.assignReference(entity, value, prop, options.em, options);
|
|
91
88
|
}
|
|
92
|
-
if (prop.kind ===
|
|
89
|
+
if (prop.kind === ReferenceKind.SCALAR && SCALAR_TYPES.includes(prop.runtimeType) && (prop.setter || !prop.getter)) {
|
|
93
90
|
return entity[prop.name] = validator.validateProperty(prop, value, entity);
|
|
94
91
|
}
|
|
95
|
-
if (prop.kind ===
|
|
92
|
+
if (prop.kind === ReferenceKind.EMBEDDED && EntityAssigner.validateEM(options.em)) {
|
|
96
93
|
return EntityAssigner.assignEmbeddable(entity, value, prop, options.em, options);
|
|
97
94
|
}
|
|
98
|
-
if (options.mergeObjectProperties &&
|
|
95
|
+
if (options.mergeObjectProperties && Utils.isPlainObject(entity[propName]) && Utils.isPlainObject(value)) {
|
|
99
96
|
entity[propName] ??= {};
|
|
100
|
-
entity[propName] =
|
|
97
|
+
entity[propName] = Utils.merge({}, entity[propName], value);
|
|
101
98
|
}
|
|
102
99
|
else if (!prop || prop.setter || !prop.getter) {
|
|
103
100
|
entity[propName] = value;
|
|
@@ -110,18 +107,18 @@ class EntityAssigner {
|
|
|
110
107
|
*/
|
|
111
108
|
static autoWireOneToOne(prop, entity) {
|
|
112
109
|
const ref = entity[prop.name];
|
|
113
|
-
if (prop.kind !==
|
|
110
|
+
if (prop.kind !== ReferenceKind.ONE_TO_ONE || !Utils.isEntity(ref)) {
|
|
114
111
|
return;
|
|
115
112
|
}
|
|
116
|
-
const meta2 =
|
|
113
|
+
const meta2 = helper(ref).__meta;
|
|
117
114
|
const prop2 = meta2.properties[prop.inversedBy || prop.mappedBy];
|
|
118
|
-
/*
|
|
115
|
+
/* v8 ignore next 7 */
|
|
119
116
|
if (prop2 && !ref[prop2.name]) {
|
|
120
|
-
if (
|
|
121
|
-
ref.unwrap()[prop2.name] =
|
|
117
|
+
if (Reference.isReference(ref)) {
|
|
118
|
+
ref.unwrap()[prop2.name] = Reference.wrapReference(entity, prop2);
|
|
122
119
|
}
|
|
123
120
|
else {
|
|
124
|
-
ref[prop2.name] =
|
|
121
|
+
ref[prop2.name] = Reference.wrapReference(entity, prop2);
|
|
125
122
|
}
|
|
126
123
|
}
|
|
127
124
|
}
|
|
@@ -132,17 +129,17 @@ class EntityAssigner {
|
|
|
132
129
|
return true;
|
|
133
130
|
}
|
|
134
131
|
static assignReference(entity, value, prop, em, options) {
|
|
135
|
-
if (
|
|
136
|
-
entity[prop.name] =
|
|
132
|
+
if (Utils.isEntity(value, true)) {
|
|
133
|
+
entity[prop.name] = Reference.wrapReference(value, prop);
|
|
137
134
|
}
|
|
138
|
-
else if (
|
|
139
|
-
entity[prop.name] = prop.mapToPk ? value :
|
|
135
|
+
else if (Utils.isPrimaryKey(value, true) && EntityAssigner.validateEM(em)) {
|
|
136
|
+
entity[prop.name] = prop.mapToPk ? value : Reference.wrapReference(em.getReference(prop.type, value, options), prop);
|
|
140
137
|
}
|
|
141
|
-
else if (
|
|
142
|
-
entity[prop.name] =
|
|
138
|
+
else if (Utils.isPlainObject(value) && options.merge && EntityAssigner.validateEM(em)) {
|
|
139
|
+
entity[prop.name] = Reference.wrapReference(em.merge(prop.type, value, options), prop);
|
|
143
140
|
}
|
|
144
|
-
else if (
|
|
145
|
-
entity[prop.name] =
|
|
141
|
+
else if (Utils.isPlainObject(value) && EntityAssigner.validateEM(em)) {
|
|
142
|
+
entity[prop.name] = Reference.wrapReference(em.create(prop.type, value, options), prop);
|
|
146
143
|
}
|
|
147
144
|
else {
|
|
148
145
|
const name = entity.constructor.name;
|
|
@@ -152,32 +149,31 @@ class EntityAssigner {
|
|
|
152
149
|
}
|
|
153
150
|
static assignCollection(entity, collection, value, prop, em, options) {
|
|
154
151
|
const invalid = [];
|
|
155
|
-
const items =
|
|
152
|
+
const items = Utils.asArray(value).map((item, idx) => {
|
|
156
153
|
// try to propagate missing owning side reference to the payload first
|
|
157
154
|
const prop2 = prop.targetMeta?.properties[prop.mappedBy];
|
|
158
|
-
if (
|
|
159
|
-
item = { ...item, [prop2.name]:
|
|
155
|
+
if (Utils.isPlainObject(item) && prop2 && item[prop2.name] == null) {
|
|
156
|
+
item = { ...item, [prop2.name]: Reference.wrapReference(entity, prop2) };
|
|
160
157
|
}
|
|
161
|
-
if (options.updateNestedEntities && options.updateByPrimaryKey &&
|
|
162
|
-
const pk =
|
|
158
|
+
if (options.updateNestedEntities && options.updateByPrimaryKey && Utils.isPlainObject(item)) {
|
|
159
|
+
const pk = Utils.extractPK(item, prop.targetMeta);
|
|
163
160
|
if (pk && EntityAssigner.validateEM(em)) {
|
|
164
161
|
const ref = em.getUnitOfWork().getById(prop.type, pk, options.schema);
|
|
165
|
-
/* istanbul ignore else */
|
|
166
162
|
if (ref) {
|
|
167
163
|
return EntityAssigner.assign(ref, item, options);
|
|
168
164
|
}
|
|
169
165
|
}
|
|
170
166
|
return this.createCollectionItem(item, em, prop, invalid, options);
|
|
171
167
|
}
|
|
172
|
-
/*
|
|
173
|
-
if (options.updateNestedEntities && !options.updateByPrimaryKey && collection[idx] &&
|
|
168
|
+
/* v8 ignore next 3 */
|
|
169
|
+
if (options.updateNestedEntities && !options.updateByPrimaryKey && collection[idx] && helper(collection[idx])?.isInitialized()) {
|
|
174
170
|
return EntityAssigner.assign(collection[idx], item, options);
|
|
175
171
|
}
|
|
176
172
|
return this.createCollectionItem(item, em, prop, invalid, options);
|
|
177
173
|
});
|
|
178
174
|
if (invalid.length > 0) {
|
|
179
175
|
const name = entity.constructor.name;
|
|
180
|
-
throw new Error(`Invalid collection values provided for '${name}.${prop.name}' in ${name}.assign(): ${
|
|
176
|
+
throw new Error(`Invalid collection values provided for '${name}.${prop.name}' in ${name}.assign(): ${inspect(invalid)}`);
|
|
181
177
|
}
|
|
182
178
|
if (Array.isArray(value)) {
|
|
183
179
|
collection.set(items);
|
|
@@ -197,7 +193,7 @@ class EntityAssigner {
|
|
|
197
193
|
entity[propName] = [];
|
|
198
194
|
}
|
|
199
195
|
if (prop.array) {
|
|
200
|
-
return
|
|
196
|
+
return Utils.asArray(value).forEach(item => {
|
|
201
197
|
const tmp = {};
|
|
202
198
|
this.assignEmbeddable(tmp, item, { ...prop, array: false }, em, options);
|
|
203
199
|
entity[propName].push(...Object.values(tmp));
|
|
@@ -213,21 +209,20 @@ class EntityAssigner {
|
|
|
213
209
|
});
|
|
214
210
|
}
|
|
215
211
|
static createCollectionItem(item, em, prop, invalid, options) {
|
|
216
|
-
if (
|
|
212
|
+
if (Utils.isEntity(item)) {
|
|
217
213
|
return item;
|
|
218
214
|
}
|
|
219
|
-
if (
|
|
215
|
+
if (Utils.isPrimaryKey(item) && EntityAssigner.validateEM(em)) {
|
|
220
216
|
return em.getReference(prop.type, item, options);
|
|
221
217
|
}
|
|
222
|
-
if (
|
|
218
|
+
if (Utils.isPlainObject(item) && options.merge && EntityAssigner.validateEM(em)) {
|
|
223
219
|
return em.merge(prop.type, item, options);
|
|
224
220
|
}
|
|
225
|
-
if (
|
|
221
|
+
if (Utils.isPlainObject(item) && EntityAssigner.validateEM(em)) {
|
|
226
222
|
return em.create(prop.type, item, options);
|
|
227
223
|
}
|
|
228
224
|
invalid.push(item);
|
|
229
225
|
return item;
|
|
230
226
|
}
|
|
231
227
|
}
|
|
232
|
-
|
|
233
|
-
exports.assign = EntityAssigner.assign;
|
|
228
|
+
export const assign = EntityAssigner.assign;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { EntityData, EntityMetadata, EntityName, New, Primary } from '../typings';
|
|
2
|
-
import type { EntityManager } from '../EntityManager';
|
|
3
|
-
import type { EntityComparator } from '../utils/EntityComparator';
|
|
1
|
+
import type { EntityData, EntityMetadata, EntityName, New, Primary } from '../typings.js';
|
|
2
|
+
import type { EntityManager } from '../EntityManager.js';
|
|
3
|
+
import type { EntityComparator } from '../utils/EntityComparator.js';
|
|
4
4
|
export interface FactoryOptions {
|
|
5
5
|
initialized?: boolean;
|
|
6
6
|
newEntity?: boolean;
|
package/entity/EntityFactory.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const wrap_1 = require("./wrap");
|
|
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
|
+
export class EntityFactory {
|
|
11
8
|
em;
|
|
12
9
|
driver;
|
|
13
10
|
platform;
|
|
@@ -27,12 +24,12 @@ class EntityFactory {
|
|
|
27
24
|
this.comparator = this.em.getComparator();
|
|
28
25
|
}
|
|
29
26
|
create(entityName, data, options = {}) {
|
|
30
|
-
data =
|
|
27
|
+
data = Reference.unwrapReference(data);
|
|
31
28
|
options.initialized ??= true;
|
|
32
29
|
if (data.__entity) {
|
|
33
30
|
return data;
|
|
34
31
|
}
|
|
35
|
-
entityName =
|
|
32
|
+
entityName = Utils.className(entityName);
|
|
36
33
|
const meta = this.metadata.get(entityName);
|
|
37
34
|
if (meta.virtual) {
|
|
38
35
|
data = { ...data };
|
|
@@ -45,9 +42,10 @@ class EntityFactory {
|
|
|
45
42
|
}
|
|
46
43
|
const meta2 = this.processDiscriminatorColumn(meta, data);
|
|
47
44
|
const exists = this.findEntity(data, meta2, options);
|
|
48
|
-
let wrapped = exists &&
|
|
45
|
+
let wrapped = exists && helper(exists);
|
|
49
46
|
if (wrapped && !options.refresh) {
|
|
50
47
|
wrapped.__processing = true;
|
|
48
|
+
Utils.dropUndefinedProperties(data);
|
|
51
49
|
this.mergeData(meta2, exists, data, options);
|
|
52
50
|
wrapped.__processing = false;
|
|
53
51
|
if (wrapped.isInitialized()) {
|
|
@@ -56,7 +54,7 @@ class EntityFactory {
|
|
|
56
54
|
}
|
|
57
55
|
data = { ...data };
|
|
58
56
|
const entity = exists ?? this.createEntity(data, meta2, options);
|
|
59
|
-
wrapped =
|
|
57
|
+
wrapped = helper(entity);
|
|
60
58
|
wrapped.__processing = true;
|
|
61
59
|
wrapped.__initialized = options.initialized;
|
|
62
60
|
if (options.newEntity || meta.forceConstructor || meta.virtual) {
|
|
@@ -69,11 +67,11 @@ class EntityFactory {
|
|
|
69
67
|
if (options.convertCustomTypes) {
|
|
70
68
|
for (const prop of meta.props) {
|
|
71
69
|
if (prop.customType?.ensureComparable(meta, prop) && data[prop.name]) {
|
|
72
|
-
if ([
|
|
70
|
+
if ([ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind)) {
|
|
73
71
|
continue;
|
|
74
72
|
}
|
|
75
|
-
if ([
|
|
76
|
-
data[prop.name] =
|
|
73
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name])) {
|
|
74
|
+
data[prop.name] = Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta.primaryKeys, true);
|
|
77
75
|
}
|
|
78
76
|
data[prop.name] = prop.customType.convertToDatabaseValue(data[prop.name], this.platform, { key: prop.name, mode: 'hydration' });
|
|
79
77
|
}
|
|
@@ -89,7 +87,9 @@ class EntityFactory {
|
|
|
89
87
|
}
|
|
90
88
|
if (options.merge && wrapped.hasPrimaryKey()) {
|
|
91
89
|
this.unitOfWork.register(entity, data, {
|
|
92
|
-
refresh
|
|
90
|
+
// Always refresh to ensure the payload is in correct shape for joined strategy. When loading nested relations,
|
|
91
|
+
// they will be created early without `Type.ensureComparable` being properly handled, resulting in extra updates.
|
|
92
|
+
refresh: options.initialized,
|
|
93
93
|
newEntity: options.newEntity,
|
|
94
94
|
loaded: options.initialized,
|
|
95
95
|
});
|
|
@@ -97,17 +97,17 @@ class EntityFactory {
|
|
|
97
97
|
wrapped.__originalEntityData = this.comparator.prepareEntity(entity);
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
-
if (this.eventManager.hasListeners(
|
|
101
|
-
this.eventManager.dispatchEvent(
|
|
100
|
+
if (this.eventManager.hasListeners(EventType.onInit, meta2)) {
|
|
101
|
+
this.eventManager.dispatchEvent(EventType.onInit, { entity, meta: meta2, em: this.em });
|
|
102
102
|
}
|
|
103
103
|
wrapped.__processing = false;
|
|
104
104
|
return entity;
|
|
105
105
|
}
|
|
106
106
|
mergeData(meta, entity, data, options = {}) {
|
|
107
107
|
// merge unchanged properties automatically
|
|
108
|
-
data =
|
|
108
|
+
data = QueryHelper.processParams(data);
|
|
109
109
|
const existsData = this.comparator.prepareEntity(entity);
|
|
110
|
-
const originalEntityData =
|
|
110
|
+
const originalEntityData = helper(entity).__originalEntityData ?? {};
|
|
111
111
|
const diff = this.comparator.diffEntities(meta.className, originalEntityData, existsData);
|
|
112
112
|
// version properties are not part of entity snapshots
|
|
113
113
|
if (meta.versionProperty && data[meta.versionProperty] && data[meta.versionProperty] !== originalEntityData[meta.versionProperty]) {
|
|
@@ -115,8 +115,8 @@ class EntityFactory {
|
|
|
115
115
|
}
|
|
116
116
|
const diff2 = this.comparator.diffEntities(meta.className, existsData, data);
|
|
117
117
|
// do not override values changed by user
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
Utils.keys(diff).forEach(key => delete diff2[key]);
|
|
119
|
+
Utils.keys(diff2).filter(key => {
|
|
120
120
|
// ignore null values if there is already present non-null value
|
|
121
121
|
if (existsData[key] != null) {
|
|
122
122
|
return diff2[key] == null;
|
|
@@ -124,40 +124,40 @@ class EntityFactory {
|
|
|
124
124
|
return diff2[key] === undefined;
|
|
125
125
|
}).forEach(key => delete diff2[key]);
|
|
126
126
|
// but always add collection properties and formulas if they are part of the `data`
|
|
127
|
-
|
|
128
|
-
.filter(key => meta.properties[key]?.formula || [
|
|
127
|
+
Utils.keys(data)
|
|
128
|
+
.filter(key => meta.properties[key]?.formula || [ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(meta.properties[key]?.kind))
|
|
129
129
|
.forEach(key => diff2[key] = data[key]);
|
|
130
130
|
// rehydrated with the new values, skip those changed by user
|
|
131
131
|
this.hydrate(entity, meta, diff2, options);
|
|
132
132
|
// we need to update the entity data only with keys that were not present before
|
|
133
133
|
const nullVal = this.config.get('forceUndefined') ? undefined : null;
|
|
134
|
-
|
|
134
|
+
Utils.keys(diff2).forEach(key => {
|
|
135
135
|
const prop = meta.properties[key];
|
|
136
|
-
if ([
|
|
137
|
-
diff2[key] = entity[prop.name] ?
|
|
136
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name])) {
|
|
137
|
+
diff2[key] = entity[prop.name] ? helper(entity[prop.name]).getPrimaryKey(options.convertCustomTypes) : null;
|
|
138
138
|
}
|
|
139
139
|
originalEntityData[key] = diff2[key] === null ? nullVal : diff2[key];
|
|
140
|
-
|
|
140
|
+
helper(entity).__loadedProperties.add(key);
|
|
141
141
|
});
|
|
142
142
|
// in case of joined loading strategy, we need to cascade the merging to possibly loaded relations manually
|
|
143
143
|
meta.relations.forEach(prop => {
|
|
144
|
-
if ([
|
|
144
|
+
if ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop.kind) && Array.isArray(data[prop.name])) {
|
|
145
145
|
// instead of trying to match the collection items (which could easily fail if the collection was loaded with different ordering),
|
|
146
146
|
// we just create the entity from scratch, which will automatically pick the right one from the identity map and call `mergeData` on it
|
|
147
147
|
data[prop.name]
|
|
148
|
-
.filter(child =>
|
|
148
|
+
.filter(child => Utils.isPlainObject(child)) // objects with prototype can be PKs (e.g. `ObjectId`)
|
|
149
149
|
.forEach(child => this.create(prop.type, child, options)); // we can ignore the value, we just care about the `mergeData` call
|
|
150
150
|
return;
|
|
151
151
|
}
|
|
152
|
-
if ([
|
|
152
|
+
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
153
|
this.create(prop.type, data[prop.name], options); // we can ignore the value, we just care about the `mergeData` call
|
|
154
154
|
}
|
|
155
155
|
});
|
|
156
|
-
|
|
156
|
+
helper(entity).__touched = false;
|
|
157
157
|
}
|
|
158
158
|
createReference(entityName, id, options = {}) {
|
|
159
159
|
options.convertCustomTypes ??= true;
|
|
160
|
-
entityName =
|
|
160
|
+
entityName = Utils.className(entityName);
|
|
161
161
|
const meta = this.metadata.get(entityName);
|
|
162
162
|
const schema = this.driver.getSchemaName(meta, options);
|
|
163
163
|
if (meta.simplePK) {
|
|
@@ -165,24 +165,24 @@ class EntityFactory {
|
|
|
165
165
|
if (exists) {
|
|
166
166
|
return exists;
|
|
167
167
|
}
|
|
168
|
-
const data =
|
|
168
|
+
const data = Utils.isPlainObject(id) ? id : { [meta.primaryKeys[0]]: Array.isArray(id) ? id[0] : id };
|
|
169
169
|
return this.create(entityName, data, { ...options, initialized: false });
|
|
170
170
|
}
|
|
171
171
|
if (Array.isArray(id)) {
|
|
172
|
-
id =
|
|
172
|
+
id = Utils.getPrimaryKeyCondFromArray(id, meta);
|
|
173
173
|
}
|
|
174
|
-
const pks =
|
|
174
|
+
const pks = Utils.getOrderedPrimaryKeys(id, meta, this.platform, options.convertCustomTypes);
|
|
175
175
|
const exists = this.unitOfWork.getById(entityName, pks, schema);
|
|
176
176
|
if (exists) {
|
|
177
177
|
return exists;
|
|
178
178
|
}
|
|
179
|
-
if (
|
|
179
|
+
if (Utils.isPrimaryKey(id)) {
|
|
180
180
|
id = { [meta.primaryKeys[0]]: id };
|
|
181
181
|
}
|
|
182
182
|
return this.create(entityName, id, { ...options, initialized: false });
|
|
183
183
|
}
|
|
184
184
|
createEmbeddable(entityName, data, options = {}) {
|
|
185
|
-
entityName =
|
|
185
|
+
entityName = Utils.className(entityName);
|
|
186
186
|
data = { ...data };
|
|
187
187
|
const meta = this.metadata.get(entityName);
|
|
188
188
|
const meta2 = this.processDiscriminatorColumn(meta, data);
|
|
@@ -211,23 +211,23 @@ class EntityFactory {
|
|
|
211
211
|
if (meta.virtual) {
|
|
212
212
|
return entity;
|
|
213
213
|
}
|
|
214
|
-
|
|
214
|
+
helper(entity).__schema = schema;
|
|
215
215
|
if (options.initialized) {
|
|
216
|
-
|
|
216
|
+
EntityHelper.ensurePropagation(entity);
|
|
217
217
|
}
|
|
218
218
|
return entity;
|
|
219
219
|
}
|
|
220
220
|
// creates new entity instance, bypassing constructor call as its already persisted entity
|
|
221
221
|
const entity = Object.create(meta.class.prototype);
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
helper(entity).__managed = true;
|
|
223
|
+
helper(entity).__processing = !meta.embeddable && !meta.virtual;
|
|
224
|
+
helper(entity).__schema = schema;
|
|
225
225
|
if (options.merge && !options.newEntity) {
|
|
226
226
|
this.hydrator.hydrateReference(entity, meta, data, this, options.convertCustomTypes, options.schema, options.parentSchema);
|
|
227
227
|
this.unitOfWork.register(entity);
|
|
228
228
|
}
|
|
229
229
|
if (options.initialized) {
|
|
230
|
-
|
|
230
|
+
EntityHelper.ensurePropagation(entity);
|
|
231
231
|
}
|
|
232
232
|
return entity;
|
|
233
233
|
}
|
|
@@ -238,9 +238,9 @@ class EntityFactory {
|
|
|
238
238
|
else {
|
|
239
239
|
this.hydrator.hydrateReference(entity, meta, data, this, options.convertCustomTypes, options.schema, this.driver.getSchemaName(meta, options));
|
|
240
240
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
241
|
+
Utils.keys(data).forEach(key => {
|
|
242
|
+
helper(entity)?.__loadedProperties.add(key);
|
|
243
|
+
helper(entity)?.__serializationContext.fields?.add(key);
|
|
244
244
|
});
|
|
245
245
|
}
|
|
246
246
|
findEntity(data, meta, options) {
|
|
@@ -251,7 +251,7 @@ class EntityFactory {
|
|
|
251
251
|
if (!Array.isArray(data) && meta.primaryKeys.some(pk => data[pk] == null)) {
|
|
252
252
|
return undefined;
|
|
253
253
|
}
|
|
254
|
-
const pks =
|
|
254
|
+
const pks = Utils.getOrderedPrimaryKeys(data, meta, this.platform);
|
|
255
255
|
return this.unitOfWork.getById(meta.className, pks, schema);
|
|
256
256
|
}
|
|
257
257
|
processDiscriminatorColumn(meta, data) {
|
|
@@ -283,26 +283,26 @@ class EntityFactory {
|
|
|
283
283
|
*/
|
|
284
284
|
extractConstructorParams(meta, data, options) {
|
|
285
285
|
return meta.constructorParams.map(k => {
|
|
286
|
-
if (meta.properties[k] && [
|
|
287
|
-
const pk =
|
|
286
|
+
if (meta.properties[k] && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(meta.properties[k].kind) && data[k]) {
|
|
287
|
+
const pk = Reference.unwrapReference(data[k]);
|
|
288
288
|
const entity = this.unitOfWork.getById(meta.properties[k].type, pk, options.schema);
|
|
289
289
|
if (entity) {
|
|
290
290
|
return entity;
|
|
291
291
|
}
|
|
292
|
-
if (
|
|
292
|
+
if (Utils.isEntity(data[k])) {
|
|
293
293
|
return data[k];
|
|
294
294
|
}
|
|
295
|
-
const nakedPk =
|
|
296
|
-
if (
|
|
295
|
+
const nakedPk = Utils.extractPK(data[k], meta.properties[k].targetMeta, true);
|
|
296
|
+
if (Utils.isObject(data[k]) && !nakedPk) {
|
|
297
297
|
return this.create(meta.properties[k].type, data[k], options);
|
|
298
298
|
}
|
|
299
299
|
const { newEntity, initialized, ...rest } = options;
|
|
300
300
|
const target = this.createReference(meta.properties[k].type, nakedPk, rest);
|
|
301
|
-
return
|
|
301
|
+
return Reference.wrapReference(target, meta.properties[k]);
|
|
302
302
|
}
|
|
303
|
-
if (meta.properties[k]?.kind ===
|
|
304
|
-
/*
|
|
305
|
-
if (
|
|
303
|
+
if (meta.properties[k]?.kind === ReferenceKind.EMBEDDED && data[k]) {
|
|
304
|
+
/* v8 ignore next 3 */
|
|
305
|
+
if (Utils.isEntity(data[k])) {
|
|
306
306
|
return data[k];
|
|
307
307
|
}
|
|
308
308
|
return this.createEmbeddable(meta.properties[k].type, data[k], options);
|
|
@@ -313,10 +313,10 @@ class EntityFactory {
|
|
|
313
313
|
if (!options.convertCustomTypes || !prop.customType || tmp[prop.name] == null) {
|
|
314
314
|
continue;
|
|
315
315
|
}
|
|
316
|
-
if ([
|
|
317
|
-
tmp[prop.name] =
|
|
316
|
+
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)) {
|
|
317
|
+
tmp[prop.name] = Reference.wrapReference(this.create(meta.properties[prop.name].type, tmp[prop.name], options), prop);
|
|
318
318
|
}
|
|
319
|
-
else if (prop.kind ===
|
|
319
|
+
else if (prop.kind === ReferenceKind.SCALAR) {
|
|
320
320
|
tmp[prop.name] = prop.customType.convertToJSValue(tmp[prop.name], this.platform);
|
|
321
321
|
}
|
|
322
322
|
}
|
|
@@ -332,4 +332,3 @@ class EntityFactory {
|
|
|
332
332
|
return this.em.getUnitOfWork(false);
|
|
333
333
|
}
|
|
334
334
|
}
|
|
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
|
*/
|