@mikro-orm/core 6.4.17-dev.3 → 6.4.17-dev.30

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.js CHANGED
@@ -488,11 +488,17 @@ class EntityManager {
488
488
  ...options,
489
489
  flushMode: enums_1.FlushMode.COMMIT,
490
490
  });
491
+ const em = this.getContext();
491
492
  if (reloaded) {
492
- this.config.getHydrator(this.metadata).hydrate(entity, (0, entity_1.helper)(entity).__meta, (0, entity_1.helper)(reloaded).toPOJO(), this.getEntityFactory(), 'full', false, true);
493
+ for (const e of fork.unitOfWork.getIdentityMap()) {
494
+ const ref = em.getReference(e.constructor.name, (0, entity_1.helper)(e).getPrimaryKey());
495
+ const data = this.comparator.prepareEntity(e);
496
+ em.config.getHydrator(this.metadata).hydrate(ref, (0, entity_1.helper)(ref).__meta, (0, entity_1.helper)(e).toPOJO(), em.entityFactory, 'full', false, true);
497
+ (0, entity_1.helper)(ref).__originalEntityData = data;
498
+ }
493
499
  }
494
500
  else {
495
- this.getUnitOfWork().unsetIdentity(entity);
501
+ em.unitOfWork.unsetIdentity(entity);
496
502
  }
497
503
  return reloaded ? entity : reloaded;
498
504
  }
@@ -1267,7 +1273,7 @@ class EntityManager {
1267
1273
  if (cached?.data !== undefined) {
1268
1274
  return cached.data;
1269
1275
  }
1270
- const count = await em.driver.count(entityName, where, { ctx: em.transactionContext, ...options });
1276
+ const count = await em.driver.count(entityName, where, { ctx: em.transactionContext, em, ...options });
1271
1277
  await em.storeCache(options.cache, cached, () => +count);
1272
1278
  return +count;
1273
1279
  }
@@ -1,4 +1,4 @@
1
- import type { EntityClass, Dictionary, AutoPath } from '../typings';
1
+ import type { EntityClass, Dictionary, AutoPath, IndexCallback } from '../typings';
2
2
  import type { DeferMode } from '../enums';
3
3
  export declare function Index<T extends object, H extends string>(options?: IndexOptions<T, H>): (target: T, propertyName?: (T extends EntityClass<unknown> ? undefined : keyof T) | undefined) => any;
4
4
  export declare function Unique<T extends object, H extends string>(options?: UniqueOptions<T, H>): (target: T, propertyName?: (T extends EntityClass<unknown> ? undefined : keyof T) | undefined) => any;
@@ -8,7 +8,7 @@ interface BaseOptions<T, H extends string> {
8
8
  name?: string;
9
9
  properties?: (T extends EntityClass<infer P> ? Properties<P, H> : Properties<T, H>);
10
10
  options?: Dictionary;
11
- expression?: string;
11
+ expression?: string | (T extends EntityClass<infer P> ? IndexCallback<P> : IndexCallback<T>);
12
12
  }
13
13
  export interface UniqueOptions<T, H extends string = string> extends BaseOptions<T, H> {
14
14
  deferMode?: DeferMode | `${DeferMode}`;
@@ -37,4 +37,6 @@ export interface ManyToManyOptions<Owner, Target> extends ReferenceOptions<Owner
37
37
  deleteRule?: 'cascade' | 'no action' | 'set null' | 'set default' | AnyString;
38
38
  /** What to do when the reference to the target entity gets updated. */
39
39
  updateRule?: 'cascade' | 'no action' | 'set null' | 'set default' | AnyString;
40
+ /** Enable/disable foreign key constraint creation on this relation */
41
+ createForeignKeyConstraint?: boolean;
40
42
  }
@@ -27,6 +27,8 @@ export interface ManyToOneOptions<Owner, Target> extends ReferenceOptions<Owner,
27
27
  updateRule?: 'cascade' | 'no action' | 'set null' | 'set default' | AnyString;
