@mikro-orm/core 7.0.0-dev.305 → 7.0.0-dev.306

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "7.0.0-dev.305",
3
+ "version": "7.0.0-dev.306",
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",
@@ -27,6 +27,22 @@ export declare class QueryHelper {
27
27
  private static processJsonCondition;
28
28
  private static getValueType;
29
29
  static findProperty<T>(fieldName: string, options: ProcessWhereOptions<T>): EntityProperty<T> | undefined;
30
+ /**
31
+ * Converts entity references for composite FK properties into flat arrays
32
+ * of correctly-ordered join column values, before processParams flattens them
33
+ * incorrectly due to shared FK columns.
34
+ */
35
+ private static convertCompositeEntityRefs;
36
+ /**
37
+ * Extracts values for a FK's join columns from an entity by traversing the FK chain.
38
+ * Handles shared FK columns (e.g., tenant_id referenced by multiple FKs) correctly.
39
+ */
40
+ private static extractJoinColumnValues;
41
+ /**
42
+ * Extracts the value for a specific column from an entity by finding which PK property
43
+ * owns that column and recursively traversing FK references.
44
+ */
45
+ private static extractColumnValue;
30
46
  /**
31
47
  * Merges multiple orderBy sources with key-level deduplication (first-seen key wins).
32
48
  * RawQueryFragment symbol keys are never deduped (each is unique).
@@ -133,6 +133,9 @@ export class QueryHelper {
133
133
  QueryHelper.liftGroupOperators(where, meta, metadata);
134
134
  QueryHelper.inlinePrimaryKeyObjects(where, meta, metadata);
135
135
  }
136
+ if (meta && root) {
137
+ QueryHelper.convertCompositeEntityRefs(where, meta);
138
+ }
136
139
  if (platform.getConfig().get('ignoreUndefinedInQuery') && where && typeof where === 'object') {
137
140
  Utils.dropUndefinedProperties(where);
138
141
  }
@@ -312,6 +315,71 @@ export class QueryHelper {
312
315
  const meta = entityName ? options.metadata.find(entityName) : undefined;
313
316
  return meta?.properties[propName];
314
317
  }
318
+ /**
319
+ * Converts entity references for composite FK properties into flat arrays
320
+ * of correctly-ordered join column values, before processParams flattens them
321
+ * incorrectly due to shared FK columns.
322
+ */
323
+ static convertCompositeEntityRefs(where, meta) {
324
+ if (!Utils.isPlainObject(where)) {
325
+ return;
326
+ }
327
+ for (const k of Object.keys(where)) {
328
+ if (k in GroupOperator) {
329
+ if (Array.isArray(where[k])) {
330
+ where[k].forEach((sub) => this.convertCompositeEntityRefs(sub, meta));
331
+ }
332
+ continue;
333
+ }
334
+ if (k === '$not') {
335
+ this.convertCompositeEntityRefs(where[k], meta);
336
+ continue;
337
+ }
338
+ const prop = meta.properties[k];
339
+ if (!prop?.joinColumns || prop.joinColumns.length <= 1) {
340
+ continue;
341
+ }
342
+ const w = where[k];
343
+ if (Utils.isEntity(w)) {
344
+ where[k] = this.extractJoinColumnValues(w, prop);
345
+ }
346
+ else if (Utils.isPlainObject(w)) {
347
+ for (const op of Object.keys(w)) {
348
+ if (Utils.isOperator(op, false) && Array.isArray(w[op])) {
349
+ w[op] = w[op].map((item) => Utils.isEntity(item) ? this.extractJoinColumnValues(item, prop) : item);
350
+ }
351
+ }
352
+ }
353
+ }
354
+ }
355
+ /**
356
+ * Extracts values for a FK's join columns from an entity by traversing the FK chain.
357
+ * Handles shared FK columns (e.g., tenant_id referenced by multiple FKs) correctly.
358
+ */
359
+ static extractJoinColumnValues(entity, prop) {
360
+ return prop.referencedColumnNames.map(refCol => {
361
+ return this.extractColumnValue(entity, prop.targetMeta, refCol);
362
+ });
363
+ }
364
+ /**
365
+ * Extracts the value for a specific column from an entity by finding which PK property
366
+ * owns that column and recursively traversing FK references.
367
+ */
368
+ static extractColumnValue(entity, meta, columnName) {
369
+ for (const pk of meta.primaryKeys) {
370
+ const pkProp = meta.properties[pk];
371
+ const colIdx = pkProp.fieldNames.indexOf(columnName);
372
+ if (colIdx !== -1) {
373
+ const value = entity[pk];
374
+ if (pkProp.targetMeta && Utils.isEntity(value, true)) {
375
+ const refCol = pkProp.referencedColumnNames[colIdx];
376
+ return this.extractColumnValue(value, pkProp.targetMeta, refCol);
377
+ }
378
+ return value;
379
+ }
380
+ }
381
+ return null;
382
+ }
315
383
  /**
316
384
  * Merges multiple orderBy sources with key-level deduplication (first-seen key wins).
317
385
  * RawQueryFragment symbol keys are never deduped (each is unique).
package/utils/Utils.js CHANGED
@@ -123,7 +123,7 @@ export function parseJsonSafe(value) {
123
123
  }
124
124
  export class Utils {
125
125
  static PK_SEPARATOR = '~~~';
126
- static #ORM_VERSION = '7.0.0-dev.305';
126
+ static #ORM_VERSION = '7.0.0-dev.306';
127
127
  /**
128
128
  * Checks if the argument is instance of `Object`. Returns false for arrays.
129
129
  */