@mikro-orm/core 7.0.0-dev.9 → 7.0.0-dev.91

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.
Files changed (191) hide show
  1. package/EntityManager.d.ts +77 -48
  2. package/EntityManager.js +288 -225
  3. package/MikroORM.d.ts +40 -31
  4. package/MikroORM.js +98 -137
  5. package/README.md +3 -2
  6. package/cache/FileCacheAdapter.d.ts +1 -1
  7. package/cache/FileCacheAdapter.js +6 -5
  8. package/cache/GeneratedCacheAdapter.d.ts +0 -1
  9. package/cache/GeneratedCacheAdapter.js +0 -2
  10. package/cache/index.d.ts +0 -1
  11. package/cache/index.js +0 -1
  12. package/connections/Connection.d.ts +11 -7
  13. package/connections/Connection.js +16 -14
  14. package/drivers/DatabaseDriver.d.ts +11 -5
  15. package/drivers/DatabaseDriver.js +23 -11
  16. package/drivers/IDatabaseDriver.d.ts +25 -4
  17. package/entity/BaseEntity.d.ts +0 -1
  18. package/entity/BaseEntity.js +0 -3
  19. package/entity/Collection.d.ts +95 -30
  20. package/entity/Collection.js +432 -93
  21. package/entity/EntityAssigner.d.ts +1 -1
  22. package/entity/EntityAssigner.js +17 -9
  23. package/entity/EntityFactory.d.ts +7 -0
  24. package/entity/EntityFactory.js +63 -41
  25. package/entity/EntityHelper.js +26 -12
  26. package/entity/EntityLoader.d.ts +5 -4
  27. package/entity/EntityLoader.js +63 -38
  28. package/entity/EntityRepository.d.ts +1 -1
  29. package/entity/Reference.d.ts +6 -5
  30. package/entity/Reference.js +34 -9
  31. package/entity/WrappedEntity.d.ts +2 -7
  32. package/entity/WrappedEntity.js +2 -7
  33. package/entity/defineEntity.d.ts +568 -0
  34. package/entity/defineEntity.js +529 -0
  35. package/entity/index.d.ts +3 -2
  36. package/entity/index.js +3 -2
  37. package/entity/utils.d.ts +7 -0
  38. package/entity/utils.js +16 -4
  39. package/entity/validators.d.ts +11 -0
  40. package/entity/validators.js +65 -0
  41. package/enums.d.ts +21 -6
  42. package/enums.js +14 -1
  43. package/errors.d.ts +10 -2
  44. package/errors.js +29 -10
  45. package/events/EventManager.d.ts +2 -1
  46. package/events/EventManager.js +19 -11
  47. package/events/EventSubscriber.d.ts +3 -1
  48. package/hydration/Hydrator.js +1 -2
  49. package/hydration/ObjectHydrator.d.ts +4 -4
  50. package/hydration/ObjectHydrator.js +35 -25
  51. package/index.d.ts +2 -2
  52. package/index.js +1 -2
  53. package/logging/DefaultLogger.d.ts +1 -1
  54. package/logging/DefaultLogger.js +1 -0
  55. package/logging/SimpleLogger.d.ts +1 -1
  56. package/logging/index.d.ts +1 -0
  57. package/logging/index.js +1 -0
  58. package/logging/inspect.d.ts +2 -0
  59. package/logging/inspect.js +16 -0
  60. package/metadata/EntitySchema.d.ts +9 -13
  61. package/metadata/EntitySchema.js +44 -26
  62. package/metadata/MetadataDiscovery.d.ts +6 -9
  63. package/metadata/MetadataDiscovery.js +165 -205
  64. package/metadata/MetadataProvider.d.ts +11 -2
  65. package/metadata/MetadataProvider.js +44 -2
  66. package/metadata/MetadataStorage.d.ts +1 -6
  67. package/metadata/MetadataStorage.js +6 -18
  68. package/metadata/MetadataValidator.d.ts +0 -7
  69. package/metadata/MetadataValidator.js +0 -10
  70. package/metadata/discover-entities.d.ts +5 -0
  71. package/metadata/discover-entities.js +40 -0
  72. package/metadata/index.d.ts +1 -1
  73. package/metadata/index.js +1 -1
  74. package/metadata/types.d.ts +480 -0
  75. package/metadata/types.js +1 -0
  76. package/naming-strategy/AbstractNamingStrategy.d.ts +5 -1
  77. package/naming-strategy/AbstractNamingStrategy.js +8 -2
  78. package/naming-strategy/NamingStrategy.d.ts +11 -1
  79. package/not-supported.d.ts +2 -0
  80. package/not-supported.js +4 -0
  81. package/package.json +18 -10
  82. package/platforms/ExceptionConverter.js +1 -1
  83. package/platforms/Platform.d.ts +6 -13
  84. package/platforms/Platform.js +15 -41
  85. package/serialization/EntitySerializer.d.ts +2 -0
  86. package/serialization/EntitySerializer.js +32 -14
  87. package/serialization/EntityTransformer.js +22 -12
  88. package/serialization/SerializationContext.js +16 -13
  89. package/types/ArrayType.d.ts +1 -1
  90. package/types/ArrayType.js +2 -3
  91. package/types/BigIntType.d.ts +8 -6
  92. package/types/BigIntType.js +1 -1
  93. package/types/BlobType.d.ts +0 -1
  94. package/types/BlobType.js +0 -3
  95. package/types/BooleanType.d.ts +2 -1
  96. package/types/BooleanType.js +3 -0
  97. package/types/DecimalType.d.ts +6 -4
  98. package/types/DecimalType.js +3 -3
  99. package/types/DoubleType.js +2 -2
  100. package/types/EnumArrayType.js +1 -2
  101. package/types/JsonType.d.ts +1 -1
  102. package/types/JsonType.js +7 -2
  103. package/types/TinyIntType.js +1 -1
  104. package/types/Type.d.ts +2 -4
  105. package/types/Type.js +3 -3
  106. package/types/Uint8ArrayType.d.ts +0 -1
  107. package/types/Uint8ArrayType.js +1 -4
  108. package/types/index.d.ts +1 -1
  109. package/typings.d.ts +109 -73
  110. package/typings.js +38 -35
  111. package/unit-of-work/ChangeSet.d.ts +0 -3
  112. package/unit-of-work/ChangeSet.js +2 -2
  113. package/unit-of-work/ChangeSetComputer.d.ts +1 -3
  114. package/unit-of-work/ChangeSetComputer.js +11 -9
  115. package/unit-of-work/ChangeSetPersister.d.ts +5 -4
  116. package/unit-of-work/ChangeSetPersister.js +51 -19
  117. package/unit-of-work/UnitOfWork.d.ts +8 -1
  118. package/unit-of-work/UnitOfWork.js +91 -49
  119. package/utils/AbstractSchemaGenerator.d.ts +5 -5
  120. package/utils/AbstractSchemaGenerator.js +11 -9
  121. package/utils/Configuration.d.ts +757 -206
  122. package/utils/Configuration.js +140 -188
  123. package/utils/ConfigurationLoader.d.ts +1 -54
  124. package/utils/ConfigurationLoader.js +1 -352
  125. package/utils/Cursor.d.ts +0 -3
  126. package/utils/Cursor.js +6 -3
  127. package/utils/DataloaderUtils.d.ts +15 -5
  128. package/utils/DataloaderUtils.js +54 -8
  129. package/utils/EntityComparator.d.ts +8 -4
  130. package/utils/EntityComparator.js +52 -17
  131. package/utils/QueryHelper.d.ts +9 -1
  132. package/utils/QueryHelper.js +70 -9
  133. package/utils/RawQueryFragment.d.ts +36 -13
  134. package/utils/RawQueryFragment.js +36 -16
  135. package/utils/TransactionManager.d.ts +65 -0
  136. package/utils/TransactionManager.js +223 -0
  137. package/utils/Utils.d.ts +9 -97
  138. package/utils/Utils.js +83 -302
  139. package/utils/clone.js +2 -3
  140. package/utils/env-vars.d.ts +3 -0
  141. package/utils/env-vars.js +87 -0
  142. package/utils/fs-utils.d.ts +12 -0
  143. package/utils/fs-utils.js +97 -0
  144. package/utils/index.d.ts +2 -1
  145. package/utils/index.js +2 -1
  146. package/utils/upsert-utils.d.ts +7 -2
  147. package/utils/upsert-utils.js +55 -4
  148. package/decorators/Check.d.ts +0 -3
  149. package/decorators/Check.js +0 -13
  150. package/decorators/CreateRequestContext.d.ts +0 -3
  151. package/decorators/CreateRequestContext.js +0 -32
  152. package/decorators/Embeddable.d.ts +0 -8
  153. package/decorators/Embeddable.js +0 -11
  154. package/decorators/Embedded.d.ts +0 -18
  155. package/decorators/Embedded.js +0 -18
  156. package/decorators/Entity.d.ts +0 -18
  157. package/decorators/Entity.js +0 -12
  158. package/decorators/Enum.d.ts +0 -9
  159. package/decorators/Enum.js +0 -16
  160. package/decorators/Filter.d.ts +0 -2
  161. package/decorators/Filter.js +0 -8
  162. package/decorators/Formula.d.ts +0 -4
  163. package/decorators/Formula.js +0 -15
  164. package/decorators/Indexed.d.ts +0 -19
  165. package/decorators/Indexed.js +0 -20
  166. package/decorators/ManyToMany.d.ts +0 -40
  167. package/decorators/ManyToMany.js +0 -14
  168. package/decorators/ManyToOne.d.ts +0 -30
  169. package/decorators/ManyToOne.js +0 -14
  170. package/decorators/OneToMany.d.ts +0 -28
  171. package/decorators/OneToMany.js +0 -17
  172. package/decorators/OneToOne.d.ts +0 -24
  173. package/decorators/OneToOne.js +0 -7
  174. package/decorators/PrimaryKey.d.ts +0 -8
  175. package/decorators/PrimaryKey.js +0 -20
  176. package/decorators/Property.d.ts +0 -250
  177. package/decorators/Property.js +0 -32
  178. package/decorators/Transactional.d.ts +0 -13
  179. package/decorators/Transactional.js +0 -28
  180. package/decorators/hooks.d.ts +0 -16
  181. package/decorators/hooks.js +0 -47
  182. package/decorators/index.d.ts +0 -17
  183. package/decorators/index.js +0 -17
  184. package/entity/ArrayCollection.d.ts +0 -116
  185. package/entity/ArrayCollection.js +0 -402
  186. package/entity/EntityValidator.d.ts +0 -19
  187. package/entity/EntityValidator.js +0 -150
  188. package/metadata/ReflectMetadataProvider.d.ts +0 -8
  189. package/metadata/ReflectMetadataProvider.js +0 -44
  190. package/utils/resolveContextProvider.d.ts +0 -10
  191. package/utils/resolveContextProvider.js +0 -28