28
28
  /** Set the constraint type. Immediate constraints are checked for each statement, while deferred ones are only checked at the end of the transaction. Only for postgres unique constraints. */
29
29
  deferMode?: DeferMode | `${DeferMode}`;
30
+ /** Enable/disable foreign key constraint creation on this relation */
31
+ createForeignKeyConstraint?: boolean;
30
32
  /** Set a custom foreign key constraint name, overriding NamingStrategy.indexName(). */
31
33
  foreignKeyName?: string;
32
34
  }
@@ -23,4 +23,6 @@ export interface OneToOneOptions<Owner, Target> extends Partial<Omit<OneToManyOp
23
23
  deferMode?: DeferMode | `${DeferMode}`;
24
24
  /** Set a custom foreign key constraint name, overriding NamingStrategy.indexName(). */
25
25
  foreignKeyName?: string;
26
+ /** Enable/disable foreign key constraint creation on this relation */
27
+ createForeignKeyConstraint?: boolean;
26
28
  }
@@ -2,6 +2,7 @@ import type { TransactionOptions } from '../enums';
2
2
  import type { ContextProvider } from '../typings';
3
3
  type TransactionalOptions<T> = TransactionOptions & {
4
4
  context?: ContextProvider<T>;
5
+ contextName?: string;
5
6
  };
6
7
  /**
7
8
  * This decorator wraps the method with `em.transactional()`, so you can provide `TransactionOptions` just like with `em.transactional()`.
@@ -17,10 +17,10 @@ function Transactional(options = {}) {
17
17
  throw new Error('@Transactional() should be use with async functions');
18
18
  }
19
19
  descriptor.value = async function (...args) {
20
- const { context, ...txOptions } = options;
20
+ const { context, contextName, ...txOptions } = options;
21
21
  const em = await (0, resolveContextProvider_1.resolveContextProvider)(this, context)
22
- || TransactionContext_1.TransactionContext.getEntityManager()
23
- || RequestContext_1.RequestContext.getEntityManager();
22
+ || TransactionContext_1.TransactionContext.getEntityManager(contextName)
23
+ || RequestContext_1.RequestContext.getEntityManager(contextName);
24
24
  if (!em) {
25
25
  throw new Error(`@Transactional() decorator can only be applied to methods of classes with \`orm: MikroORM\` property, \`em: EntityManager\` property, or with a callback parameter like \`@Transactional(() => orm)\` that returns one of those types. The parameter will contain a reference to current \`this\`. Returning an EntityRepository from it is also supported.`);
26
26
  }
@@ -200,6 +200,8 @@ export interface CountOptions<T extends object, P extends string = never> {
200
200
  hintComments?: string | string[];
201
201
  loggerContext?: LogContext;
202
202
  logging?: LoggingOptions;
203
+ /** @internal used to apply filters to the auto-joined relations */
204
+ em?: EntityManager;
203
205
  }
204
206
  export interface UpdateOptions<T> {
205
207
  filters?: FilterOptions;
@@ -74,7 +74,7 @@ class EntityFactory {
74
74
  continue;
75
75
  }
76
76
  if ([enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils_1.Utils.isPlainObject(data[prop.name])) {
77
- data[prop.name] = Utils_1.Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta.primaryKeys, true);
77
+ data[prop.name] = Utils_1.Utils.getPrimaryKeyValues(data[prop.name], prop.targetMeta, true);
78
78
  }
79
79
  data[prop.name] = prop.customType.convertToDatabaseValue(data[prop.name], this.platform, { key: prop.name, mode: 'hydration' });
80
80
  }
