@mikro-orm/core 7.0.0-rc.2 → 7.0.0

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 (114) hide show
  1. package/EntityManager.d.ts +4 -16
  2. package/EntityManager.js +248 -181
  3. package/MikroORM.d.ts +4 -6
  4. package/MikroORM.js +24 -24
  5. package/README.md +5 -4
  6. package/cache/FileCacheAdapter.d.ts +1 -5
  7. package/cache/FileCacheAdapter.js +22 -24
  8. package/cache/GeneratedCacheAdapter.d.ts +1 -1
  9. package/cache/GeneratedCacheAdapter.js +6 -6
  10. package/cache/MemoryCacheAdapter.d.ts +1 -2
  11. package/cache/MemoryCacheAdapter.js +8 -8
  12. package/cache/index.d.ts +1 -1
  13. package/cache/index.js +0 -1
  14. package/connections/Connection.d.ts +1 -0
  15. package/connections/Connection.js +43 -14
  16. package/drivers/DatabaseDriver.d.ts +0 -2
  17. package/drivers/DatabaseDriver.js +28 -12
  18. package/drivers/IDatabaseDriver.d.ts +43 -0
  19. package/entity/Collection.d.ts +1 -9
  20. package/entity/Collection.js +124 -108
  21. package/entity/EntityAssigner.js +23 -11
  22. package/entity/EntityFactory.d.ts +1 -8
  23. package/entity/EntityFactory.js +79 -59
  24. package/entity/EntityHelper.js +25 -16
  25. package/entity/EntityLoader.d.ts +1 -3
  26. package/entity/EntityLoader.js +90 -60
  27. package/entity/Reference.d.ts +2 -3
  28. package/entity/Reference.js +48 -19
  29. package/entity/WrappedEntity.d.ts +4 -2
  30. package/entity/WrappedEntity.js +5 -1
  31. package/entity/defineEntity.d.ts +42 -85
  32. package/entity/utils.js +28 -26
  33. package/entity/validators.js +2 -1
  34. package/enums.d.ts +2 -1
  35. package/enums.js +13 -17
  36. package/errors.d.ts +11 -11
  37. package/errors.js +8 -8
  38. package/events/EventManager.d.ts +1 -4
  39. package/events/EventManager.js +26 -23
  40. package/events/index.d.ts +1 -1
  41. package/events/index.js +0 -1
  42. package/exceptions.js +9 -2
  43. package/hydration/ObjectHydrator.d.ts +1 -2
  44. package/hydration/ObjectHydrator.js +41 -27
  45. package/index.d.ts +1 -1
  46. package/index.js +1 -1
  47. package/logging/DefaultLogger.js +6 -7
  48. package/logging/Logger.d.ts +2 -1
  49. package/logging/colors.js +2 -5
  50. package/logging/index.d.ts +1 -1
  51. package/logging/index.js +0 -1
  52. package/metadata/EntitySchema.d.ts +3 -3
  53. package/metadata/EntitySchema.js +12 -2
  54. package/metadata/MetadataDiscovery.d.ts +1 -9
  55. package/metadata/MetadataDiscovery.js +251 -179
  56. package/metadata/MetadataProvider.js +26 -1
  57. package/metadata/MetadataStorage.d.ts +1 -5
  58. package/metadata/MetadataStorage.js +37 -39
  59. package/metadata/MetadataValidator.js +20 -5
  60. package/metadata/discover-entities.js +1 -1
  61. package/metadata/index.d.ts +1 -1
  62. package/metadata/index.js +0 -1
  63. package/metadata/types.d.ts +2 -2
  64. package/naming-strategy/AbstractNamingStrategy.js +6 -3
  65. package/naming-strategy/EntityCaseNamingStrategy.js +1 -1
  66. package/naming-strategy/index.d.ts +1 -1
  67. package/naming-strategy/index.js +0 -1
  68. package/not-supported.js +5 -1
  69. package/package.json +38 -38
  70. package/platforms/Platform.d.ts +24 -1
  71. package/platforms/Platform.js +106 -27
  72. package/serialization/EntitySerializer.js +8 -4
  73. package/serialization/EntityTransformer.js +4 -1
  74. package/serialization/SerializationContext.d.ts +4 -8
  75. package/serialization/SerializationContext.js +21 -16
  76. package/types/UuidType.d.ts +2 -0
  77. package/types/UuidType.js +14 -2
  78. package/types/index.d.ts +2 -1
  79. package/typings.d.ts +35 -24
  80. package/typings.js +9 -9
  81. package/unit-of-work/ChangeSet.js +4 -4
  82. package/unit-of-work/ChangeSetComputer.d.ts +1 -6
  83. package/unit-of-work/ChangeSetComputer.js +29 -27
  84. package/unit-of-work/ChangeSetPersister.d.ts +1 -9
  85. package/unit-of-work/ChangeSetPersister.js +63 -58
  86. package/unit-of-work/CommitOrderCalculator.d.ts +1 -4
  87. package/unit-of-work/CommitOrderCalculator.js +17 -15
  88. package/unit-of-work/IdentityMap.d.ts +2 -5
  89. package/unit-of-work/IdentityMap.js +18 -18
  90. package/unit-of-work/UnitOfWork.d.ts +12 -20
  91. package/unit-of-work/UnitOfWork.js +228 -191
  92. package/utils/AbstractMigrator.d.ts +2 -2
  93. package/utils/AbstractMigrator.js +10 -12
  94. package/utils/AbstractSchemaGenerator.js +2 -1
  95. package/utils/AsyncContext.js +1 -1
  96. package/utils/Configuration.d.ts +90 -189
  97. package/utils/Configuration.js +97 -77
  98. package/utils/Cursor.d.ts +3 -3
  99. package/utils/Cursor.js +8 -6
  100. package/utils/DataloaderUtils.js +15 -12
  101. package/utils/EntityComparator.d.ts +8 -15
  102. package/utils/EntityComparator.js +100 -92
  103. package/utils/QueryHelper.d.ts +16 -1
  104. package/utils/QueryHelper.js +108 -50
  105. package/utils/RawQueryFragment.d.ts +4 -4
  106. package/utils/RawQueryFragment.js +3 -2
  107. package/utils/TransactionManager.js +3 -3
  108. package/utils/Utils.d.ts +2 -2
  109. package/utils/Utils.js +39 -32
  110. package/utils/clone.js +5 -0
  111. package/utils/env-vars.js +6 -5
  112. package/utils/fs-utils.d.ts +3 -17
  113. package/utils/fs-utils.js +2 -5
  114. package/utils/upsert-utils.js +7 -4