@@ -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 { EntityValidator } from './EntityValidator.js';
5
+ import { validateProperty } from './validators.js';
7
6
  import { helper, wrap } from './wrap.js';
8
7
  import { EntityHelper } from './EntityHelper.js';
9
- const validator = new EntityValidator(false);
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.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop.kind)) {
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.includes(prop.runtimeType) && (prop.setter || !prop.getter)) {
90
- return entity[prop.name] = validator.validateProperty(prop, value, entity);
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 7 */
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 3 */
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 new Error(`Invalid collection values provided for '${name}.${prop.name}' in ${name}.assign(): ${inspect(invalid)}`);
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;
@@ -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 (this.platform.usesDifferentSerializedPrimaryKey()) {
41
- meta.primaryKeys.forEach(pk => this.denormalizePrimaryKey(data, pk, meta.properties[pk]));
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.forEach(prop => delete tmp[prop]);
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.primaryKeys, true);
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
- helper(entity).__touched = false;
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, options.convertCustomTypes);
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(data, primaryKey, prop) {
271
- const pk = this.platform.getSerializedPrimaryKeyField(primaryKey);
272
- if (data[pk] != null || data[primaryKey] != null) {
273
- let id = (data[pk] || data[primaryKey]);
274
- if (prop.type.toLowerCase() === 'objectid') {
275
- id = this.platform.denormalizePrimaryKey(id);
276
- }
277
- delete data[pk];
278
- data[primaryKey] = id;
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
- 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
- const entity = this.unitOfWork.getById(meta.properties[k].type, pk, options.schema);
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(data[k])) {
293
- return data[k];
314
+ if (Utils.isEntity(value)) {
315
+ return value;
294
316
  }
295
- const nakedPk = Utils.extractPK(data[k], meta.properties[k].targetMeta, true);
296
- if (Utils.isObject(data[k]) && !nakedPk) {
297
- return this.create(meta.properties[k].type, data[k], options);
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(meta.properties[k].type, nakedPk, rest);
301
- return Reference.wrapReference(target, meta.properties[k]);
322
+ const target = this.createReference(prop.type, nakedPk, rest);
323
+ return Reference.wrapReference(target, prop);
302
324
  }
303
- if (meta.properties[k]?.kind === ReferenceKind.EMBEDDED && data[k]) {
304
- /* v8 ignore next 3 */
305
- if (Utils.isEntity(data[k])) {
306
- return data[k];
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(meta.properties[k].type, data[k], options);
330
+ return this.createEmbeddable(prop.type, value, options);
309
331
  }
310
- if (!meta.properties[k]) {
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 && meta.properties[k].customType && data[k] != null) {
326
- return meta.properties[k].customType.convertToJSValue(data[k], this.platform);
347
+ if (options.convertCustomTypes && prop.customType && value != null) {
348
+ return prop.customType.convertToJSValue(value, this.platform);
327
349
  }
328
- return data[k];
350
+ return value;
329
351
  });
330
352
  }
331
353
  get unitOfWork() {
@@ -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.slice(meta.toJsonParams.length));
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.persist === false || prop.trackChanges === false || prop.embedded || isCollection) {
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 = { ...this };
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 = (this).constructor.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.primaryKeys, true);
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) {
@@ -1,7 +1,7 @@
1
- import type { ConnectionType, Dictionary, FilterQuery, PopulateOptions } from '../typings.js';
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?: Dictionary<boolean | Dictionary> | string[] | boolean;
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
- private findChildrenFromPivotTable;
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;