@@ -155,7 +155,7 @@ class EntityHelper {
155
155
  wrapped.__data[prop.name] = Reference_1.Reference.wrapReference(val, prop);
156
156
  // when propagation from inside hydration, we set the FK to the entity data immediately
157
157
  if (val && hydrator.isRunning() && wrapped.__originalEntityData && prop.owner) {
158
- wrapped.__originalEntityData[prop.name] = Utils_1.Utils.getPrimaryKeyValues(wrapped.__data[prop.name], prop.targetMeta.primaryKeys, true);
158
+ wrapped.__originalEntityData[prop.name] = Utils_1.Utils.getPrimaryKeyValues(wrapped.__data[prop.name], prop.targetMeta, true);
159
159
  }
160
160
  else {
161
161
  wrapped.__touched = !hydrator.isRunning();
@@ -154,7 +154,7 @@ class EntityLoader {
154
154
  }
155
155
  async populateScalar(meta, filtered, options) {
156
156
  const pk = Utils_1.Utils.getPrimaryKeyHash(meta.primaryKeys);
157
- const ids = Utils_1.Utils.unique(filtered.map(e => Utils_1.Utils.getPrimaryKeyValues(e, meta.primaryKeys, true)));
157
+ const ids = Utils_1.Utils.unique(filtered.map(e => Utils_1.Utils.getPrimaryKeyValues(e, meta, true)));
158
158
  const where = this.mergePrimaryCondition(ids, pk, options, meta, this.metadata, this.driver.getPlatform());
159
159
  const { filters, convertCustomTypes, lockMode, strategy, populateWhere, connectionType, logging, fields } = options;
160
160
  await this.em.find(meta.className, where, {
@@ -56,6 +56,11 @@ export declare class ScalarReference<Value> {
56
56
  * Returns either the whole entity, or the requested property.
57
57
  */
58
58
  load(options?: Omit<LoadReferenceOptions<any, any>, 'populate' | 'fields' | 'exclude'>): Promise<Value | undefined>;
59
+ /**
60
+ * Ensures the underlying entity is loaded first (without reloading it if it already is loaded).
61
+ * Returns the entity or throws an error just like `em.findOneOrFail()` (and respects the same config options).
62
+ */
63
+ loadOrFail(options?: Omit<LoadReferenceOrFailOptions<any, any>, 'populate' | 'fields' | 'exclude'>): Promise<Value>;
59
64
  set(value: Value): void;
60
65
  bind<Entity extends object>(entity: Entity, property: EntityKey<Entity>): void;
61
66
  unwrap(): Value | undefined;
@@ -7,6 +7,7 @@ const node_util_1 = require("node:util");
7
7
  const enums_1 = require("../enums");
8
8
  const wrap_1 = require("./wrap");
9
9
  const utils_1 = require("../utils");
10
+ const errors_1 = require("../errors");
10
11
  class Reference {
11
12
  entity;
12
13
  constructor(entity) {
@@ -178,6 +179,21 @@ class ScalarReference {
178
179
  }
179
180
  return this.value;
180
181
  }
182
+ /**
183
+ * Ensures the underlying entity is loaded first (without reloading it if it already is loaded).
184
+ * Returns the entity or throws an error just like `em.findOneOrFail()` (and respects the same config options).
185
+ */
186
+ async loadOrFail(options = {}) {
187
+ const ret = await this.load(options);
188
+ if (!ret) {
189
+ const wrapped = (0, wrap_1.helper)(this.entity);
190
+ options.failHandler ??= wrapped.__em.config.get('findOneOrFailHandler');
191
+ const entityName = this.entity.constructor.name;
192
+ const where = wrapped.getPrimaryKey();
193
+ throw new errors_1.NotFoundError(`${entityName} (${where}) failed to load property '${this.property}'`);
194
+ }
195
+ return ret;
196
+ }
181
197
  set(value) {
182
198
  this.value = value;
183
199
  this.initialized = true;
@@ -153,7 +153,7 @@ class WrappedEntity {
153
153
  return this.__em?.config ?? this.entity.__config;
154
154
  }
155
155
  get __primaryKeys() {
156
- return Utils_1.Utils.getPrimaryKeyValues(this.entity, this.__meta.primaryKeys);
156
+ return Utils_1.Utils.getPrimaryKeyValues(this.entity, this.__meta);
157
157
  }
158
158
  /** @ignore */
159
159
  [node_util_1.inspect.custom]() {