@mikro-orm/core 7.1.0-dev.45 → 7.1.0-dev.47

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.
@@ -369,8 +369,11 @@ export class EntityLoader {
369
369
  }
370
370
  const fields = this.buildFields(options.fields, prop, ref);
371
371
  /* eslint-disable prefer-const */
372
- let { refresh, filters, convertCustomTypes, lockMode, strategy, populateWhere = 'infer', connectionType, logging, } = options;
372
+ let { refresh, filters, convertCustomTypes, lockMode, strategy, populateWhere, connectionType, logging } = options;
373
373
  /* eslint-enable prefer-const */
374
+ // `populateWhere` is typed as required via `Required<EntityLoaderOptions>`, but `em.populate(...)`
375
+ // forwards user-supplied options without filling it in — keep the runtime default.
376
+ populateWhere ??= 'infer';
374
377
  if (typeof populateWhere === 'object') {
375
378
  populateWhere = await this.extractChildCondition({ where: populateWhere }, prop);
376
379
  }
@@ -615,7 +615,7 @@ export type PropertyBuilders = {
615
615
  /** Own keys + base entity keys (when TBase is not `never`). Guards against `keyof never = string | number | symbol`. */
616
616
  type AllKeys<TProperties, TBase> = keyof TProperties | (IsNever<TBase> extends true ? never : keyof TBase);
617
617
  /** Metadata descriptor for `defineEntity()`, combining entity options with property definitions. */
618
- export interface EntityMetadataWithProperties<TName extends string, TTableName extends string, TProperties extends Record<string, any>, TPK extends (keyof TProperties)[] | undefined = undefined, TBase = never, TRepository = never, TForceObject extends boolean = false, TDiscriminatorColumn extends string | undefined = undefined, TDiscriminatorValue extends string | number | undefined = undefined, TBaseDiscriminatorColumn extends string | undefined = undefined> extends Omit<Partial<EntityMetadata<InferEntityFromProperties<TProperties, TPK, TBase, TRepository>>>, 'properties' | 'extends' | 'primaryKeys' | 'hooks' | 'discriminatorColumn' | 'discriminatorValue' | 'versionProperty' | 'concurrencyCheckKeys' | 'serializedPrimaryKey' | 'indexes' | 'uniques' | 'triggers' | 'repository' | 'filters' | 'orderBy'> {
618
+ export interface EntityMetadataWithProperties<TName extends string, TTableName extends string, TProperties extends Record<string, any>, TPK extends (keyof TProperties)[] | undefined = undefined, TBase = never, TRepository = never, TForceObject extends boolean = false, TDiscriminatorColumn extends string | undefined = undefined, TDiscriminatorValue extends string | number | undefined = undefined, TBaseDiscriminatorColumn extends string | undefined = undefined> extends Omit<Partial<EntityMetadata<InferEntityFromProperties<TProperties, TPK, TBase, TRepository>>>, 'properties' | 'extends' | 'primaryKeys' | 'hooks' | 'discriminator' | 'discriminatorColumn' | 'discriminatorValue' | 'versionProperty' | 'concurrencyCheckKeys' | 'serializedPrimaryKey' | 'indexes' | 'uniques' | 'triggers' | 'repository' | 'filters' | 'orderBy'> {
619
619
  name: TName;
620
620
  tableName?: TTableName;
621
621
  extends?: {
@@ -643,6 +643,8 @@ export interface EntityMetadataWithProperties<TName extends string, TTableName e
643
643
  } | {
644
644
  [K in Extract<AllKeys<TProperties, TBase>, string>]?: QueryOrderKeysFlat;
645
645
  }[];
646
+ discriminator?: TDiscriminatorColumn;
647
+ /** Alias for `discriminator`. */
646
648
  discriminatorColumn?: TDiscriminatorColumn;
647
649
  discriminatorValue?: TDiscriminatorValue;
648
650
  versionProperty?: AllKeys<TProperties, TBase>;
@@ -254,6 +254,21 @@ export class EntitySchema {
254
254
  return this;
255
255
  }
256
256
  this.setClass(this._meta.class);
257
+ // `discriminator` is the property name on the entity / embeddable; `discriminatorColumn` is an
258
+ // optional column-name override on that property. For backward compat, when only
259
+ // `discriminatorColumn` is given (legacy), it is treated as the property name. Once normalized,
260
+ // `meta.discriminatorColumn` always holds the property name (so existing readers keep working),
261
+ // and `meta.discriminatorFieldName` carries the explicit column override (if any).
262
+ if (this._meta.discriminator &&
263
+ this._meta.discriminatorColumn &&
264
+ this._meta.discriminator !== this._meta.discriminatorColumn) {
265
+ this._meta.discriminatorFieldName = this._meta.discriminatorColumn;
266
+ this._meta.discriminatorColumn = this._meta.discriminator;
267
+ }
268
+ else {
269
+ this._meta.discriminatorColumn ??= this._meta.discriminator;
270
+ this._meta.discriminator ??= this._meta.discriminatorColumn;
271
+ }
257
272
  // Abstract TPT entities keep their name because they have their own table
258
273
  const isTPT = this._meta.inheritance === 'tpt' || this.isPartOfTPTHierarchy();
259
274
  if (this._meta.abstract && !this._meta.discriminatorColumn && !isTPT) {
@@ -1582,13 +1582,18 @@ export class MetadataDiscovery {
1582
1582
  });
1583
1583
  }
1584
1584
  createDiscriminatorProperty(meta) {
1585
- meta.addProperty({
1585
+ const prop = {
1586
1586
  name: meta.discriminatorColumn,
1587
1587
  type: 'string',
1588
1588
  enum: true,
1589
1589
  kind: ReferenceKind.SCALAR,
1590
1590
  userDefined: false,
1591
- });
1591
+ };
1592
+ // honor the column-name override set via `discriminatorColumn` when `discriminator` is also given
1593
+ if (meta.discriminatorFieldName) {
1594
+ prop.fieldName = meta.discriminatorFieldName;
1595
+ }
1596
+ meta.addProperty(prop);
1592
1597
  }
1593
1598
  initAutoincrement(meta) {
1594
1599
  const pks = meta.getPrimaryProps();
@@ -65,8 +65,10 @@ export type EntityOptions<T, E = T extends EntityClass<infer P> ? P : T> = {
65
65
  * 3. Entity-level `@Entity({ orderBy })`
66
66
  */
67
67
  orderBy?: QueryOrderMap<E> | QueryOrderMap<E>[];
68
- /** For {@doclink inheritance-mapping#single-table-inheritance | Single Table Inheritance}. */
69
- discriminatorColumn?: (T extends EntityClass<infer P> ? keyof P : string) | AnyString;
68
+ /** For {@doclink inheritance-mapping#single-table-inheritance | Single Table Inheritance}. Property name on the entity that stores the discriminator value. */
69
+ discriminator?: (T extends EntityClass<infer P> ? keyof P : string) | AnyString;
70
+ /** For {@doclink inheritance-mapping#single-table-inheritance | Single Table Inheritance}. Override the discriminator column name (the property is named via `discriminator`; defaults to the naming-strategy-derived column). */
71
+ discriminatorColumn?: string;
70
72
  /** For {@doclink inheritance-mapping#single-table-inheritance | Single Table Inheritance}. */
71
73
  discriminatorMap?: Dictionary<string>;
72
74
  /** For {@doclink inheritance-mapping#single-table-inheritance | Single Table Inheritance}. */
@@ -553,10 +555,10 @@ export interface EmbeddedOptions<Owner, Target> extends PropertyOptions<Owner> {
553
555
  export interface EmbeddableOptions<Owner> {
554
556
  /** Specify constructor parameters to be used in `em.create` or when `forceConstructor` is enabled. Those should be names of declared entity properties in the same order as your constructor uses them. The ORM tries to infer those automatically, use this option in case the inference fails. */
555
557
  constructorParams?: (Owner extends EntityClass<infer P> ? keyof P : string)[];
556
- /** For polymorphic embeddables. Specify the property name that stores the discriminator value. Alias for `discriminatorColumn`. */
558
+ /** For polymorphic embeddables. Property name on the embeddable class that stores the discriminator value. */
557
559
  discriminator?: (Owner extends EntityClass<infer P> ? keyof P : string) | AnyString;
558
- /** For polymorphic embeddables. @deprecated Use `discriminator` instead. */
559
- discriminatorColumn?: (Owner extends EntityClass<infer P> ? keyof P : string) | AnyString;
560
+ /** For polymorphic embeddables. Override the discriminator column name (the property is named via `discriminator`; defaults to the naming-strategy-derived column). */
561
+ discriminatorColumn?: string;
560
562
  discriminatorMap?: Dictionary<string>;
561
563
  discriminatorValue?: number | string;
562
564
  abstract?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "7.1.0-dev.45",
3
+ "version": "7.1.0-dev.47",
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
  "keywords": [
6
6
  "data-mapper",
package/typings.d.ts CHANGED
@@ -1091,7 +1091,12 @@ export interface EntityMetadata<Entity = any, Class extends EntityCtor<Entity> =
1091
1091
  /** PostgreSQL partitioning definition for this table. */
1092
1092
  partitionBy?: EntityPartitionBy<Entity>;
1093
1093
  expression?: string | ((em: any, where: ObjectQuery<Entity>, options: FindOptions<Entity, any, any, any>, stream?: boolean) => MaybePromise<Raw | object | string>);
1094
+ /** Property name on the entity that stores the discriminator value. */
1095
+ discriminator?: EntityKey<Entity> | AnyString;
1096
+ /** Internally holds the discriminator property name (legacy) or a column-name override (when different from `discriminator`); normalized in `EntitySchema.init()`. */
1094
1097
  discriminatorColumn?: EntityKey<Entity> | AnyString;
1098
+ /** Explicit column-name override for the auto-managed discriminator property. Set when both `discriminator` and `discriminatorColumn` are provided and differ. */
1099
+ discriminatorFieldName?: string;
1095
1100
  discriminatorValue?: number | string;
1096
1101
  discriminatorMap?: Dictionary<EntityClass>;
1097
1102
  embeddable: boolean;
@@ -388,6 +388,23 @@ export class UnitOfWork {
388
388
  }
389
389
  continue;
390
390
  }
391
+ // inlined pivot M:N: scrub the deleted entity from each owning-side document's array;
392
+ // the owner's collection update rides along inside its UPDATE changeset in the same flush
393
+ if (prop.kind === ReferenceKind.MANY_TO_MANY &&
394
+ prop.mappedBy &&
395
+ !this.#platform.usesPivotTable() &&
396
+ Utils.isCollection(relation)) {
397
+ if (!relation.isInitialized(true)) {
398
+ throw ValidationError.cannotModifyInverseCollection(entity, prop);
399
+ }
400
+ for (const owner of relation.getItems(false)) {
401
+ const ownerColl = owner[inverseProp];
402
+ if (Utils.isCollection(ownerColl)) {
403
+ ownerColl.removeWithoutPropagation(entity);
404
+ }
405
+ }
406
+ continue;
407
+ }
391
408
  const target = relation?.[inverseProp];
392
409
  if (relation && Utils.isCollection(target)) {
393
410
  target.removeWithoutPropagation(entity);
package/utils/Utils.js CHANGED
@@ -141,7 +141,7 @@ export function parseJsonSafe(value) {
141
141
  /** Collection of general-purpose utility methods used throughout the ORM. */
142
142
  export class Utils {
143
143
  static PK_SEPARATOR = '~~~';
144
- static #ORM_VERSION = '7.1.0-dev.45';
144
+ static #ORM_VERSION = '7.1.0-dev.47';
145
145
  /**
146
146
  * Checks if the argument is instance of `Object`. Returns false for arrays.
147
147
  */