@mikro-orm/core 6.4.17-dev.46 → 6.4.17-dev.48

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.
@@ -542,11 +542,18 @@ export interface CreateOptions<Convert extends boolean> {
542
542
  partial?: boolean;
543
543
  /** convert raw database values based on mapped types (by default, already converted values are expected) */
544
544
  convertCustomTypes?: Convert;
545
+ /**
546
+ * Property `onCreate` hooks are normally executed during `flush` operation.
547
+ * With this option, they will be processed early inside `em.create()` method.
548
+ */
549
+ processOnCreateHooksEarly?: boolean;
545
550
  }
546
551
  export interface MergeOptions {
547
552
  refresh?: boolean;
548
553
  convertCustomTypes?: boolean;
549
554
  schema?: string;
555
+ disableContextResolution?: boolean;
556
+ keepIdentity?: boolean;
550
557
  }
551
558
  export interface ForkOptions {
552
559
  /** do we want a clear identity map? defaults to true */
package/EntityManager.js CHANGED
@@ -988,8 +988,7 @@ class EntityManager {
988
988
  if (propagateToUpperContext) {
989
989
  // ensure all entities from inner context are merged to the upper one
990
990
  for (const entity of fork.unitOfWork.getIdentityMap()) {
991
- em.unitOfWork.register(entity);
992
- entity.__helper.__em = em;
991
+ em.merge(entity, { disableContextResolution: true, keepIdentity: true, refresh: true });
993
992
  }
994
993
  }
995
994
  return ret;
@@ -1174,10 +1173,10 @@ class EntityManager {
1174
1173
  * via second parameter. By default, it will return already loaded entities without modifying them.
1175
1174
  */
1176
1175
  merge(entityName, data, options = {}) {
1177
- const em = this.getContext();
1178
1176
  if (utils_1.Utils.isEntity(entityName)) {
1179
- return em.merge(entityName.constructor.name, entityName, data);
1177
+ return this.merge(entityName.constructor.name, entityName, data);
1180
1178
  }
1179
+ const em = options.disableContextResolution ? this : this.getContext();
1181
1180
  options.schema ??= em._schema;
1182
1181
  entityName = utils_1.Utils.className(entityName);
1183
1182
  em.validator.validatePrimaryKey(data, em.metadata.get(entityName));
@@ -1187,7 +1186,12 @@ class EntityManager {
1187
1186
  }
1188
1187
  const meta = em.metadata.find(entityName);
1189
1188
  const childMeta = em.metadata.getByDiscriminatorColumn(meta, data);
1190
- entity = utils_1.Utils.isEntity(data) ? data : em.entityFactory.create(entityName, data, { merge: true, ...options });
1189
+ const dataIsEntity = utils_1.Utils.isEntity(data);
1190
+ if (options.keepIdentity && entity && dataIsEntity && entity !== data) {
1191
+ em.entityFactory.mergeData(meta, entity, (0, entity_1.helper)(data).__originalEntityData, { initialized: true, merge: true, ...options });
1192
+ return entity;
1193
+ }
1194
+ entity = dataIsEntity ? data : em.entityFactory.create(entityName, data, { merge: true, ...options });
1191
1195
  em.validator.validate(entity, data, childMeta ?? meta);
1192
1196
  em.unitOfWork.merge(entity);
1193
1197
  return entity;
@@ -4,6 +4,11 @@ import type { EntityComparator } from '../utils/EntityComparator';
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;
@@ -27,6 +32,7 @@ export declare class EntityFactory {
27
32
  createEmbeddable<T extends object>(entityName: EntityName<T>, data: EntityData<T>, options?: Pick<FactoryOptions, 'newEntity' | 'convertCustomTypes'>): T;
28
33
  getComparator(): EntityComparator;
29
34
  private createEntity;
35
+ private assignDefaultValues;
30
36
  private hydrate;
31
37
  private findEntity;
32
38
  private processDiscriminatorColumn;
@@ -234,6 +234,13 @@ class EntityFactory {
234
234
  }
235
235
  return entity;
236
236
  }
237
+ assignDefaultValues(entity, meta) {
238
+ for (const prop of meta.props) {
239
+ if (prop.onCreate) {
240
+ entity[prop.name] ??= prop.onCreate(entity, this.em);
241
+ }
242
+ }
243
+ }
237
244
  hydrate(entity, meta, data, options) {
238
245
  if (options.initialized) {
239
246
  this.hydrator.hydrate(entity, meta, data, this, 'full', options.newEntity, options.convertCustomTypes, options.schema, this.driver.getSchemaName(meta, options));
@@ -245,6 +252,10 @@ class EntityFactory {
245
252
  (0, wrap_1.helper)(entity)?.__loadedProperties.add(key);
246
253
  (0, wrap_1.helper)(entity)?.__serializationContext.fields?.add(key);
247
254
  });
255
+ const processOnCreateHooksEarly = options.processOnCreateHooksEarly ?? this.config.get('processOnCreateHooksEarly');
256
+ if (options.newEntity && processOnCreateHooksEarly) {
257
+ this.assignDefaultValues(entity, meta);
258
+ }
248
259
  }
249
260
  findEntity(data, meta, options) {
250
261
  const schema = this.driver.getSchemaName(meta, options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "6.4.17-dev.46",
3
+ "version": "6.4.17-dev.48",
4
4
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -64,7 +64,7 @@
64
64
  "esprima": "4.0.1",
65
65
  "fs-extra": "11.3.0",
66
66
  "globby": "11.1.0",
67
- "mikro-orm": "6.4.17-dev.46",
67
+ "mikro-orm": "6.4.17-dev.48",
68
68
  "reflect-metadata": "0.2.2"
69
69
  }
70
70
  }
@@ -77,6 +77,7 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
77
77
  upsertManaged: true;
78
78
  forceEntityConstructor: false;
79
79
  forceUndefined: false;
80
+ processOnCreateHooksEarly: false;
80
81
  ensureDatabase: true;
81
82
  ensureIndexes: false;
82
83
  batchSize: number;
@@ -345,6 +346,11 @@ export interface MikroORMOptions<D extends IDatabaseDriver = IDatabaseDriver, EM
345
346
  upsertManaged: boolean;
346
347
  forceEntityConstructor: boolean | (Constructor<AnyEntity> | string)[];
347
348
  forceUndefined: boolean;
349
+ /**
350
+ * Property `onCreate` hooks are normally executed during `flush` operation.
351
+ * With this option, they will be processed early inside `em.create()` method.
352
+ */
353
+ processOnCreateHooksEarly: boolean;
348
354
  forceUtcTimezone?: boolean;
349
355
  timezone?: string;
350
356
  ensureDatabase: boolean | EnsureDatabaseOptions;
@@ -71,6 +71,7 @@ class Configuration {
71
71
  upsertManaged: true,
72
72
  forceEntityConstructor: false,
73
73
  forceUndefined: false,
74
+ processOnCreateHooksEarly: false,
74
75
  ensureDatabase: true,
75
76
  ensureIndexes: false,
76
77
  batchSize: 300,