@mikro-orm/core 7.1.0-dev.36 → 7.1.0-dev.37

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
@@ -797,7 +797,10 @@ export class EntityManager {
797
797
  data = QueryHelper.processObjectParams(data);
798
798
  validateParams(data, 'insert data');
799
799
  if (em.eventManager.hasListeners(EventType.beforeUpsert, meta)) {
800
- await em.eventManager.dispatchEvent(EventType.beforeUpsert, { entity: data, em, meta }, meta);
800
+ await em.eventManager.dispatchEvent(EventType.beforeUpsert, { entity: entity ?? data, em, meta }, meta);
801
+ if (entity) {
802
+ data = em.#comparator.prepareEntity(entity);
803
+ }
801
804
  }
802
805
  const ret = await em.driver.nativeUpdate(entityName, where, data, {
803
806
  ctx: em.#transactionContext,
@@ -912,6 +915,7 @@ export class EntityManager {
912
915
  const allWhere = [];
913
916
  const entities = new Map();
914
917
  const entitiesByData = new Map();
918
+ const entitiesByAllDataIdx = new Map();
915
919
  for (let i = 0; i < data.length; i++) {
916
920
  let row = data[i];
917
921
  let where;
@@ -925,6 +929,7 @@ export class EntityManager {
925
929
  }
926
930
  where = helper(entity).getPrimaryKey();
927
931
  em.#entityFactory.assignDefaultValues(entity, meta);
932
+ entitiesByAllDataIdx.set(allData.length, entity);
928
933
  row = em.#comparator.prepareEntity(entity);
929
934
  }
930
935
  else {
@@ -972,6 +977,9 @@ export class EntityManager {
972
977
  const entity = entitiesByData.get(dto) ?? dto;
973
978
  await em.eventManager.dispatchEvent(EventType.beforeUpsert, { entity, em, meta }, meta);
974
979
  }
980
+ for (const [idx, entity] of entitiesByAllDataIdx) {
981
+ allData[idx] = em.#comparator.prepareEntity(entity);
982
+ }
975
983
  }
976
984
  const res = await em.driver.nativeUpdateMany(entityName, allWhere, allData, {
977
985
  ctx: em.#transactionContext,
package/index.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * @module core
4
4
  */
5
5
  export { EntityMetadata, PrimaryKeyProp, EntityRepositoryType, OptionalProps, EagerProps, HiddenProps, Config, EntityName, IndexHints, } from './typings.js';
6
- export type { CompiledFunctions, Constructor, ConnectionType, Dictionary, Primary, IPrimaryKey, ObjectQuery, FilterQuery, IWrappedEntity, InferEntityName, EntityData, Highlighter, MaybePromise, AnyEntity, EntityClass, EntityProperty, PopulateOptions, Populate, Loaded, New, LoadedReference, LoadedCollection, IMigrator, IMigrationGenerator, MigratorEvent, GetRepository, MigrationObject, DeepPartial, PrimaryProperty, Cast, IsUnknown, EntityDictionary, EntityDTO, EntityDTOFlat, EntityDTOProp, SerializeDTO, MigrationDiff, GenerateOptions, FilterObject, IndexFilterQuery, ExtractIndexHints, IndexName, IndexColumns, WithUsingOptions, IMigrationRunner, IEntityGenerator, ISeedManager, SeederObject, IMigratorStorage, RequiredEntityData, CheckCallback, TriggerCallback, IndexCallback, FormulaCallback, FormulaColumns, FormulaTable, SchemaTable, SchemaColumns, EntityDataPropValue, SimpleColumnMeta, Rel, Ref, LazyRef, ScalarRef, EntityRef, ISchemaGenerator, MigrationInfo, MigrateOptions, MigrationResult, MigrationRow, EntityKey, EntityValue, EntityDataValue, FilterKey, EntityType, FromEntityType, Selected, IsSubset, EntityProps, ExpandProperty, ExpandScalar, FilterItemValue, ExpandQuery, Scalar, ExpandHint, FilterValue, MergeLoaded, MergeSelected, TypeConfig, AnyString, ClearDatabaseOptions, CreateSchemaOptions, EnsureDatabaseOptions, UpdateSchemaOptions, DropSchemaOptions, RefreshDatabaseOptions, AutoPath, UnboxArray, MetadataProcessor, ImportsResolver, RequiredNullable, DefineConfig, Opt, Hidden, EntitySchemaWithMeta, InferEntity, CheckConstraint, TriggerDef, GeneratedColumnCallback, FilterDef, EntityCtor, Subquery, PopulateHintOptions, Prefixes, } from './typings.js';
6
+ export type { CompiledFunctions, Constructor, ConnectionType, Dictionary, Primary, IPrimaryKey, ObjectQuery, FilterQuery, IWrappedEntity, InferEntityName, EntityData, Highlighter, MaybePromise, AnyEntity, EntityClass, EntityProperty, PopulateOptions, Populate, Loaded, New, LoadedReference, LoadedCollection, IMigrator, IMigrationGenerator, MigratorEvent, GetRepository, MigrationObject, DeepPartial, PrimaryProperty, Cast, IsUnknown, EntityDictionary, EntityDTO, EntityDTOFlat, EntityDTOProp, SerializeDTO, MigrationDiff, GenerateOptions, FilterObject, IndexFilterQuery, ExtractIndexHints, IndexName, IndexColumns, WithUsingOptions, IMigrationRunner, IEntityGenerator, ISeedManager, SeederObject, IMigratorStorage, RequiredEntityData, CheckCallback, TriggerCallback, IndexCallback, FormulaCallback, FormulaColumns, FormulaTable, SchemaTable, SchemaColumns, SchemaColumnRef, EntityDataPropValue, SimpleColumnMeta, Rel, Ref, LazyRef, ScalarRef, EntityRef, ISchemaGenerator, MigrationInfo, MigrateOptions, MigrationResult, MigrationRow, EntityKey, EntityValue, EntityDataValue, FilterKey, EntityType, FromEntityType, Selected, IsSubset, EntityProps, ExpandProperty, ExpandScalar, FilterItemValue, ExpandQuery, Scalar, ExpandHint, FilterValue, MergeLoaded, MergeSelected, TypeConfig, AnyString, ClearDatabaseOptions, CreateSchemaOptions, EnsureDatabaseOptions, UpdateSchemaOptions, DropSchemaOptions, RefreshDatabaseOptions, AutoPath, UnboxArray, MetadataProcessor, ImportsResolver, RequiredNullable, DefineConfig, Opt, Hidden, EntitySchemaWithMeta, InferEntity, CheckConstraint, TriggerDef, GeneratedColumnCallback, FilterDef, EntityCtor, Subquery, PopulateHintOptions, Prefixes, } from './typings.js';
7
7
  export * from './enums.js';
8
8
  export * from './errors.js';
9
9
  export * from './exceptions.js';
@@ -1030,10 +1030,14 @@ export class MetadataDiscovery {
1030
1030
  meta.propertyOrder.set(prop.name, (order += 0.01));
1031
1031
  });
1032
1032
  }
1033
- meta.indexes = Utils.unique([...base.indexes, ...meta.indexes]);
1034
- meta.uniques = Utils.unique([...base.uniques, ...meta.uniques]);
1035
- meta.checks = Utils.unique([...base.checks, ...meta.checks]);
1036
- meta.triggers = Utils.unique([...base.triggers, ...meta.triggers]);
1033
+ // TPT children have their own tables that don't contain the parent's columns,
1034
+ // so propagating parent indexes/uniques/checks/triggers would target missing columns.
1035
+ if (meta.inheritanceType !== 'tpt' || !meta.tptParent) {
1036
+ meta.indexes = Utils.unique([...base.indexes, ...meta.indexes]);
1037
+ meta.uniques = Utils.unique([...base.uniques, ...meta.uniques]);
1038
+ meta.checks = Utils.unique([...base.checks, ...meta.checks]);
1039
+ meta.triggers = Utils.unique([...base.triggers, ...meta.triggers]);
1040
+ }
1037
1041
  const pks = Object.values(meta.properties)
1038
1042
  .filter(p => p.primary)
1039
1043
  .map(p => p.name);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "7.1.0-dev.36",
3
+ "version": "7.1.0-dev.37",
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
@@ -673,21 +673,39 @@ export type SchemaTable = {
673
673
  export type FormulaColumns<T> = Record<PropertyName<T>, string> & {
674
674
  toString(): string;
675
675
  };
676
+ /**
677
+ * Column reference for schema callbacks. Behaves like a string (coercible via `toString()`),
678
+ * with arbitrary nested property access for embedded sub-columns (e.g. `cols.address.city`).
679
+ */
680
+ export type SchemaColumnRef = string & {
681
+ readonly [key: string]: SchemaColumnRef;
682
+ };
676
683
  /**
677
684
  * Column mapping for schema callbacks (indexes, checks, generated columns).
678
685
  * Maps property names to field names. For TPT entities, only includes properties
679
686
  * that belong to the current table (not inherited properties from parent tables).
687
+ * Embedded properties expose their sub-columns via nested access (e.g. `cols.address.city`),
688
+ * while coercing to the embedded property's own column name via `toString()` (matches the
689
+ * pre-7712 behaviour, regardless of any custom `prefix`).
690
+ */
691
+ export type SchemaColumns<T> = Record<PropertyName<T>, SchemaColumnRef>;
692
+ /**
693
+ * Callback for custom index expressions. Receives column mappings, table info, and the index name.
694
+ * The runtime `columns` object includes nested entries for embedded properties (see `SchemaColumnRef`);
695
+ * cast to `SchemaColumns<T>` if you need typed nested access.
680
696
  */
681
- export type SchemaColumns<T> = Record<PropertyName<T>, string>;
682
- /** Callback for custom index expressions. Receives column mappings, table info, and the index name. */
683
697
  export type IndexCallback<T> = (columns: Record<PropertyName<T>, string>, table: SchemaTable, indexName: string) => string | Raw;
684
698
  /** Callback for computed (formula) properties. Receives column mappings and table info, returns a SQL expression. */
685
699
  export type FormulaCallback<T> = (columns: FormulaColumns<T>, table: FormulaTable) => string | Raw;
686
700
  /** Callback for CHECK constraint expressions. Receives column mappings and table info. */
687
- export type CheckCallback<T> = (columns: Record<PropertyName<T>, string>, table: SchemaTable) => string | Raw;
701
+ export type CheckCallback<T> = (columns: SchemaColumns<T>, table: SchemaTable) => string | Raw;
688
702
  /** Callback for trigger body expressions. Receives column mappings and table info. */
689
703
  export type TriggerCallback<T> = (columns: Record<PropertyName<T>, string>, table: SchemaTable) => string | Raw;
690
- /** Callback for generated (computed) column expressions. Receives column mappings and table info. */
704
+ /**
705
+ * Callback for generated (computed) column expressions. Receives column mappings and table info.
706
+ * The runtime `columns` object includes nested entries for embedded properties (see `SchemaColumnRef`);
707
+ * cast to `SchemaColumns<T>` if you need typed nested access.
708
+ */
691
709
  export type GeneratedColumnCallback<T> = (columns: Record<PropertyName<T>, string>, table: SchemaTable) => string | Raw;
692
710
  /** Definition of a CHECK constraint on a table or property. */
693
711
  export interface CheckConstraint<T = any> {
@@ -842,8 +860,12 @@ export declare class EntityMetadata<Entity = any, Class extends EntityCtor<Entit
842
860
  /**
843
861
  * Creates a column mapping for schema callbacks (indexes, checks, generated columns).
844
862
  * For TPT entities, only includes properties that belong to the current table (ownProps).
863
+ * Embedded properties expose their sub-columns via nested access (e.g. `cols.address.city`),
864
+ * while still coercing to the embedded column prefix when used as a string (GH #7712).
845
865
  */
846
866
  createSchemaColumnMappingObject(): SchemaColumns<Entity>;
867
+ /** @internal Recursively builds a column mapping for an embedded property's sub-columns. */
868
+ private static buildEmbeddedColumnMapping;
847
869
  get tableName(): string;
848
870
  set tableName(name: string);
849
871
  get uniqueName(): string;
package/typings.js CHANGED
@@ -133,16 +133,37 @@ export class EntityMetadata {
133
133
  /**
134
134
  * Creates a column mapping for schema callbacks (indexes, checks, generated columns).
135
135
  * For TPT entities, only includes properties that belong to the current table (ownProps).
136
+ * Embedded properties expose their sub-columns via nested access (e.g. `cols.address.city`),
137
+ * while still coercing to the embedded column prefix when used as a string (GH #7712).
136
138
  */
137
139
  createSchemaColumnMappingObject() {
138
140
  // For TPT entities, only include properties that belong to this entity's table
139
141
  const props = this.inheritanceType === 'tpt' && this.ownProps ? this.ownProps : Object.values(this.properties);
140
- return props.reduce((o, prop) => {
141
- if (prop.fieldNames) {
142
- o[prop.name] = prop.fieldNames[0];
142
+ const result = {};
143
+ for (const prop of props) {
144
+ if (!prop.fieldNames) {
145
+ continue;
143
146
  }
144
- return o;
145
- }, {});
147
+ if (prop.kind === ReferenceKind.EMBEDDED && prop.embeddedProps) {
148
+ result[prop.name] = EntityMetadata.buildEmbeddedColumnMapping(prop);
149
+ continue;
150
+ }
151
+ result[prop.name] = prop.fieldNames[0];
152
+ }
153
+ return result;
154
+ }
155
+ /** @internal Recursively builds a column mapping for an embedded property's sub-columns. */
156
+ static buildEmbeddedColumnMapping(embeddedProp) {
157
+ const result = {};
158
+ for (const [name, sub] of Object.entries(embeddedProp.embeddedProps)) {
159
+ result[name] =
160
+ sub.kind === ReferenceKind.EMBEDDED && sub.embeddedProps
161
+ ? EntityMetadata.buildEmbeddedColumnMapping(sub)
162
+ : sub.fieldNames[0];
163
+ }
164
+ const prefix = embeddedProp.fieldNames[0];
165
+ Object.defineProperty(result, 'toString', { value: () => prefix, enumerable: false });
166
+ return result;
146
167
  }
147
168
  get tableName() {
148
169
  return this.collection;
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.36';
144
+ static #ORM_VERSION = '7.1.0-dev.37';
145
145
  /**
146
146
  * Checks if the argument is instance of `Object`. Returns false for arrays.
147
147
  */