@mikro-orm/core 7.0.4-dev.8 → 7.0.4
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 +884 -583
- package/EntityManager.js +1922 -1895
- package/MikroORM.d.ts +103 -74
- package/MikroORM.js +178 -179
- package/README.md +1 -1
- package/cache/CacheAdapter.d.ts +36 -36
- package/cache/FileCacheAdapter.d.ts +30 -24
- package/cache/FileCacheAdapter.js +80 -78
- package/cache/GeneratedCacheAdapter.d.ts +18 -20
- package/cache/GeneratedCacheAdapter.js +30 -30
- package/cache/MemoryCacheAdapter.d.ts +18 -20
- package/cache/MemoryCacheAdapter.js +35 -36
- package/cache/NullCacheAdapter.d.ts +16 -16
- package/cache/NullCacheAdapter.js +24 -24
- package/connections/Connection.d.ts +95 -84
- package/connections/Connection.js +165 -168
- package/drivers/DatabaseDriver.d.ts +186 -80
- package/drivers/DatabaseDriver.js +450 -443
- package/drivers/IDatabaseDriver.d.ts +440 -301
- package/entity/BaseEntity.d.ts +120 -83
- package/entity/BaseEntity.js +43 -43
- package/entity/Collection.d.ts +212 -179
- package/entity/Collection.js +727 -721
- package/entity/EntityAssigner.d.ts +88 -77
- package/entity/EntityAssigner.js +231 -230
- package/entity/EntityFactory.d.ts +66 -54
- package/entity/EntityFactory.js +425 -383
- package/entity/EntityHelper.d.ts +34 -22
- package/entity/EntityHelper.js +280 -267
- package/entity/EntityIdentifier.d.ts +4 -4
- package/entity/EntityIdentifier.js +10 -10
- package/entity/EntityLoader.d.ts +98 -72
- package/entity/EntityLoader.js +753 -723
- package/entity/EntityRepository.d.ts +316 -201
- package/entity/EntityRepository.js +213 -213
- package/entity/PolymorphicRef.d.ts +5 -5
- package/entity/PolymorphicRef.js +10 -10
- package/entity/Reference.d.ts +126 -82
- package/entity/Reference.js +278 -274
- package/entity/WrappedEntity.d.ts +115 -72
- package/entity/WrappedEntity.js +168 -166
- package/entity/defineEntity.d.ts +1315 -636
- package/entity/defineEntity.js +527 -518
- package/entity/utils.d.ts +13 -3
- package/entity/utils.js +71 -73
- package/entity/validators.js +43 -43
- package/entity/wrap.js +8 -8
- package/enums.d.ts +258 -253
- package/enums.js +251 -252
- package/errors.d.ts +114 -72
- package/errors.js +350 -253
- package/events/EventManager.d.ts +26 -14
- package/events/EventManager.js +79 -77
- package/events/EventSubscriber.d.ts +29 -29
- package/events/TransactionEventBroadcaster.d.ts +15 -8
- package/events/TransactionEventBroadcaster.js +14 -14
- package/exceptions.d.ts +23 -40
- package/exceptions.js +35 -52
- package/hydration/Hydrator.d.ts +42 -17
- package/hydration/Hydrator.js +43 -43
- package/hydration/ObjectHydrator.d.ts +50 -17
- package/hydration/ObjectHydrator.js +481 -416
- package/index.d.ts +116 -2
- package/index.js +10 -1
- package/logging/DefaultLogger.d.ts +34 -32
- package/logging/DefaultLogger.js +86 -86
- package/logging/Logger.d.ts +41 -41
- package/logging/SimpleLogger.d.ts +13 -11
- package/logging/SimpleLogger.js +22 -22
- package/logging/colors.d.ts +6 -6
- package/logging/colors.js +11 -10
- package/logging/inspect.js +7 -7
- package/metadata/EntitySchema.d.ts +211 -127
- package/metadata/EntitySchema.js +397 -398
- package/metadata/MetadataDiscovery.d.ts +114 -114
- package/metadata/MetadataDiscovery.js +1951 -1863
- package/metadata/MetadataProvider.d.ts +24 -21
- package/metadata/MetadataProvider.js +82 -84
- package/metadata/MetadataStorage.d.ts +38 -32
- package/metadata/MetadataStorage.js +118 -118
- package/metadata/MetadataValidator.d.ts +39 -39
- package/metadata/MetadataValidator.js +381 -338
- package/metadata/discover-entities.d.ts +5 -2
- package/metadata/discover-entities.js +35 -27
- package/metadata/types.d.ts +615 -531
- package/naming-strategy/AbstractNamingStrategy.d.ts +54 -39
- package/naming-strategy/AbstractNamingStrategy.js +90 -85
- package/naming-strategy/EntityCaseNamingStrategy.d.ts +6 -6
- package/naming-strategy/EntityCaseNamingStrategy.js +22 -22
- package/naming-strategy/MongoNamingStrategy.d.ts +6 -6
- package/naming-strategy/MongoNamingStrategy.js +18 -18
- package/naming-strategy/NamingStrategy.d.ts +109 -99
- package/naming-strategy/UnderscoreNamingStrategy.d.ts +7 -7
- package/naming-strategy/UnderscoreNamingStrategy.js +21 -21
- package/not-supported.js +7 -4
- package/package.json +1 -1
- package/platforms/ExceptionConverter.d.ts +1 -1
- package/platforms/ExceptionConverter.js +4 -4
- package/platforms/Platform.d.ts +310 -299
- package/platforms/Platform.js +663 -636
- package/serialization/EntitySerializer.d.ts +49 -26
- package/serialization/EntitySerializer.js +224 -218
- package/serialization/EntityTransformer.d.ts +10 -6
- package/serialization/EntityTransformer.js +219 -217
- package/serialization/SerializationContext.d.ts +27 -23
- package/serialization/SerializationContext.js +105 -105
- package/types/ArrayType.d.ts +8 -8
- package/types/ArrayType.js +33 -33
- package/types/BigIntType.d.ts +17 -10
- package/types/BigIntType.js +37 -37
- package/types/BlobType.d.ts +3 -3
- package/types/BlobType.js +13 -13
- package/types/BooleanType.d.ts +4 -4
- package/types/BooleanType.js +12 -12
- package/types/CharacterType.d.ts +2 -2
- package/types/CharacterType.js +6 -6
- package/types/DateTimeType.d.ts +5 -5
- package/types/DateTimeType.js +15 -15
- package/types/DateType.d.ts +5 -5
- package/types/DateType.js +15 -15
- package/types/DecimalType.d.ts +7 -7
- package/types/DecimalType.js +26 -26
- package/types/DoubleType.d.ts +3 -3
- package/types/DoubleType.js +12 -12
- package/types/EnumArrayType.d.ts +5 -5
- package/types/EnumArrayType.js +24 -24
- package/types/EnumType.d.ts +3 -3
- package/types/EnumType.js +11 -11
- package/types/FloatType.d.ts +3 -3
- package/types/FloatType.js +9 -9
- package/types/IntegerType.d.ts +3 -3
- package/types/IntegerType.js +9 -9
- package/types/IntervalType.d.ts +4 -4
- package/types/IntervalType.js +12 -12
- package/types/JsonType.d.ts +8 -8
- package/types/JsonType.js +32 -32
- package/types/MediumIntType.d.ts +1 -1
- package/types/MediumIntType.js +3 -3
- package/types/SmallIntType.d.ts +3 -3
- package/types/SmallIntType.js +9 -9
- package/types/StringType.d.ts +4 -4
- package/types/StringType.js +12 -12
- package/types/TextType.d.ts +3 -3
- package/types/TextType.js +9 -9
- package/types/TimeType.d.ts +5 -5
- package/types/TimeType.js +17 -17
- package/types/TinyIntType.d.ts +3 -3
- package/types/TinyIntType.js +10 -10
- package/types/Type.d.ts +83 -79
- package/types/Type.js +82 -82
- package/types/Uint8ArrayType.d.ts +4 -4
- package/types/Uint8ArrayType.js +21 -21
- package/types/UnknownType.d.ts +4 -4
- package/types/UnknownType.js +12 -12
- package/types/UuidType.d.ts +5 -5
- package/types/UuidType.js +19 -19
- package/types/index.d.ts +75 -49
- package/types/index.js +52 -26
- package/typings.d.ts +1250 -737
- package/typings.js +244 -231
- package/unit-of-work/ChangeSet.d.ts +26 -26
- package/unit-of-work/ChangeSet.js +56 -56
- package/unit-of-work/ChangeSetComputer.d.ts +12 -12
- package/unit-of-work/ChangeSetComputer.js +178 -170
- package/unit-of-work/ChangeSetPersister.d.ts +63 -44
- package/unit-of-work/ChangeSetPersister.js +442 -421
- package/unit-of-work/CommitOrderCalculator.d.ts +40 -40
- package/unit-of-work/CommitOrderCalculator.js +89 -88
- package/unit-of-work/IdentityMap.d.ts +31 -31
- package/unit-of-work/IdentityMap.js +105 -105
- package/unit-of-work/UnitOfWork.d.ts +181 -141
- package/unit-of-work/UnitOfWork.js +1200 -1183
- package/utils/AbstractMigrator.d.ts +111 -91
- package/utils/AbstractMigrator.js +275 -275
- package/utils/AbstractSchemaGenerator.d.ts +43 -34
- package/utils/AbstractSchemaGenerator.js +121 -122
- package/utils/AsyncContext.d.ts +3 -3
- package/utils/AsyncContext.js +34 -35
- package/utils/Configuration.d.ts +852 -808
- package/utils/Configuration.js +359 -344
- package/utils/Cursor.d.ts +40 -22
- package/utils/Cursor.js +135 -127
- package/utils/DataloaderUtils.d.ts +58 -43
- package/utils/DataloaderUtils.js +203 -198
- package/utils/EntityComparator.d.ts +98 -81
- package/utils/EntityComparator.js +828 -728
- package/utils/NullHighlighter.d.ts +1 -1
- package/utils/NullHighlighter.js +3 -3
- package/utils/QueryHelper.d.ts +79 -51
- package/utils/QueryHelper.js +372 -361
- package/utils/RawQueryFragment.d.ts +50 -34
- package/utils/RawQueryFragment.js +107 -105
- package/utils/RequestContext.d.ts +32 -32
- package/utils/RequestContext.js +52 -53
- package/utils/TransactionContext.d.ts +16 -16
- package/utils/TransactionContext.js +27 -27
- package/utils/TransactionManager.d.ts +58 -58
- package/utils/TransactionManager.js +199 -197
- package/utils/Utils.d.ts +204 -145
- package/utils/Utils.js +812 -810
- package/utils/clone.js +104 -113
- package/utils/env-vars.js +90 -88
- package/utils/fs-utils.d.ts +15 -15
- package/utils/fs-utils.js +180 -181
- package/utils/upsert-utils.d.ts +20 -5
- package/utils/upsert-utils.js +114 -116
package/entity/EntityAssigner.js
CHANGED
|
@@ -8,243 +8,244 @@ import { EntityHelper } from './EntityHelper.js';
|
|
|
8
8
|
import { ValidationError } from '../errors.js';
|
|
9
9
|
/** Handles assigning data to entities, resolving relations, and propagating changes. */
|
|
10
10
|
export class EntityAssigner {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
EntityHelper.ensurePropagation(entity);
|
|
18
|
-
opts.visited ??= new Set();
|
|
19
|
-
opts.visited.add(entity);
|
|
20
|
-
const wrapped = helper(entity);
|
|
21
|
-
opts = {
|
|
22
|
-
...wrapped.__config.get('assign'),
|
|
23
|
-
schema: wrapped.__schema,
|
|
24
|
-
...opts, // allow overriding the defaults
|
|
25
|
-
};
|
|
26
|
-
const meta = wrapped.__meta;
|
|
27
|
-
const props = meta.properties;
|
|
28
|
-
Object.keys(data).forEach(prop => {
|
|
29
|
-
return EntityAssigner.assignProperty(entity, prop, props, data, {
|
|
30
|
-
...opts,
|
|
31
|
-
em: opts.em || wrapped.__em,
|
|
32
|
-
platform: wrapped.__platform,
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
return entity;
|
|
36
|
-
}
|
|
37
|
-
static assignProperty(entity, propName, props, data, options) {
|
|
38
|
-
let value = data[propName];
|
|
39
|
-
const onlyProperties = options.onlyProperties && !(propName in props);
|
|
40
|
-
const ignoreUndefined = options.ignoreUndefined === true && value === undefined;
|
|
41
|
-
if (onlyProperties || ignoreUndefined) {
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
const prop = { ...props[propName], name: propName };
|
|
45
|
-
if (prop && options.onlyOwnProperties) {
|
|
46
|
-
if ([ReferenceKind.ONE_TO_MANY].includes(prop.kind)) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
if ([ReferenceKind.MANY_TO_MANY].includes(prop.kind)) {
|
|
50
|
-
if (!prop.owner) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
else if (value?.map) {
|
|
54
|
-
value = value.map((v) => Utils.extractPK(v, prop.targetMeta));
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
|
|
58
|
-
value = Utils.extractPK(value, prop.targetMeta);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
if (propName in props && !prop.nullable && value == null) {
|
|
62
|
-
throw new Error(`You must pass a non-${value} value to the property ${propName} of entity ${entity.constructor.name}.`);
|
|
63
|
-
}
|
|
64
|
-
// create collection instance if its missing so old items can be deleted with orphan removal
|
|
65
|
-
if ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop?.kind) && entity[prop.name] == null) {
|
|
66
|
-
entity[prop.name] = Collection.create(entity, prop.name, undefined, helper(entity).isInitialized());
|
|
67
|
-
}
|
|
68
|
-
if (prop && Utils.isCollection(entity[prop.name])) {
|
|
69
|
-
return EntityAssigner.assignCollection(entity, entity[prop.name], value, prop, options.em, options);
|
|
70
|
-
}
|
|
71
|
-
const customType = prop?.customType;
|
|
72
|
-
if (options.convertCustomTypes && customType && prop.kind === ReferenceKind.SCALAR && !Utils.isEntity(data)) {
|
|
73
|
-
value = customType.convertToJSValue(value, options.platform);
|
|
74
|
-
}
|
|
75
|
-
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop?.kind) && value != null) {
|
|
76
|
-
if (options.updateNestedEntities &&
|
|
77
|
-
Object.hasOwn(entity, propName) &&
|
|
78
|
-
Utils.isEntity(entity[propName], true) &&
|
|
79
|
-
Utils.isPlainObject(value)) {
|
|
80
|
-
const unwrappedEntity = Reference.unwrapReference(entity[propName]);
|
|
81
|
-
const wrapped = helper(unwrappedEntity);
|
|
82
|
-
if (options.updateByPrimaryKey) {
|
|
83
|
-
const pk = Utils.extractPK(value, prop.targetMeta);
|
|
84
|
-
if (pk) {
|
|
85
|
-
const ref = options.em.getReference(prop.targetMeta.class, pk, options);
|
|
86
|
-
// if the PK differs, we want to change the target entity, not update it
|
|
87
|
-
const wrappedChild = helper(ref);
|
|
88
|
-
const sameTarget = wrappedChild.getSerializedPrimaryKey() === wrapped.getSerializedPrimaryKey();
|
|
89
|
-
if (wrappedChild.__managed && wrappedChild.isInitialized() && sameTarget) {
|
|
90
|
-
return EntityAssigner.assign(ref, value, options);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return EntityAssigner.assignReference(entity, value, prop, options.em, options);
|
|
94
|
-
}
|
|
95
|
-
if (wrapped.__managed && wrap(unwrappedEntity).isInitialized()) {
|
|
96
|
-
return EntityAssigner.assign(unwrappedEntity, value, options);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return EntityAssigner.assignReference(entity, value, prop, options.em, options);
|
|
100
|
-
}
|
|
101
|
-
if (prop.kind === ReferenceKind.SCALAR && SCALAR_TYPES.has(prop.runtimeType) && (prop.setter || !prop.getter)) {
|
|
102
|
-
validateProperty(prop, value, entity);
|
|
103
|
-
return (entity[prop.name] = value);
|
|
104
|
-
}
|
|
105
|
-
if (prop.kind === ReferenceKind.EMBEDDED && EntityAssigner.validateEM(options.em)) {
|
|
106
|
-
return EntityAssigner.assignEmbeddable(entity, value, prop, options.em, options);
|
|
107
|
-
}
|
|
108
|
-
if (options.mergeObjectProperties &&
|
|
109
|
-
Utils.isPlainObject(entity[propName]) &&
|
|
110
|
-
Utils.isPlainObject(value)) {
|
|
111
|
-
entity[propName] ??= {};
|
|
112
|
-
entity[propName] = Utils.merge({}, entity[propName], value);
|
|
113
|
-
}
|
|
114
|
-
else if (!prop || prop.setter || !prop.getter) {
|
|
115
|
-
entity[propName] = value;
|
|
116
|
-
}
|
|
11
|
+
/** Assigns the given data to the entity, resolving relations and handling custom types. */
|
|
12
|
+
static assign(entity, data, options = {}) {
|
|
13
|
+
let opts = options;
|
|
14
|
+
if (opts.visited?.has(entity)) {
|
|
15
|
+
return entity;
|
|
117
16
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
17
|
+
EntityHelper.ensurePropagation(entity);
|
|
18
|
+
opts.visited ??= new Set();
|
|
19
|
+
opts.visited.add(entity);
|
|
20
|
+
const wrapped = helper(entity);
|
|
21
|
+
opts = {
|
|
22
|
+
...wrapped.__config.get('assign'),
|
|
23
|
+
schema: wrapped.__schema,
|
|
24
|
+
...opts, // allow overriding the defaults
|
|
25
|
+
};
|
|
26
|
+
const meta = wrapped.__meta;
|
|
27
|
+
const props = meta.properties;
|
|
28
|
+
Object.keys(data).forEach(prop => {
|
|
29
|
+
return EntityAssigner.assignProperty(entity, prop, props, data, {
|
|
30
|
+
...opts,
|
|
31
|
+
em: opts.em || wrapped.__em,
|
|
32
|
+
platform: wrapped.__platform,
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
return entity;
|
|
36
|
+
}
|
|
37
|
+
static assignProperty(entity, propName, props, data, options) {
|
|
38
|
+
let value = data[propName];
|
|
39
|
+
const onlyProperties = options.onlyProperties && !(propName in props);
|
|
40
|
+
const ignoreUndefined = options.ignoreUndefined === true && value === undefined;
|
|
41
|
+
if (onlyProperties || ignoreUndefined) {
|
|
42
|
+
return;
|
|
139
43
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
44
|
+
const prop = { ...props[propName], name: propName };
|
|
45
|
+
if (prop && options.onlyOwnProperties) {
|
|
46
|
+
if ([ReferenceKind.ONE_TO_MANY].includes(prop.kind)) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if ([ReferenceKind.MANY_TO_MANY].includes(prop.kind)) {
|
|
50
|
+
if (!prop.owner) {
|
|
51
|
+
return;
|
|
52
|
+
} else if (value?.map) {
|
|
53
|
+
value = value.map(v => Utils.extractPK(v, prop.targetMeta));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
|
|
57
|
+
value = Utils.extractPK(value, prop.targetMeta);
|
|
58
|
+
}
|
|
145
59
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
if
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
return EntityAssigner.assign(ref, item, options);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return this.createCollectionItem(item, em, prop, invalid, options);
|
|
184
|
-
}
|
|
185
|
-
/* v8 ignore next */
|
|
186
|
-
if (options.updateNestedEntities &&
|
|
187
|
-
!options.updateByPrimaryKey &&
|
|
188
|
-
collection[idx] &&
|
|
189
|
-
helper(collection[idx])?.isInitialized()) {
|
|
190
|
-
return EntityAssigner.assign(collection[idx], item, options);
|
|
60
|
+
if (propName in props && !prop.nullable && value == null) {
|
|
61
|
+
throw new Error(
|
|
62
|
+
`You must pass a non-${value} value to the property ${propName} of entity ${entity.constructor.name}.`,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
// create collection instance if its missing so old items can be deleted with orphan removal
|
|
66
|
+
if ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop?.kind) && entity[prop.name] == null) {
|
|
67
|
+
entity[prop.name] = Collection.create(entity, prop.name, undefined, helper(entity).isInitialized());
|
|
68
|
+
}
|
|
69
|
+
if (prop && Utils.isCollection(entity[prop.name])) {
|
|
70
|
+
return EntityAssigner.assignCollection(entity, entity[prop.name], value, prop, options.em, options);
|
|
71
|
+
}
|
|
72
|
+
const customType = prop?.customType;
|
|
73
|
+
if (options.convertCustomTypes && customType && prop.kind === ReferenceKind.SCALAR && !Utils.isEntity(data)) {
|
|
74
|
+
value = customType.convertToJSValue(value, options.platform);
|
|
75
|
+
}
|
|
76
|
+
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop?.kind) && value != null) {
|
|
77
|
+
if (
|
|
78
|
+
options.updateNestedEntities &&
|
|
79
|
+
Object.hasOwn(entity, propName) &&
|
|
80
|
+
Utils.isEntity(entity[propName], true) &&
|
|
81
|
+
Utils.isPlainObject(value)
|
|
82
|
+
) {
|
|
83
|
+
const unwrappedEntity = Reference.unwrapReference(entity[propName]);
|
|
84
|
+
const wrapped = helper(unwrappedEntity);
|
|
85
|
+
if (options.updateByPrimaryKey) {
|
|
86
|
+
const pk = Utils.extractPK(value, prop.targetMeta);
|
|
87
|
+
if (pk) {
|
|
88
|
+
const ref = options.em.getReference(prop.targetMeta.class, pk, options);
|
|
89
|
+
// if the PK differs, we want to change the target entity, not update it
|
|
90
|
+
const wrappedChild = helper(ref);
|
|
91
|
+
const sameTarget = wrappedChild.getSerializedPrimaryKey() === wrapped.getSerializedPrimaryKey();
|
|
92
|
+
if (wrappedChild.__managed && wrappedChild.isInitialized() && sameTarget) {
|
|
93
|
+
return EntityAssigner.assign(ref, value, options);
|
|
191
94
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if (invalid.length > 0) {
|
|
195
|
-
const name = entity.constructor.name;
|
|
196
|
-
throw ValidationError.invalidCollectionValues(name, prop.name, invalid);
|
|
95
|
+
}
|
|
96
|
+
return EntityAssigner.assignReference(entity, value, prop, options.em, options);
|
|
197
97
|
}
|
|
198
|
-
if (
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
else {
|
|
202
|
-
// append to the collection in case of assigning a single value instead of array
|
|
203
|
-
collection.add(items);
|
|
98
|
+
if (wrapped.__managed && wrap(unwrappedEntity).isInitialized()) {
|
|
99
|
+
return EntityAssigner.assign(unwrappedEntity, value, options);
|
|
204
100
|
}
|
|
101
|
+
}
|
|
102
|
+
return EntityAssigner.assignReference(entity, value, prop, options.em, options);
|
|
205
103
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
104
|
+
if (prop.kind === ReferenceKind.SCALAR && SCALAR_TYPES.has(prop.runtimeType) && (prop.setter || !prop.getter)) {
|
|
105
|
+
validateProperty(prop, value, entity);
|
|
106
|
+
return (entity[prop.name] = value);
|
|
107
|
+
}
|
|
108
|
+
if (prop.kind === ReferenceKind.EMBEDDED && EntityAssigner.validateEM(options.em)) {
|
|
109
|
+
return EntityAssigner.assignEmbeddable(entity, value, prop, options.em, options);
|
|
110
|
+
}
|
|
111
|
+
if (options.mergeObjectProperties && Utils.isPlainObject(entity[propName]) && Utils.isPlainObject(value)) {
|
|
112
|
+
entity[propName] ??= {};
|
|
113
|
+
entity[propName] = Utils.merge({}, entity[propName], value);
|
|
114
|
+
} else if (!prop || prop.setter || !prop.getter) {
|
|
115
|
+
entity[propName] = value;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* auto-wire 1:1 inverse side with owner as in no-sql drivers it can't be joined
|
|
120
|
+
* also makes sure the link is bidirectional when creating new entities from nested structures
|
|
121
|
+
* @internal
|
|
122
|
+
*/
|
|
123
|
+
static autoWireOneToOne(prop, entity) {
|
|
124
|
+
const ref = entity[prop.name];
|
|
125
|
+
if (prop.kind !== ReferenceKind.ONE_TO_ONE || !Utils.isEntity(ref)) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const meta2 = helper(ref).__meta;
|
|
129
|
+
const prop2 = meta2.properties[prop.inversedBy || prop.mappedBy];
|
|
130
|
+
/* v8 ignore next */
|
|
131
|
+
if (prop2 && !ref[prop2.name]) {
|
|
132
|
+
if (Reference.isReference(ref)) {
|
|
133
|
+
ref.unwrap()[prop2.name] = Reference.wrapReference(entity, prop2);
|
|
134
|
+
} else {
|
|
135
|
+
ref[prop2.name] = Reference.wrapReference(entity, prop2);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
static validateEM(em) {
|
|
140
|
+
if (!em) {
|
|
141
|
+
throw new Error(
|
|
142
|
+
`To use assign() on not managed entities, explicitly provide EM instance: wrap(entity).assign(data, { em: orm.em })`,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
static assignReference(entity, value, prop, em, options) {
|
|
148
|
+
if (Utils.isEntity(value, true)) {
|
|
149
|
+
entity[prop.name] = Reference.wrapReference(value, prop);
|
|
150
|
+
} else if (Utils.isPrimaryKey(value, true) && EntityAssigner.validateEM(em)) {
|
|
151
|
+
entity[prop.name] = prop.mapToPk
|
|
152
|
+
? value
|
|
153
|
+
: Reference.wrapReference(em.getReference(prop.targetMeta.class, value, options), prop);
|
|
154
|
+
} else if (Utils.isPlainObject(value) && options.merge && EntityAssigner.validateEM(em)) {
|
|
155
|
+
entity[prop.name] = Reference.wrapReference(em.merge(prop.targetMeta.class, value, options), prop);
|
|
156
|
+
} else if (Utils.isPlainObject(value) && EntityAssigner.validateEM(em)) {
|
|
157
|
+
entity[prop.name] = Reference.wrapReference(em.create(prop.targetMeta.class, value, options), prop);
|
|
158
|
+
} else {
|
|
159
|
+
const name = entity.constructor.name;
|
|
160
|
+
throw new Error(
|
|
161
|
+
`Invalid reference value provided for '${name}.${prop.name}' in ${name}.assign(): ${JSON.stringify(value)}`,
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
EntityAssigner.autoWireOneToOne(prop, entity);
|
|
165
|
+
}
|
|
166
|
+
static assignCollection(entity, collection, value, prop, em, options) {
|
|
167
|
+
const invalid = [];
|
|
168
|
+
const items = Utils.asArray(value).map((item, idx) => {
|
|
169
|
+
// try to propagate missing owning side reference to the payload first
|
|
170
|
+
const prop2 = prop.targetMeta?.properties[prop.mappedBy];
|
|
171
|
+
if (Utils.isPlainObject(item) && prop2 && item[prop2.name] == null) {
|
|
172
|
+
item = { ...item, [prop2.name]: Reference.wrapReference(entity, prop2) };
|
|
173
|
+
}
|
|
174
|
+
if (options.updateNestedEntities && options.updateByPrimaryKey && Utils.isPlainObject(item)) {
|
|
175
|
+
const pk = Utils.extractPK(item, prop.targetMeta);
|
|
176
|
+
if (pk && EntityAssigner.validateEM(em)) {
|
|
177
|
+
const ref = em.getUnitOfWork().getById(prop.targetMeta.class, pk, options.schema);
|
|
178
|
+
if (ref) {
|
|
179
|
+
return EntityAssigner.assign(ref, item, options);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return this.createCollectionItem(item, em, prop, invalid, options);
|
|
183
|
+
}
|
|
184
|
+
/* v8 ignore next */
|
|
185
|
+
if (
|
|
186
|
+
options.updateNestedEntities &&
|
|
187
|
+
!options.updateByPrimaryKey &&
|
|
188
|
+
collection[idx] &&
|
|
189
|
+
helper(collection[idx])?.isInitialized()
|
|
190
|
+
) {
|
|
191
|
+
return EntityAssigner.assign(collection[idx], item, options);
|
|
192
|
+
}
|
|
193
|
+
return this.createCollectionItem(item, em, prop, invalid, options);
|
|
194
|
+
});
|
|
195
|
+
if (invalid.length > 0) {
|
|
196
|
+
const name = entity.constructor.name;
|
|
197
|
+
throw ValidationError.invalidCollectionValues(name, prop.name, invalid);
|
|
198
|
+
}
|
|
199
|
+
if (Array.isArray(value)) {
|
|
200
|
+
collection.set(items);
|
|
201
|
+
} else {
|
|
202
|
+
// append to the collection in case of assigning a single value instead of array
|
|
203
|
+
collection.add(items);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
static assignEmbeddable(entity, value, prop, em, options) {
|
|
207
|
+
const propName = prop.embedded ? prop.embedded[1] : prop.name;
|
|
208
|
+
if (value == null) {
|
|
209
|
+
entity[propName] = value;
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
// if the value is not an array, we just push, otherwise we replace the array
|
|
213
|
+
if (prop.array && (Array.isArray(value) || entity[propName] == null)) {
|
|
214
|
+
entity[propName] = [];
|
|
215
|
+
}
|
|
216
|
+
if (prop.array) {
|
|
217
|
+
return Utils.asArray(value).forEach(item => {
|
|
218
|
+
const tmp = {};
|
|
219
|
+
this.assignEmbeddable(tmp, item, { ...prop, array: false }, em, options);
|
|
220
|
+
entity[propName].push(...Object.values(tmp));
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
const create = () =>
|
|
224
|
+
EntityAssigner.validateEM(em) &&
|
|
225
|
+
em.getEntityFactory().createEmbeddable(prop.targetMeta.class, value, {
|
|
226
|
+
convertCustomTypes: options.convertCustomTypes,
|
|
227
|
+
newEntity: options.mergeEmbeddedProperties ? !('propName' in entity) : true,
|
|
228
|
+
});
|
|
229
|
+
entity[propName] = options.mergeEmbeddedProperties ? entity[propName] || create() : create();
|
|
230
|
+
Object.keys(value).forEach(key => {
|
|
231
|
+
EntityAssigner.assignProperty(entity[propName], key, prop.embeddedProps, value, options);
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
static createCollectionItem(item, em, prop, invalid, options) {
|
|
235
|
+
if (Utils.isEntity(item)) {
|
|
236
|
+
return item;
|
|
237
|
+
}
|
|
238
|
+
if (Utils.isPrimaryKey(item) && EntityAssigner.validateEM(em)) {
|
|
239
|
+
return em.getReference(prop.targetMeta.class, item, options);
|
|
240
|
+
}
|
|
241
|
+
if (Utils.isPlainObject(item) && options.merge && EntityAssigner.validateEM(em)) {
|
|
242
|
+
return em.merge(prop.targetMeta.class, item, options);
|
|
243
|
+
}
|
|
244
|
+
if (Utils.isPlainObject(item) && EntityAssigner.validateEM(em)) {
|
|
245
|
+
return em.create(prop.targetMeta.class, item, options);
|
|
248
246
|
}
|
|
247
|
+
invalid.push(item);
|
|
248
|
+
return item;
|
|
249
|
+
}
|
|
249
250
|
}
|
|
250
251
|
export const assign = EntityAssigner.assign;
|
|
@@ -3,61 +3,73 @@ import type { EntityManager } from '../EntityManager.js';
|
|
|
3
3
|
import type { EntityComparator } from '../utils/EntityComparator.js';
|
|
4
4
|
/** @internal Options for creating and merging entities via the EntityFactory. */
|
|
5
5
|
export interface FactoryOptions {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
6
|
+
/** Whether the entity should be marked as initialized. */
|
|
7
|
+
initialized?: boolean;
|
|
8
|
+
/** Whether the entity is being newly created (uses constructor). */
|
|
9
|
+
newEntity?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Property `onCreate` hooks are normally executed during `flush` operation.
|
|
12
|
+
* With this option, they will be processed early inside `em.create()` method.
|
|
13
|
+
*/
|
|
14
|
+
processOnCreateHooksEarly?: boolean;
|
|
15
|
+
/** Whether to merge the entity into the identity map. */
|
|
16
|
+
merge?: boolean;
|
|
17
|
+
/** Whether to refresh an already loaded entity with new data. */
|
|
18
|
+
refresh?: boolean;
|
|
19
|
+
/** Whether to convert custom types during hydration. */
|
|
20
|
+
convertCustomTypes?: boolean;
|
|
21
|
+
/** Whether to recompute the entity snapshot after creation. */
|
|
22
|
+
recomputeSnapshot?: boolean;
|
|
23
|
+
/** Schema from FindOptions, overrides default schema. */
|
|
24
|
+
schema?: string;
|
|
25
|
+
/** Parent entity schema for nested entity creation. */
|
|
26
|
+
parentSchema?: string;
|
|
27
|
+
/** Whether to normalize accessors to the correct property names (normally handled via result mapper). */
|
|
28
|
+
normalizeAccessors?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Property name to use for identity map lookup instead of the primary key.
|
|
31
|
+
* This is useful for creating references by unique non-PK properties.
|
|
32
|
+
*/
|
|
33
|
+
key?: string;
|
|
34
34
|
}
|
|
35
35
|
/** @internal Factory responsible for creating, merging, and hydrating entity instances. */
|
|
36
36
|
export declare class EntityFactory {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
37
|
+
#private;
|
|
38
|
+
constructor(em: EntityManager);
|
|
39
|
+
/** Creates a new entity instance or returns an existing one from the identity map, hydrating it with the provided data. */
|
|
40
|
+
create<T extends object, P extends string = string>(
|
|
41
|
+
entityName: EntityName<T>,
|
|
42
|
+
data: EntityData<T>,
|
|
43
|
+
options?: FactoryOptions,
|
|
44
|
+
): New<T, P>;
|
|
45
|
+
/** Merges new data into an existing entity, preserving user-modified properties. */
|
|
46
|
+
mergeData<T extends object>(meta: EntityMetadata<T>, entity: T, data: EntityData<T>, options?: FactoryOptions): void;
|
|
47
|
+
/** Creates or retrieves an uninitialized entity reference by its primary key or alternate key. */
|
|
48
|
+
createReference<T extends object>(
|
|
49
|
+
entityName: EntityName<T>,
|
|
50
|
+
id: Primary<T> | Primary<T>[] | Record<string, Primary<T>>,
|
|
51
|
+
options?: Pick<FactoryOptions, 'merge' | 'convertCustomTypes' | 'schema' | 'key'>,
|
|
52
|
+
): T;
|
|
53
|
+
/** Creates an embeddable entity instance from the provided data. */
|
|
54
|
+
createEmbeddable<T extends object>(
|
|
55
|
+
entityName: EntityName<T>,
|
|
56
|
+
data: EntityData<T>,
|
|
57
|
+
options?: Pick<FactoryOptions, 'newEntity' | 'convertCustomTypes'>,
|
|
58
|
+
): T;
|
|
59
|
+
/** Returns the EntityComparator instance used for diffing entities. */
|
|
60
|
+
getComparator(): EntityComparator;
|
|
61
|
+
private createEntity;
|
|
62
|
+
private assignDefaultValues;
|
|
63
|
+
private hydrate;
|
|
64
|
+
private findEntity;
|
|
65
|
+
private processDiscriminatorColumn;
|
|
66
|
+
/**
|
|
67
|
+
* denormalize PK to value required by driver (e.g. ObjectId)
|
|
68
|
+
*/
|
|
69
|
+
private denormalizePrimaryKey;
|
|
70
|
+
/**
|
|
71
|
+
* returns parameters for entity constructor, creating references from plain ids
|
|
72
|
+
*/
|
|
73
|
+
private extractConstructorParams;
|
|
74
|
+
private get unitOfWork();
|
|
63
75
|
}
|