@mikro-orm/core 7.0.0-dev.9 → 7.0.0-dev.90
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 +77 -48
- package/EntityManager.js +288 -225
- package/MikroORM.d.ts +40 -31
- package/MikroORM.js +98 -137
- package/README.md +3 -2
- package/cache/FileCacheAdapter.d.ts +1 -1
- package/cache/FileCacheAdapter.js +6 -5
- package/cache/GeneratedCacheAdapter.d.ts +0 -1
- package/cache/GeneratedCacheAdapter.js +0 -2
- package/cache/index.d.ts +0 -1
- package/cache/index.js +0 -1
- package/connections/Connection.d.ts +11 -7
- package/connections/Connection.js +16 -14
- package/drivers/DatabaseDriver.d.ts +11 -5
- package/drivers/DatabaseDriver.js +23 -11
- package/drivers/IDatabaseDriver.d.ts +25 -4
- package/entity/BaseEntity.d.ts +0 -1
- package/entity/BaseEntity.js +0 -3
- package/entity/Collection.d.ts +95 -30
- package/entity/Collection.js +432 -93
- package/entity/EntityAssigner.d.ts +1 -1
- package/entity/EntityAssigner.js +17 -9
- package/entity/EntityFactory.d.ts +7 -0
- package/entity/EntityFactory.js +63 -41
- package/entity/EntityHelper.js +26 -12
- package/entity/EntityLoader.d.ts +5 -4
- package/entity/EntityLoader.js +63 -38
- package/entity/EntityRepository.d.ts +1 -1
- package/entity/Reference.d.ts +6 -5
- package/entity/Reference.js +34 -9
- package/entity/WrappedEntity.d.ts +2 -7
- package/entity/WrappedEntity.js +2 -7
- package/entity/defineEntity.d.ts +568 -0
- package/entity/defineEntity.js +529 -0
- package/entity/index.d.ts +3 -2
- package/entity/index.js +3 -2
- package/entity/utils.d.ts +7 -0
- package/entity/utils.js +16 -4
- package/entity/validators.d.ts +11 -0
- package/entity/validators.js +65 -0
- package/enums.d.ts +21 -6
- package/enums.js +14 -1
- package/errors.d.ts +10 -2
- package/errors.js +29 -10
- package/events/EventManager.d.ts +2 -1
- package/events/EventManager.js +19 -11
- package/events/EventSubscriber.d.ts +3 -1
- package/hydration/Hydrator.js +1 -2
- package/hydration/ObjectHydrator.d.ts +4 -4
- package/hydration/ObjectHydrator.js +35 -25
- package/index.d.ts +2 -2
- package/index.js +1 -2
- package/logging/DefaultLogger.d.ts +1 -1
- package/logging/DefaultLogger.js +1 -0
- package/logging/SimpleLogger.d.ts +1 -1
- package/logging/index.d.ts +1 -0
- package/logging/index.js +1 -0
- package/logging/inspect.d.ts +2 -0
- package/logging/inspect.js +16 -0
- package/metadata/EntitySchema.d.ts +9 -13
- package/metadata/EntitySchema.js +44 -26
- package/metadata/MetadataDiscovery.d.ts +6 -9
- package/metadata/MetadataDiscovery.js +165 -205
- package/metadata/MetadataProvider.d.ts +11 -2
- package/metadata/MetadataProvider.js +44 -2
- package/metadata/MetadataStorage.d.ts +1 -6
- package/metadata/MetadataStorage.js +6 -18
- package/metadata/MetadataValidator.d.ts +0 -7
- package/metadata/MetadataValidator.js +0 -10
- package/metadata/discover-entities.d.ts +5 -0
- package/metadata/discover-entities.js +40 -0
- package/metadata/index.d.ts +1 -1
- package/metadata/index.js +1 -1
- package/metadata/types.d.ts +480 -0
- package/metadata/types.js +1 -0
- package/naming-strategy/AbstractNamingStrategy.d.ts +5 -1
- package/naming-strategy/AbstractNamingStrategy.js +8 -2
- package/naming-strategy/NamingStrategy.d.ts +11 -1
- package/not-supported.d.ts +2 -0
- package/not-supported.js +4 -0
- package/package.json +18 -10
- package/platforms/ExceptionConverter.js +1 -1
- package/platforms/Platform.d.ts +6 -13
- package/platforms/Platform.js +15 -41
- package/serialization/EntitySerializer.d.ts +2 -0
- package/serialization/EntitySerializer.js +32 -14
- package/serialization/EntityTransformer.js +22 -12
- package/serialization/SerializationContext.js +16 -13
- package/types/ArrayType.d.ts +1 -1
- package/types/ArrayType.js +2 -3
- package/types/BigIntType.d.ts +8 -6
- package/types/BigIntType.js +1 -1
- package/types/BlobType.d.ts +0 -1
- package/types/BlobType.js +0 -3
- package/types/BooleanType.d.ts +2 -1
- package/types/BooleanType.js +3 -0
- package/types/DecimalType.d.ts +6 -4
- package/types/DecimalType.js +3 -3
- package/types/DoubleType.js +2 -2
- package/types/EnumArrayType.js +1 -2
- package/types/JsonType.d.ts +1 -1
- package/types/JsonType.js +7 -2
- package/types/TinyIntType.js +1 -1
- package/types/Type.d.ts +2 -4
- package/types/Type.js +3 -3
- package/types/Uint8ArrayType.d.ts +0 -1
- package/types/Uint8ArrayType.js +1 -4
- package/types/index.d.ts +1 -1
- package/typings.d.ts +109 -73
- package/typings.js +38 -35
- package/unit-of-work/ChangeSet.d.ts +0 -3
- package/unit-of-work/ChangeSet.js +2 -2
- package/unit-of-work/ChangeSetComputer.d.ts +1 -3
- package/unit-of-work/ChangeSetComputer.js +11 -9
- package/unit-of-work/ChangeSetPersister.d.ts +5 -4
- package/unit-of-work/ChangeSetPersister.js +51 -19
- package/unit-of-work/UnitOfWork.d.ts +8 -1
- package/unit-of-work/UnitOfWork.js +91 -49
- package/utils/AbstractSchemaGenerator.d.ts +5 -5
- package/utils/AbstractSchemaGenerator.js +11 -9
- package/utils/Configuration.d.ts +757 -206
- package/utils/Configuration.js +140 -188
- package/utils/ConfigurationLoader.d.ts +1 -54
- package/utils/ConfigurationLoader.js +1 -352
- package/utils/Cursor.d.ts +0 -3
- package/utils/Cursor.js +6 -3
- package/utils/DataloaderUtils.d.ts +15 -5
- package/utils/DataloaderUtils.js +54 -8
- package/utils/EntityComparator.d.ts +8 -4
- package/utils/EntityComparator.js +52 -17
- package/utils/QueryHelper.d.ts +9 -1
- package/utils/QueryHelper.js +70 -9
- package/utils/RawQueryFragment.d.ts +36 -13
- package/utils/RawQueryFragment.js +36 -16
- package/utils/TransactionManager.d.ts +65 -0
- package/utils/TransactionManager.js +223 -0
- package/utils/Utils.d.ts +8 -97
- package/utils/Utils.js +82 -302
- package/utils/clone.js +2 -3
- 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 +2 -1
- package/utils/index.js +2 -1
- package/utils/upsert-utils.d.ts +7 -2
- package/utils/upsert-utils.js +55 -4
- package/decorators/Check.d.ts +0 -3
- package/decorators/Check.js +0 -13
- package/decorators/CreateRequestContext.d.ts +0 -3
- package/decorators/CreateRequestContext.js +0 -32
- package/decorators/Embeddable.d.ts +0 -8
- package/decorators/Embeddable.js +0 -11
- package/decorators/Embedded.d.ts +0 -18
- package/decorators/Embedded.js +0 -18
- package/decorators/Entity.d.ts +0 -18
- package/decorators/Entity.js +0 -12
- package/decorators/Enum.d.ts +0 -9
- package/decorators/Enum.js +0 -16
- package/decorators/Filter.d.ts +0 -2
- package/decorators/Filter.js +0 -8
- package/decorators/Formula.d.ts +0 -4
- package/decorators/Formula.js +0 -15
- package/decorators/Indexed.d.ts +0 -19
- package/decorators/Indexed.js +0 -20
- package/decorators/ManyToMany.d.ts +0 -40
- package/decorators/ManyToMany.js +0 -14
- package/decorators/ManyToOne.d.ts +0 -30
- package/decorators/ManyToOne.js +0 -14
- package/decorators/OneToMany.d.ts +0 -28
- package/decorators/OneToMany.js +0 -17
- package/decorators/OneToOne.d.ts +0 -24
- package/decorators/OneToOne.js +0 -7
- package/decorators/PrimaryKey.d.ts +0 -8
- package/decorators/PrimaryKey.js +0 -20
- package/decorators/Property.d.ts +0 -250
- package/decorators/Property.js +0 -32
- package/decorators/Transactional.d.ts +0 -13
- package/decorators/Transactional.js +0 -28
- package/decorators/hooks.d.ts +0 -16
- package/decorators/hooks.js +0 -47
- package/decorators/index.d.ts +0 -17
- package/decorators/index.js +0 -17
- package/entity/ArrayCollection.d.ts +0 -116
- package/entity/ArrayCollection.js +0 -402
- package/entity/EntityValidator.d.ts +0 -19
- package/entity/EntityValidator.js +0 -150
- package/metadata/ReflectMetadataProvider.d.ts +0 -8
- package/metadata/ReflectMetadataProvider.js +0 -44
- package/utils/resolveContextProvider.d.ts +0 -10
- package/utils/resolveContextProvider.js +0 -28
package/entity/EntityAssigner.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { inspect } from 'node:util';
|
|
2
1
|
import { Collection } from './Collection.js';
|
|
3
2
|
import { Utils } from '../utils/Utils.js';
|
|
4
3
|
import { Reference } from './Reference.js';
|
|
5
4
|
import { ReferenceKind, SCALAR_TYPES } from '../enums.js';
|
|
6
|
-
import {
|
|
5
|
+
import { validateProperty } from './validators.js';
|
|
7
6
|
import { helper, wrap } from './wrap.js';
|
|
8
7
|
import { EntityHelper } from './EntityHelper.js';
|
|
9
|
-
|
|
8
|
+
import { ValidationError } from '../errors.js';
|
|
10
9
|
export class EntityAssigner {
|
|
11
10
|
static assign(entity, data, options = {}) {
|
|
12
11
|
let opts = options;
|
|
@@ -42,9 +41,17 @@ export class EntityAssigner {
|
|
|
42
41
|
}
|
|
43
42
|
const prop = { ...props[propName], name: propName };
|
|
44
43
|
if (prop && options.onlyOwnProperties) {
|
|
45
|
-
if ([ReferenceKind.
|
|
44
|
+
if ([ReferenceKind.ONE_TO_MANY].includes(prop.kind)) {
|
|
46
45
|
return;
|
|
47
46
|
}
|
|
47
|
+
if ([ReferenceKind.MANY_TO_MANY].includes(prop.kind)) {
|
|
48
|
+
if (!prop.owner) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
else if (value?.map) {
|
|
52
|
+
value = value.map((v) => Utils.extractPK(v, prop.targetMeta));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
48
55
|
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {
|
|
49
56
|
value = Utils.extractPK(value, prop.targetMeta);
|
|
50
57
|
}
|
|
@@ -86,8 +93,9 @@ export class EntityAssigner {
|
|
|
86
93
|
}
|
|
87
94
|
return EntityAssigner.assignReference(entity, value, prop, options.em, options);
|
|
88
95
|
}
|
|
89
|
-
if (prop.kind === ReferenceKind.SCALAR && SCALAR_TYPES.
|
|
90
|
-
|
|
96
|
+
if (prop.kind === ReferenceKind.SCALAR && SCALAR_TYPES.has(prop.runtimeType) && (prop.setter || !prop.getter)) {
|
|
97
|
+
validateProperty(prop, value, entity);
|
|
98
|
+
return entity[prop.name] = value;
|
|
91
99
|
}
|
|
92
100
|
if (prop.kind === ReferenceKind.EMBEDDED && EntityAssigner.validateEM(options.em)) {
|
|
93
101
|
return EntityAssigner.assignEmbeddable(entity, value, prop, options.em, options);
|
|
@@ -112,7 +120,7 @@ export class EntityAssigner {
|
|
|
112
120
|
}
|
|
113
121
|
const meta2 = helper(ref).__meta;
|
|
114
122
|
const prop2 = meta2.properties[prop.inversedBy || prop.mappedBy];
|
|
115
|
-
/* v8 ignore next
|
|
123
|
+
/* v8 ignore next */
|
|
116
124
|
if (prop2 && !ref[prop2.name]) {
|
|
117
125
|
if (Reference.isReference(ref)) {
|
|
118
126
|
ref.unwrap()[prop2.name] = Reference.wrapReference(entity, prop2);
|
|
@@ -165,7 +173,7 @@ export class EntityAssigner {
|
|
|
165
173
|
}
|
|
166
174
|
return this.createCollectionItem(item, em, prop, invalid, options);
|
|
167
175
|
}
|
|
168
|
-
/* v8 ignore next
|
|
176
|
+
/* v8 ignore next */
|
|
169
177
|
if (options.updateNestedEntities && !options.updateByPrimaryKey && collection[idx] && helper(collection[idx])?.isInitialized()) {
|
|
170
178
|
return EntityAssigner.assign(collection[idx], item, options);
|
|
171
179
|
}
|
|
@@ -173,7 +181,7 @@ export class EntityAssigner {
|
|
|
173
181
|
});
|
|
174
182
|
if (invalid.length > 0) {
|
|
175
183
|
const name = entity.constructor.name;
|
|
176
|
-
throw
|
|
184
|
+
throw ValidationError.invalidCollectionValues(name, prop.name, invalid);
|
|
177
185
|
}
|
|
178
186
|
if (Array.isArray(value)) {
|
|
179
187
|
collection.set(items);
|
|
@@ -4,12 +4,18 @@ import type { EntityComparator } from '../utils/EntityComparator.js';
|
|
|
4
4
|
export interface FactoryOptions {
|
|
5
5
|
initialized?: boolean;
|
|
6
6
|
newEntity?: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Property `onCreate` hooks are normally executed during `flush` operation.
|
|
9
|
+
* With this option, they will be processed early inside `em.create()` method.
|
|
10
|
+
*/
|
|
11
|
+
processOnCreateHooksEarly?: boolean;
|
|
7
12
|
merge?: boolean;
|
|
8
13
|
refresh?: boolean;
|
|
9
14
|
convertCustomTypes?: boolean;
|
|
10
15
|
recomputeSnapshot?: boolean;
|
|
11
16
|
schema?: string;
|
|
12
17
|
parentSchema?: string;
|
|
18
|
+
normalizeAccessors?: boolean;
|
|
13
19
|
}
|
|
14
20
|
export declare class EntityFactory {
|
|
15
21
|
private readonly em;
|
|
@@ -27,6 +33,7 @@ export declare class EntityFactory {
|
|
|
27
33
|
createEmbeddable<T extends object>(entityName: EntityName<T>, data: EntityData<T>, options?: Pick<FactoryOptions, 'newEntity' | 'convertCustomTypes'>): T;
|
|
28
34
|
getComparator(): EntityComparator;
|
|
29
35
|
private createEntity;
|
|
36
|
+
private assignDefaultValues;
|
|
30
37
|
private hydrate;
|
|
31
38
|
private findEntity;
|
|
32
39
|
private processDiscriminatorColumn;
|
package/entity/EntityFactory.js
CHANGED
|
@@ -4,6 +4,7 @@ import { EventType, ReferenceKind } from '../enums.js';
|
|
|
4
4
|
import { Reference } from './Reference.js';
|
|
5
5
|
import { helper } from './wrap.js';
|
|
6
6
|
import { EntityHelper } from './EntityHelper.js';
|
|
7
|
+
import { JsonType } from '../types/JsonType.js';
|
|
7
8
|
export class EntityFactory {
|
|
8
9
|
em;
|
|
9
10
|
driver;
|
|
@@ -37,8 +38,8 @@ export class EntityFactory {
|
|
|
37
38
|
this.hydrate(entity, meta, data, options);
|
|
38
39
|
return entity;
|
|
39
40
|
}
|
|
40
|
-
if (
|
|
41
|
-
|
|
41
|
+
if (meta.serializedPrimaryKey) {
|
|
42
|
+
this.denormalizePrimaryKey(meta, data);
|
|
42
43
|
}
|
|
43
44
|
const meta2 = this.processDiscriminatorColumn(meta, data);
|
|
44
45
|
const exists = this.findEntity(data, meta2, options);
|
|
@@ -59,7 +60,7 @@ export class EntityFactory {
|
|
|
59
60
|
wrapped.__initialized = options.initialized;
|
|
60
61
|
if (options.newEntity || meta.forceConstructor || meta.virtual) {
|
|
61
62
|
const tmp = { ...data };
|
|
62
|
-
meta.constructorParams
|
|
63
|
+
meta.constructorParams?.forEach(prop => delete tmp[prop]);
|
|
63
64
|
this.hydrate(entity, meta2, tmp, options);
|
|
64
65
|
// since we now process only a copy of the `data` via hydrator, but later we register the state with the full snapshot,
|
|
65
66
|
// we need to go through all props with custom types that have `ensureComparable: true` and ensure they are comparable
|
|
@@ -71,9 +72,11 @@ export class EntityFactory {
|
|
|
71
72
|
continue;
|
|
72
73
|
}
|
|
73
74
|
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
|
|
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' });
|
|
75
79
|
}
|
|
76
|
-
data[prop.name] = prop.customType.convertToDatabaseValue(data[prop.name], this.platform, { key: prop.name, mode: 'hydration' });
|
|
77
80
|
}
|
|
78
81
|
}
|
|
79
82
|
}
|
|
@@ -81,7 +84,6 @@ export class EntityFactory {
|
|
|
81
84
|
else {
|
|
82
85
|
this.hydrate(entity, meta2, data, options);
|
|
83
86
|
}
|
|
84
|
-
wrapped.__touched = false;
|
|
85
87
|
if (exists && meta.discriminatorColumn && !(entity instanceof meta2.class)) {
|
|
86
88
|
Object.setPrototypeOf(entity, meta2.prototype);
|
|
87
89
|
}
|
|
@@ -113,7 +115,7 @@ export class EntityFactory {
|
|
|
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
120
|
Utils.keys(diff).forEach(key => delete diff2[key]);
|
|
119
121
|
Utils.keys(diff2).filter(key => {
|
|
@@ -136,6 +138,10 @@ export class EntityFactory {
|
|
|
136
138
|
if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name])) {
|
|
137
139
|
diff2[key] = entity[prop.name] ? helper(entity[prop.name]).getPrimaryKey(options.convertCustomTypes) : null;
|
|
138
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 });
|
|
144
|
+
}
|
|
139
145
|
originalEntityData[key] = diff2[key] === null ? nullVal : diff2[key];
|
|
140
146
|
helper(entity).__loadedProperties.add(key);
|
|
141
147
|
});
|
|
@@ -153,7 +159,7 @@ export class EntityFactory {
|
|
|
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;
|
|
@@ -171,8 +177,8 @@ export class EntityFactory {
|
|
|
171
177
|
if (Array.isArray(id)) {
|
|
172
178
|
id = Utils.getPrimaryKeyCondFromArray(id, meta);
|
|
173
179
|
}
|
|
174
|
-
const pks = Utils.getOrderedPrimaryKeys(id, meta, this.platform
|
|
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
|
}
|
|
@@ -231,17 +237,28 @@ export class EntityFactory {
|
|
|
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
254
|
Utils.keys(data).forEach(key => {
|
|
242
255
|
helper(entity)?.__loadedProperties.add(key);
|
|
243
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 @@ export class EntityFactory {
|
|
|
251
268
|
if (!Array.isArray(data) && meta.primaryKeys.some(pk => data[pk] == null)) {
|
|
252
269
|
return undefined;
|
|
253
270
|
}
|
|
254
|
-
const pks = Utils.getOrderedPrimaryKeys(data, meta, this.platform);
|
|
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,47 +284,52 @@ export 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 (Utils.isEntity(
|
|
293
|
-
return
|
|
314
|
+
if (Utils.isEntity(value)) {
|
|
315
|
+
return value;
|
|
294
316
|
}
|
|
295
|
-
const nakedPk = Utils.extractPK(
|
|
296
|
-
if (Utils.isObject(
|
|
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 Reference.wrapReference(target,
|
|
322
|
+
const target = this.createReference(prop.type, nakedPk, rest);
|
|
323
|
+
return Reference.wrapReference(target, prop);
|
|
302
324
|
}
|
|
303
|
-
if (
|
|
304
|
-
/* v8 ignore next
|
|
305
|
-
if (Utils.isEntity(
|
|
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) {
|
|
@@ -322,10 +344,10 @@ export class EntityFactory {
|
|
|
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() {
|
package/entity/EntityHelper.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { inspect } from 'node:util';
|
|
2
1
|
import { EagerProps, EntityRepositoryType, HiddenProps, OptionalProps, PrimaryKeyProp, } from '../typings.js';
|
|
3
2
|
import { EntityTransformer } from '../serialization/EntityTransformer.js';
|
|
4
3
|
import { Reference } from './Reference.js';
|
|
@@ -6,6 +5,7 @@ import { Utils } from '../utils/Utils.js';
|
|
|
6
5
|
import { WrappedEntity } from './WrappedEntity.js';
|
|
7
6
|
import { ReferenceKind } from '../enums.js';
|
|
8
7
|
import { helper } from './wrap.js';
|
|
8
|
+
import { inspect } from '../logging/inspect.js';
|
|
9
9
|
/**
|
|
10
10
|
* @internal
|
|
11
11
|
*/
|
|
@@ -32,7 +32,7 @@ export class EntityHelper {
|
|
|
32
32
|
const prototype = meta.prototype;
|
|
33
33
|
if (!prototype.toJSON) { // toJSON can be overridden
|
|
34
34
|
prototype.toJSON = function (...args) {
|
|
35
|
-
return EntityTransformer.toObject(this, ...args
|
|
35
|
+
return EntityTransformer.toObject(this, ...args);
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -87,7 +87,7 @@ export class EntityHelper {
|
|
|
87
87
|
});
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
|
-
if (prop.inherited || prop.primary || prop.
|
|
90
|
+
if (prop.inherited || prop.primary || prop.accessor || prop.persist === false || prop.embedded || isCollection) {
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
93
|
Object.defineProperty(meta.prototype, prop.name, {
|
|
@@ -98,13 +98,11 @@ export class EntityHelper {
|
|
|
98
98
|
},
|
|
99
99
|
set(val) {
|
|
100
100
|
this.__helper.__data[prop.name] = val;
|
|
101
|
-
this.__helper.__touched = !this.__helper.hydrator.isRunning();
|
|
102
101
|
},
|
|
103
102
|
enumerable: true,
|
|
104
103
|
configurable: true,
|
|
105
104
|
});
|
|
106
105
|
this.__helper.__data[prop.name] = val;
|
|
107
|
-
this.__helper.__touched = !this.__helper.hydrator.isRunning();
|
|
108
106
|
},
|
|
109
107
|
configurable: true,
|
|
110
108
|
});
|
|
@@ -112,15 +110,26 @@ export class EntityHelper {
|
|
|
112
110
|
}
|
|
113
111
|
static defineCustomInspect(meta) {
|
|
114
112
|
// @ts-ignore
|
|
115
|
-
meta.prototype[inspect.custom] ??= function (depth = 2) {
|
|
116
|
-
const object = {
|
|
113
|
+
meta.prototype[Symbol.for('nodejs.util.inspect.custom')] ??= function (depth = 2) {
|
|
114
|
+
const object = {};
|
|
115
|
+
const keys = new Set(Utils.keys(this));
|
|
116
|
+
for (const prop of meta.props) {
|
|
117
|
+
if (keys.has(prop.name) || (prop.getter && prop.accessor === prop.name)) {
|
|
118
|
+
object[prop.name] = this[prop.name];
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
for (const key of keys) {
|
|
122
|
+
if (!meta.properties[key]) {
|
|
123
|
+
object[key] = this[key];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
117
126
|
// ensure we dont have internal symbols in the POJO
|
|
118
127
|
[OptionalProps, EntityRepositoryType, PrimaryKeyProp, EagerProps, HiddenProps].forEach(sym => delete object[sym]);
|
|
119
128
|
meta.props
|
|
120
129
|
.filter(prop => object[prop.name] === undefined)
|
|
121
130
|
.forEach(prop => delete object[prop.name]);
|
|
122
131
|
const ret = inspect(object, { depth });
|
|
123
|
-
let name =
|
|
132
|
+
let name = this.constructor.name;
|
|
124
133
|
const showEM = ['true', 't', '1'].includes(process.env.MIKRO_ORM_LOG_EM_ID?.toString().toLowerCase() ?? '');
|
|
125
134
|
if (showEM) {
|
|
126
135
|
if (helper(this).__em) {
|
|
@@ -152,10 +161,7 @@ export class EntityHelper {
|
|
|
152
161
|
wrapped.__data[prop.name] = Reference.wrapReference(val, prop);
|
|
153
162
|
// when propagation from inside hydration, we set the FK to the entity data immediately
|
|
154
163
|
if (val && hydrator.isRunning() && wrapped.__originalEntityData && prop.owner) {
|
|
155
|
-
wrapped.__originalEntityData[prop.name] = Utils.getPrimaryKeyValues(wrapped.__data[prop.name], prop.targetMeta
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
wrapped.__touched = !hydrator.isRunning();
|
|
164
|
+
wrapped.__originalEntityData[prop.name] = Utils.getPrimaryKeyValues(wrapped.__data[prop.name], prop.targetMeta, true);
|
|
159
165
|
}
|
|
160
166
|
EntityHelper.propagate(meta, entity, this, prop, Reference.unwrapReference(val), old);
|
|
161
167
|
},
|
|
@@ -172,6 +178,13 @@ export class EntityHelper {
|
|
|
172
178
|
continue;
|
|
173
179
|
}
|
|
174
180
|
const inverse = value?.[prop2.name];
|
|
181
|
+
if (prop.ref && owner[prop.name]) {
|
|
182
|
+
// eslint-disable-next-line dot-notation
|
|
183
|
+
owner[prop.name]['property'] = prop;
|
|
184
|
+
}
|
|
185
|
+
if (Utils.isCollection(inverse) && inverse.isPartial()) {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
175
188
|
if (prop.kind === ReferenceKind.MANY_TO_ONE && Utils.isCollection(inverse) && inverse.isInitialized()) {
|
|
176
189
|
inverse.addWithoutPropagation(owner);
|
|
177
190
|
helper(owner).__em?.getUnitOfWork().cancelOrphanRemoval(owner);
|
|
@@ -210,6 +223,7 @@ export class EntityHelper {
|
|
|
210
223
|
}
|
|
211
224
|
if (old?.[prop2.name] != null) {
|
|
212
225
|
delete helper(old).__data[prop2.name];
|
|
226
|
+
old[prop2.name] = null;
|
|
213
227
|
}
|
|
214
228
|
}
|
|
215
229
|
static ensurePropagation(entity) {
|
package/entity/EntityLoader.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { ConnectionType,
|
|
1
|
+
import type { AnyEntity, ConnectionType, EntityProperty, FilterQuery, PopulateOptions } from '../typings.js';
|
|
2
2
|
import type { EntityManager } from '../EntityManager.js';
|
|
3
3
|
import { LoadStrategy, type LockMode, type PopulateHint, PopulatePath, type QueryOrderMap } from '../enums.js';
|
|
4
|
-
import type { EntityField } from '../drivers/IDatabaseDriver.js';
|
|
4
|
+
import type { EntityField, FilterOptions } from '../drivers/IDatabaseDriver.js';
|
|
5
5
|
import type { LoggingOptions } from '../logging/Logger.js';
|
|
6
6
|
export type EntityLoaderOptions<Entity, Fields extends string = PopulatePath.ALL, Excludes extends string = never> = {
|
|
7
7
|
where?: FilterQuery<Entity>;
|
|
@@ -14,7 +14,7 @@ export type EntityLoaderOptions<Entity, Fields extends string = PopulatePath.ALL
|
|
|
14
14
|
lookup?: boolean;
|
|
15
15
|
convertCustomTypes?: boolean;
|
|
16
16
|
ignoreLazyScalarProperties?: boolean;
|
|
17
|
-
filters?:
|
|
17
|
+
filters?: FilterOptions;
|
|
18
18
|
strategy?: LoadStrategy;
|
|
19
19
|
lockMode?: Exclude<LockMode, LockMode.OPTIMISTIC>;
|
|
20
20
|
schema?: string;
|
|
@@ -49,7 +49,8 @@ export declare class EntityLoader {
|
|
|
49
49
|
private findChildren;
|
|
50
50
|
private mergePrimaryCondition;
|
|
51
51
|
private populateField;
|
|
52
|
-
|
|
52
|
+
/** @internal */
|
|
53
|
+
findChildrenFromPivotTable<Entity extends object>(filtered: Entity[], prop: EntityProperty<Entity>, options: Required<EntityLoaderOptions<Entity>>, orderBy?: QueryOrderMap<Entity>[], populate?: PopulateOptions<Entity>, pivotJoin?: boolean): Promise<AnyEntity[][]>;
|
|
53
54
|
private extractChildCondition;
|
|
54
55
|
private buildFields;
|
|
55
56
|
private getChildReferences;
|