@@ -71,7 +71,10 @@ export class EntityAssigner {
71
71
  value = customType.convertToJSValue(value, options.platform);
72
72
  }
73
73
  if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop?.kind) && value != null) {
74
- if (options.updateNestedEntities && Object.hasOwn(entity, propName) && Utils.isEntity(entity[propName], true) && Utils.isPlainObject(value)) {
74
+ if (options.updateNestedEntities &&
75
+ Object.hasOwn(entity, propName) &&
76
+ Utils.isEntity(entity[propName], true) &&
77
+ Utils.isPlainObject(value)) {
75
78
  const unwrappedEntity = Reference.unwrapReference(entity[propName]);
76
79
  const wrapped = helper(unwrappedEntity);
77
80
  if (options.updateByPrimaryKey) {
@@ -95,12 +98,14 @@ export class EntityAssigner {
95
98
  }
96
99
  if (prop.kind === ReferenceKind.SCALAR && SCALAR_TYPES.has(prop.runtimeType) && (prop.setter || !prop.getter)) {
97
100
  validateProperty(prop, value, entity);
98
- return entity[prop.name] = value;
101
+ return (entity[prop.name] = value);
99
102
  }
100
103
  if (prop.kind === ReferenceKind.EMBEDDED && EntityAssigner.validateEM(options.em)) {
101
104
  return EntityAssigner.assignEmbeddable(entity, value, prop, options.em, options);
102
105
  }
103
- if (options.mergeObjectProperties && Utils.isPlainObject(entity[propName]) && Utils.isPlainObject(value)) {
106
+ if (options.mergeObjectProperties &&
107
+ Utils.isPlainObject(entity[propName]) &&
108
+ Utils.isPlainObject(value)) {
104
109
  entity[propName] ??= {};
105
110
  entity[propName] = Utils.merge({}, entity[propName], value);
106
111
  }
@@ -141,7 +146,9 @@ export class EntityAssigner {
141
146
  entity[prop.name] = Reference.wrapReference(value, prop);
142
147
  }
143
148
  else if (Utils.isPrimaryKey(value, true) && EntityAssigner.validateEM(em)) {
144
- entity[prop.name] = prop.mapToPk ? value : Reference.wrapReference(em.getReference(prop.targetMeta.class, value, options), prop);
149
+ entity[prop.name] = prop.mapToPk
150
+ ? value
151
+ : Reference.wrapReference(em.getReference(prop.targetMeta.class, value, options), prop);
145
152
  }
146
153
  else if (Utils.isPlainObject(value) && options.merge && EntityAssigner.validateEM(em)) {
147
154
  entity[prop.name] = Reference.wrapReference(em.merge(prop.targetMeta.class, value, options), prop);
@@ -174,7 +181,10 @@ export class EntityAssigner {
174
181
  return this.createCollectionItem(item, em, prop, invalid, options);
175
182
  }
176
183
  /* v8 ignore next */
177
- if (options.updateNestedEntities && !options.updateByPrimaryKey && collection[idx] && helper(collection[idx])?.isInitialized()) {
184
+ if (options.updateNestedEntities &&
185
+ !options.updateByPrimaryKey &&
186
+ collection[idx] &&
187
+ helper(collection[idx])?.isInitialized()) {
178
188
  return EntityAssigner.assign(collection[idx], item, options);
179
189
  }
180
190
  return this.createCollectionItem(item, em, prop, invalid, options);
@@ -186,7 +196,8 @@ export class EntityAssigner {
186
196
  if (Array.isArray(value)) {
187
197
  collection.set(items);
188
198
  }
189
- else { // append to the collection in case of assigning a single value instead of array
199
+ else {
200
+ // append to the collection in case of assigning a single value instead of array
190
201
  collection.add(items);
191
202
  }
192
203
  }
@@ -207,11 +218,12 @@ export class EntityAssigner {
207
218
  entity[propName].push(...Object.values(tmp));
208
219
  });
209
220
  }
210
- const create = () => EntityAssigner.validateEM(em) && em.getEntityFactory().createEmbeddable(prop.targetMeta.class, value, {
211
- convertCustomTypes: options.convertCustomTypes,
212
- newEntity: options.mergeEmbeddedProperties ? !('propName' in entity) : true,
213
- });
214
- entity[propName] = (options.mergeEmbeddedProperties ? (entity[propName] || create()) : create());
221
+ const create = () => EntityAssigner.validateEM(em) &&
222
+ em.getEntityFactory().createEmbeddable(prop.targetMeta.class, value, {
223
+ convertCustomTypes: options.convertCustomTypes,
224
+ newEntity: options.mergeEmbeddedProperties ? !('propName' in entity) : true,
225
+ });
226
+ entity[propName] = (options.mergeEmbeddedProperties ? entity[propName] || create() : create());
215
227
  Object.keys(value).forEach(key => {
216
228
  EntityAssigner.assignProperty(entity[propName], key, prop.embeddedProps, value, options);
217
229
  });
@@ -23,14 +23,7 @@ export interface FactoryOptions {
23
23
  key?: string;
24
24
  }
25
25
  export declare class EntityFactory {
26
- private readonly em;
27
- private readonly driver;
28
- private readonly platform;
29
- private readonly config;
30
- private readonly metadata;
31
- private readonly hydrator;
32
- private readonly eventManager;
33
- private readonly comparator;
26
+ #private;
34
27
  constructor(em: EntityManager);
35
28
  create<T extends object, P extends string = string>(entityName: EntityName<T>, data: EntityData<T>, options?: FactoryOptions): New<T, P>;
36
29
  mergeData<T extends object>(meta: EntityMetadata<T>, entity: T, data: EntityData<T>, options?: FactoryOptions): void;
@@ -6,23 +6,23 @@ import { helper } from './wrap.js';
6
6
  import { EntityHelper } from './EntityHelper.js';
7
7
  import { JsonType } from '../types/JsonType.js';
8
8
  export class EntityFactory {
9
- em;
10
- driver;
11
- platform;
12
- config;
13
- metadata;
14
- hydrator;
15
- eventManager;
16
- comparator;
9
+ #driver;
10
+ #platform;
11
+ #config;
12
+ #metadata;
13
+ #hydrator;
14
+ #eventManager;
15
+ #comparator;
16
+ #em;
17
17
  constructor(em) {
18
- this.em = em;
19
- this.driver = this.em.getDriver();
20
- this.platform = this.driver.getPlatform();
21
- this.config = this.em.config;
22
- this.metadata = this.em.getMetadata();
23
- this.hydrator = this.config.getHydrator(this.metadata);
24
- this.eventManager = this.em.getEventManager();
25
- this.comparator = this.em.getComparator();
18
+ this.#em = em;
19
+ this.#driver = this.#em.getDriver();
20
+ this.#platform = this.#driver.getPlatform();
21
+ this.#config = this.#em.config;
22
+ this.#metadata = this.#em.getMetadata();
23
+ this.#hydrator = this.#config.getHydrator(this.#metadata);
24
+ this.#eventManager = this.#em.getEventManager();
25
+ this.#comparator = this.#em.getComparator();
26
26
  }
27
27
  create(entityName, data, options = {}) {
28
28
  data = Reference.unwrapReference(data);
@@ -30,7 +30,7 @@ export class EntityFactory {
30
30
  if (data.__entity) {
31
31
  return data;
32
32
  }
33
- const meta = this.metadata.get(entityName);
33
+ const meta = this.#metadata.get(entityName);
34
34
  if (meta.virtual) {
35
35
  data = { ...data };
36
36
  const entity = this.createEntity(data, meta, options);
@@ -70,11 +70,15 @@ export class EntityFactory {
70
70
  if ([ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind)) {
71
71
  continue;
72
72
  }
73
- if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name])) {
73
+ if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) &&
74
+ Utils.isPlainObject(data[prop.name])) {
74
75
  data[prop.name] = Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta, true);
75
76
  }
76
- if (prop.customType instanceof JsonType && this.platform.convertsJsonAutomatically()) {
77
- data[prop.name] = prop.customType.convertToDatabaseValue(data[prop.name], this.platform, { key: prop.name, mode: 'hydration' });
77
+ if (prop.customType instanceof JsonType && this.#platform.convertsJsonAutomatically()) {
78
+ data[prop.name] = prop.customType.convertToDatabaseValue(data[prop.name], this.#platform, {
79
+ key: prop.name,
80
+ mode: 'hydration',
81
+ });
78
82
  }
79
83
  }
80
84
  }
@@ -95,11 +99,11 @@ export class EntityFactory {
95
99
  loaded: options.initialized,
96
100
  });
97
101
  if (options.recomputeSnapshot) {
98
- wrapped.__originalEntityData = this.comparator.prepareEntity(entity);
102
+ wrapped.__originalEntityData = this.#comparator.prepareEntity(entity);
99
103
  }
100
104
  }
101
- if (this.eventManager.hasListeners(EventType.onInit, meta2)) {
102
- this.eventManager.dispatchEvent(EventType.onInit, { entity, meta: meta2, em: this.em });
105
+ if (this.#eventManager.hasListeners(EventType.onInit, meta2)) {
106
+ this.#eventManager.dispatchEvent(EventType.onInit, { entity, meta: meta2, em: this.#em });
103
107
  }
104
108
  wrapped.__processing = false;
105
109
  return entity;
@@ -107,49 +111,60 @@ export class EntityFactory {
107
111
  mergeData(meta, entity, data, options = {}) {
108
112
  // merge unchanged properties automatically
109
113
  data = QueryHelper.processParams(data);
110
- const existsData = this.comparator.prepareEntity(entity);
114
+ const existsData = this.#comparator.prepareEntity(entity);
111
115
  const originalEntityData = helper(entity).__originalEntityData ?? {};
112
- const diff = this.comparator.diffEntities(meta.class, originalEntityData, existsData);
116
+ const diff = this.#comparator.diffEntities(meta.class, originalEntityData, existsData);
113
117
  // version properties are not part of entity snapshots
114
- if (meta.versionProperty && data[meta.versionProperty] && data[meta.versionProperty] !== originalEntityData[meta.versionProperty]) {
118
+ if (meta.versionProperty &&
119
+ data[meta.versionProperty] &&
120
+ data[meta.versionProperty] !== originalEntityData[meta.versionProperty]) {
115
121
  diff[meta.versionProperty] = data[meta.versionProperty];
116
122
  }
117
- const diff2 = this.comparator.diffEntities(meta.class, existsData, data, { includeInverseSides: true });
123
+ const diff2 = this.#comparator.diffEntities(meta.class, existsData, data, { includeInverseSides: true });
118
124
  // do not override values changed by user
119
125
  Utils.keys(diff).forEach(key => delete diff2[key]);
120
- Utils.keys(diff2).filter(key => {
126
+ Utils.keys(diff2)
127
+ .filter(key => {
121
128
  // ignore null values if there is already present non-null value
122
129
  if (existsData[key] != null) {
123
130
  return diff2[key] == null;
124
131
  }
125
132
  return diff2[key] === undefined;
126
- }).forEach(key => delete diff2[key]);
133
+ })
134
+ .forEach(key => delete diff2[key]);
127
135
  // but always add collection properties and formulas if they are part of the `data`
128
136
  Utils.keys(data)
129
- .filter(key => meta.properties[key]?.formula || [ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(meta.properties[key]?.kind))
130
- .forEach(key => diff2[key] = data[key]);
137
+ .filter(key => meta.properties[key]?.formula ||
138
+ [ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(meta.properties[key]?.kind))
139
+ .forEach(key => (diff2[key] = data[key]));
131
140
  // rehydrated with the new values, skip those changed by user
132
141
  // use full hydration if the entity is already initialized, even if the caller used `initialized: false`
133
142
  // (e.g. from createReference), otherwise scalar properties in diff2 won't be applied
134
143
  const initialized = options.initialized || helper(entity).__initialized;
135
144
  this.hydrate(entity, meta, diff2, initialized ? { ...options, initialized } : options);
136
145
  // we need to update the entity data only with keys that were not present before
137
- const nullVal = this.config.get('forceUndefined') ? undefined : null;
146
+ const nullVal = this.#config.get('forceUndefined') ? undefined : null;
138
147
  Utils.keys(diff2).forEach(key => {
139
148
  const prop = meta.properties[key];
140
- if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name])) {
149
+ if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) &&
150
+ Utils.isPlainObject(data[prop.name])) {
151
+ // oxfmt-ignore
141
152
  diff2[key] = entity[prop.name] ? helper(entity[prop.name]).getPrimaryKey(options.convertCustomTypes) : null;
142
153
  }
143
- if (!options.convertCustomTypes && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE, ReferenceKind.SCALAR].includes(prop.kind) && prop.customType?.ensureComparable(meta, prop) && diff2[key] != null) {
144
- const converted = prop.customType.convertToJSValue(diff2[key], this.platform, { force: true });
145
- diff2[key] = prop.customType.convertToDatabaseValue(converted, this.platform, { fromQuery: true });
154
+ if (!options.convertCustomTypes &&
155
+ [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE, ReferenceKind.SCALAR].includes(prop.kind) &&
156
+ prop.customType?.ensureComparable(meta, prop) &&
157
+ diff2[key] != null) {
158
+ const converted = prop.customType.convertToJSValue(diff2[key], this.#platform, { force: true });
159
+ diff2[key] = prop.customType.convertToDatabaseValue(converted, this.#platform, { fromQuery: true });
146
160
  }
147
161
  originalEntityData[key] = diff2[key] === null ? nullVal : diff2[key];
148
162
  helper(entity).__loadedProperties.add(key);
149
163
  });
150
164
  // in case of joined loading strategy, we need to cascade the merging to possibly loaded relations manually
151
165
  meta.relations.forEach(prop => {
152
- if ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop.kind) && Array.isArray(data[prop.name])) {
166
+ if ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop.kind) &&
167
+ Array.isArray(data[prop.name])) {
153
168
  // instead of trying to match the collection items (which could easily fail if the collection was loaded with different ordering),
154
169
  // we just create the entity from scratch, which will automatically pick the right one from the identity map and call `mergeData` on it
155
170
  data[prop.name]
@@ -157,7 +172,10 @@ export class EntityFactory {
157
172
  .forEach(child => this.create(prop.targetMeta.class, child, options)); // we can ignore the value, we just care about the `mergeData` call
158
173
  return;
159
174
  }
160
- if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(data[prop.name]) && entity[prop.name] && helper(entity[prop.name]).__initialized) {
175
+ if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) &&
176
+ Utils.isPlainObject(data[prop.name]) &&
177
+ entity[prop.name] &&
178
+ helper(entity[prop.name]).__initialized) {
161
179
  this.create(prop.targetMeta.class, data[prop.name], options); // we can ignore the value, we just care about the `mergeData` call
162
180
  }
163
181
  });
@@ -165,8 +183,8 @@ export class EntityFactory {
165
183
  }
166
184
  createReference(entityName, id, options = {}) {
167
185
  options.convertCustomTypes ??= true;
168
- const meta = this.metadata.get(entityName);
169
- const schema = this.driver.getSchemaName(meta, options);
186
+ const meta = this.#metadata.get(entityName);
187
+ const schema = this.#driver.getSchemaName(meta, options);
170
188
  // Handle alternate key lookup
171
189
  if (options.key) {
172
190
  const value = '' + (Array.isArray(id) ? id[0] : Utils.isPlainObject(id) ? id[options.key] : id);
@@ -190,7 +208,7 @@ export class EntityFactory {
190
208
  if (Array.isArray(id)) {
191
209
  id = Utils.getPrimaryKeyCondFromArray(id, meta);
192
210
  }
193
- const pks = Utils.getOrderedPrimaryKeys(id, meta, this.platform);
211
+ const pks = Utils.getOrderedPrimaryKeys(id, meta, this.#platform);
194
212
  const exists = this.unitOfWork.getById(entityName, pks, schema, options.convertCustomTypes);
195
213
  if (exists) {
196
214
  return exists;
@@ -202,15 +220,15 @@ export class EntityFactory {
202
220
  }
203
221
  createEmbeddable(entityName, data, options = {}) {
204
222
  data = { ...data };
205
- const meta = this.metadata.get(entityName);
223
+ const meta = this.#metadata.get(entityName);
206
224
  const meta2 = this.processDiscriminatorColumn(meta, data);
207
225
  return this.createEntity(data, meta2, options);
208
226
  }
209
227
  getComparator() {
210
- return this.comparator;
228
+ return this.#comparator;
211
229
  }
212
230
  createEntity(data, meta, options) {
213
- const schema = this.driver.getSchemaName(meta, options);
231
+ const schema = this.#driver.getSchemaName(meta, options);
214
232
  if (options.newEntity || meta.forceConstructor || meta.virtual) {
215
233
  if (meta.polymorphs) {
216
234
  throw new Error(`Cannot create entity ${meta.className}, class prototype is unknown`);
@@ -221,7 +239,7 @@ export class EntityFactory {
221
239
  const entity = new Entity(...params);
222
240
  // creating managed entity instance when `forceEntityConstructor` is enabled,
223
241
  // we need to wipe all the values as they would cause update queries on next flush
224
- if (!options.newEntity && (meta.forceConstructor || this.config.get('forceEntityConstructor'))) {
242
+ if (!options.newEntity && (meta.forceConstructor || this.#config.get('forceEntityConstructor'))) {
225
243
  meta.props
226
244
  .filter(prop => prop.persist !== false && !prop.primary && data[prop.name] === undefined)
227
245
  .forEach(prop => delete entity[prop.name]);
@@ -241,7 +259,7 @@ export class EntityFactory {
241
259
  helper(entity).__processing = !meta.embeddable && !meta.virtual;
242
260
  helper(entity).__schema = schema;
243
261
  if (options.merge && !options.newEntity) {
244
- this.hydrator.hydrateReference(entity, meta, data, this, options.convertCustomTypes, options.schema, options.parentSchema);
262
+ this.#hydrator.hydrateReference(entity, meta, data, this, options.convertCustomTypes, options.schema, options.parentSchema);
245
263
  this.unitOfWork.register(entity);
246
264
  }
247
265
  if (options.initialized) {
@@ -252,35 +270,35 @@ export class EntityFactory {
252
270
  assignDefaultValues(entity, meta) {
253
271
  for (const prop of meta.props) {
254
272
  if (prop.onCreate) {
255
- entity[prop.name] ??= prop.onCreate(entity, this.em);
273
+ entity[prop.name] ??= prop.onCreate(entity, this.#em);
256
274
  }
257
275
  }
258
276
  }
259
277
  hydrate(entity, meta, data, options) {
260
278
  if (options.initialized) {
261
- this.hydrator.hydrate(entity, meta, data, this, 'full', options.newEntity, options.convertCustomTypes, options.schema, this.driver.getSchemaName(meta, options), options.normalizeAccessors);
279
+ this.#hydrator.hydrate(entity, meta, data, this, 'full', options.newEntity, options.convertCustomTypes, options.schema, this.#driver.getSchemaName(meta, options), options.normalizeAccessors);
262
280
  }
263
281
  else {
264
- this.hydrator.hydrateReference(entity, meta, data, this, options.convertCustomTypes, options.schema, this.driver.getSchemaName(meta, options), options.normalizeAccessors);
282
+ this.#hydrator.hydrateReference(entity, meta, data, this, options.convertCustomTypes, options.schema, this.#driver.getSchemaName(meta, options), options.normalizeAccessors);
265
283
  }
266
284
  Utils.keys(data).forEach(key => {
267
285
  helper(entity)?.__loadedProperties.add(key);
268
286
  helper(entity)?.__serializationContext.fields?.add(key);
269
287
  });
270
- const processOnCreateHooksEarly = options.processOnCreateHooksEarly ?? this.config.get('processOnCreateHooksEarly');
288
+ const processOnCreateHooksEarly = options.processOnCreateHooksEarly ?? this.#config.get('processOnCreateHooksEarly');
271
289
  if (options.newEntity && processOnCreateHooksEarly) {
272
290
  this.assignDefaultValues(entity, meta);
273
291
  }
274
292
  }
275
293
  findEntity(data, meta, options) {
276
- const schema = this.driver.getSchemaName(meta, options);
294
+ const schema = this.#driver.getSchemaName(meta, options);
277
295
  if (meta.simplePK) {
278
296
  return this.unitOfWork.getById(meta.class, data[meta.primaryKeys[0]], schema);
279
297
  }
280
298
  if (!Array.isArray(data) && meta.primaryKeys.some(pk => data[pk] == null)) {
281
299
  return undefined;
282
300
  }
283
- const pks = Utils.getOrderedPrimaryKeys(data, meta, this.platform, options.convertCustomTypes);
301
+ const pks = Utils.getOrderedPrimaryKeys(data, meta, this.#platform, options.convertCustomTypes);
284
302
  return this.unitOfWork.getById(meta.class, pks, schema);
285
303
  }
286
304
  processDiscriminatorColumn(meta, data) {
@@ -289,7 +307,7 @@ export class EntityFactory {
289
307
  const prop = meta.properties[meta.root.discriminatorColumn];
290
308
  const value = data[prop.name];
291
309
  const type = meta.root.discriminatorMap[value];
292
- meta = type ? this.metadata.get(type) : meta;
310
+ meta = type ? this.#metadata.get(type) : meta;
293
311
  return meta;
294
312
  }
295
313
  // Handle TPT discriminator (computed at query time)
@@ -297,7 +315,7 @@ export class EntityFactory {
297
315
  const value = data[meta.root.tptDiscriminatorColumn];
298
316
  if (value) {
299
317
  const type = meta.root.discriminatorMap[value];
300
- meta = type ? this.metadata.get(type) : meta;
318
+ meta = type ? this.#metadata.get(type) : meta;
301
319
  }
302
320
  }
303
321
  return meta;
@@ -312,7 +330,7 @@ export class EntityFactory {
312
330
  return;
313
331
  }
314
332
  if (pk.type === 'ObjectId' && (data[pk.name] != null || data[spk.name] != null)) {
315
- data[pk.name] = this.platform.denormalizePrimaryKey((data[spk.name] || data[pk.name]));
333
+ data[pk.name] = this.#platform.denormalizePrimaryKey((data[spk.name] || data[pk.name]));
316
334
  delete data[spk.name];
317
335
  }
318
336
  }
@@ -356,22 +374,24 @@ export class EntityFactory {
356
374
  if (!options.convertCustomTypes || !prop.customType || tmp[prop.name] == null) {
357
375
  continue;
358
376
  }
359
- if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils.isPlainObject(tmp[prop.name]) && !Utils.extractPK(tmp[prop.name], prop.targetMeta, true)) {
377
+ if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) &&
378
+ Utils.isPlainObject(tmp[prop.name]) &&
379
+ !Utils.extractPK(tmp[prop.name], prop.targetMeta, true)) {
360
380
  tmp[prop.name] = Reference.wrapReference(this.create(prop.targetMeta.class, tmp[prop.name], options), prop);
361
381
  }
362
382
  else if (prop.kind === ReferenceKind.SCALAR) {
363
- tmp[prop.name] = prop.customType.convertToJSValue(tmp[prop.name], this.platform);
383
+ tmp[prop.name] = prop.customType.convertToJSValue(tmp[prop.name], this.#platform);
364
384
  }
365
385
  }
366
386
  return tmp;
367
387
  }
368
388
  if (options.convertCustomTypes && prop.customType && value != null) {
369
- return prop.customType.convertToJSValue(value, this.platform);
389
+ return prop.customType.convertToJSValue(value, this.#platform);
370
390
  }
371
391
  return value;
372
392
  });
373
393
  }
374
394
  get unitOfWork() {
375
- return this.em.getUnitOfWork(false);
395
+ return this.#em.getUnitOfWork(false);
376
396
  }
377
397
  }
@@ -31,15 +31,21 @@ export class EntityHelper {
31
31
  EntityHelper.defineProperties(meta, fork);
32
32
  }
33
33
  const prototype = meta.prototype;
34
- if (!prototype.toJSON) { // toJSON can be overridden
35
- prototype.toJSON = function (...args) {
36
- // Guard against being called on the prototype itself (e.g. by serializers
37
- // walking the object graph and calling toJSON on prototype objects)
38
- if (this === prototype) {
39
- return {};
40
- }
41
- return EntityTransformer.toObject(this, ...args);
42
- };
34
+ if (!prototype.toJSON) {
35
+ // toJSON can be overridden
36
+ Object.defineProperty(prototype, 'toJSON', {
37
+ value: function (...args) {
38
+ // Guard against being called on the prototype itself (e.g. by serializers
39
+ // walking the object graph and calling toJSON on prototype objects)
40
+ if (this === prototype) {
41
+ return {};
42
+ }
43
+ return EntityTransformer.toObject(this, ...args);
44
+ },
45
+ writable: true,
46
+ configurable: true,
47
+ enumerable: false,
48
+ });
43
49
  }
44
50
  }
45
51
  /**
@@ -49,6 +55,7 @@ export class EntityHelper {
49
55
  * property on the entity instance, so shadowing the prototype setter.
50
56
  */
51
57
  static defineBaseProperties(meta, prototype, em) {
58
+ // oxfmt-ignore
52
59
  const helperParams = meta.embeddable || meta.virtual ? [] : [em.getComparator().getPkGetter(meta), em.getComparator().getPkSerializer(meta), em.getComparator().getPkGetterConverted(meta)];
53
60
  Object.defineProperties(prototype, {
54
61
  __entity: { value: !meta.embeddable, configurable: true },
@@ -78,10 +85,9 @@ export class EntityHelper {
78
85
  * than on its prototype. Thanks to this we still have those properties enumerable (e.g. part of `Object.keys(entity)`).
79
86
  */
80
87
  static defineProperties(meta, em) {
81
- Object
82
- .values(meta.properties)
83
- .forEach(prop => {
88
+ Object.values(meta.properties).forEach(prop => {
84
89
  const isCollection = [ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind);
90
+ // oxfmt-ignore
85
91
  const isReference = [ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind) && (prop.inversedBy || prop.mappedBy) && !prop.mapToPk;
86
92
  if (isReference) {
87
93
  Object.defineProperty(meta.prototype, prop.name, {
@@ -131,9 +137,7 @@ export class EntityHelper {
131
137
  }
132
138
  // ensure we dont have internal symbols in the POJO
133
139
  [OptionalProps, EntityRepositoryType, PrimaryKeyProp, EagerProps, HiddenProps, EntityName].forEach(sym => delete object[sym]);
134
- meta.props
135
- .filter(prop => object[prop.name] === undefined)
136
- .forEach(prop => delete object[prop.name]);
140
+ meta.props.filter(prop => object[prop.name] === undefined).forEach(prop => delete object[prop.name]);
137
141
  const ret = inspect(object, { depth });
138
142
  let name = this.constructor.name;
139
143
  const showEM = ['true', 't', '1'].includes(getEnv('MIKRO_ORM_LOG_EM_ID')?.toLowerCase() ?? '');
@@ -161,6 +165,7 @@ export class EntityHelper {
161
165
  set(val) {
162
166
  const entity = Reference.unwrapReference(val ?? wrapped.__data[prop.name]);
163
167
  const old = Reference.unwrapReference(wrapped.__data[prop.name]);
168
+ // oxfmt-ignore
164
169
  if (old && old !== entity && prop.kind === ReferenceKind.MANY_TO_ONE && prop.inversedBy && old[prop.inversedBy]) {
165
170
  old[prop.inversedBy].removeWithoutPropagation(this);
166
171
  }
@@ -192,6 +197,7 @@ export class EntityHelper {
192
197
  if ((prop2.inversedBy || prop2.mappedBy) !== prop.name) {
193
198
  continue;
194
199
  }
200
+ // oxfmt-ignore
195
201
  if (prop2.targetMeta.abstract ? prop2.targetMeta.root.class !== meta.root.class : prop2.targetMeta.class !== meta.class) {
196
202
  continue;
197
203
  }
@@ -223,7 +229,10 @@ export class EntityHelper {
223
229
  static propagateOneToOne(entity, owner, prop, prop2, value, old) {
224
230
  helper(entity).__pk = helper(entity).getPrimaryKey();
225
231
  // the inverse side will be changed on the `value` too, so we need to clean-up and schedule orphan removal there too
226
- if (!prop.primary && !prop2.mapToPk && value?.[prop2.name] != null && Reference.unwrapReference(value[prop2.name]) !== entity) {
232
+ if (!prop.primary &&
233
+ !prop2.mapToPk &&
234
+ value?.[prop2.name] != null &&
235
+ Reference.unwrapReference(value[prop2.name]) !== entity) {
227
236
  const other = Reference.unwrapReference(value[prop2.name]);
228
237
  delete helper(other).__data[prop.name];
229
238
  if (prop2.orphanRemoval) {
@@ -22,9 +22,7 @@ export interface EntityLoaderOptions<Entity, Fields extends string = PopulatePat
22
22
  logging?: LoggingOptions;
23
23
  }
24
24
  export declare class EntityLoader {
25
- private readonly em;
26
- private readonly metadata;
27
- private readonly driver;
25
+ #private;
28
26
  constructor(em: EntityManager);
29
27
  /**
30
28
  * Loads specified relations in batch.