@mikro-orm/core 7.3.0-dev.4 → 7.3.0-dev.5
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 +1 -1
- package/utils/QueryHelper.d.ts +8 -0
- package/utils/QueryHelper.js +40 -5
- package/utils/Utils.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
|
-
"version": "7.3.0-dev.
|
|
3
|
+
"version": "7.3.0-dev.5",
|
|
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/utils/QueryHelper.d.ts
CHANGED
|
@@ -46,6 +46,8 @@ export declare class QueryHelper {
|
|
|
46
46
|
static processWhere<T extends object>(options: ProcessWhereOptions<T>): FilterQuery<T>;
|
|
47
47
|
/** @internal Splits a polymorphic target key like `imageable[Article]` into the property and target class names. */
|
|
48
48
|
static splitPolymorphicKey(key: string): [string, string?];
|
|
49
|
+
/** @internal Resolves the targets of a polymorphic target key like `imageable[Article]` or `imageable[Product,Article]`. */
|
|
50
|
+
static findTargetMetas(prop: EntityProperty | null | undefined, key: string): EntityMetadata[];
|
|
49
51
|
/** @internal Resolves the target entity of a condition key, including polymorphic target keys like `imageable[Article]`. */
|
|
50
52
|
static findTargetMeta(prop: EntityProperty | null | undefined, key: string): EntityMetadata | undefined;
|
|
51
53
|
/**
|
|
@@ -54,6 +56,12 @@ export declare class QueryHelper {
|
|
|
54
56
|
* when more targets match. The first target alone keeps the regular relation join.
|
|
55
57
|
*/
|
|
56
58
|
private static splitPolymorphicConditions;
|
|
59
|
+
/**
|
|
60
|
+
* Routes ordering by properties of polymorphic to-one relations to the targets that define them, e.g.
|
|
61
|
+
* `{ imageable: { name: 'asc' } }` becomes `{ 'imageable[Product,Article]': { name: 'asc' } }`, ordered by
|
|
62
|
+
* the first non-null value. Nested relations and formulas are ordered via the first target defining them.
|
|
63
|
+
*/
|
|
64
|
+
private static splitPolymorphicOrderBy;
|
|
57
65
|
/** Property names used in a condition, including those nested in group operators. */
|
|
58
66
|
private static collectConditionKeys;
|
|
59
67
|
static getActiveFilters<T>(meta: EntityMetadata<T>, options: FilterOptions | undefined, filters: Dictionary<FilterDef>): FilterDef[];
|
package/utils/QueryHelper.js
CHANGED
|
@@ -262,8 +262,10 @@ export class QueryHelper {
|
|
|
262
262
|
if (!Utils.isPlainObject(where)) {
|
|
263
263
|
return where;
|
|
264
264
|
}
|
|
265
|
-
if (meta
|
|
266
|
-
where =
|
|
265
|
+
if (meta) {
|
|
266
|
+
where = (options.type === 'orderBy'
|
|
267
|
+
? QueryHelper.splitPolymorphicOrderBy(meta, where)
|
|
268
|
+
: QueryHelper.splitPolymorphicConditions(meta, where));
|
|
267
269
|
}
|
|
268
270
|
return Utils.getObjectQueryKeys(where).reduce((o, key) => {
|
|
269
271
|
let value = where[key];
|
|
@@ -328,13 +330,18 @@ export class QueryHelper {
|
|
|
328
330
|
}
|
|
329
331
|
/** @internal Splits a polymorphic target key like `imageable[Article]` into the property and target class names. */
|
|
330
332
|
static splitPolymorphicKey(key) {
|
|
331
|
-
const match = /^(\w+)\[(\w+)]$/.exec(key);
|
|
333
|
+
const match = /^(\w+)\[([\w,]+)]$/.exec(key);
|
|
332
334
|
return match ? [match[1], match[2]] : [key];
|
|
333
335
|
}
|
|
336
|
+
/** @internal Resolves the targets of a polymorphic target key like `imageable[Article]` or `imageable[Product,Article]`. */
|
|
337
|
+
static findTargetMetas(prop, key) {
|
|
338
|
+
const [, targetNames] = QueryHelper.splitPolymorphicKey(key);
|
|
339
|
+
const targets = targetNames?.split(',').map(name => prop?.polymorphTargets?.find(t => t.className === name));
|
|
340
|
+
return targets?.every(Boolean) ? targets : [];
|
|
341
|
+
}
|
|
334
342
|
/** @internal Resolves the target entity of a condition key, including polymorphic target keys like `imageable[Article]`. */
|
|
335
343
|
static findTargetMeta(prop, key) {
|
|
336
|
-
|
|
337
|
-
return targetName ? prop?.polymorphTargets?.find(t => t.className === targetName) : prop?.targetMeta;
|
|
344
|
+
return QueryHelper.splitPolymorphicKey(key)[1] ? QueryHelper.findTargetMetas(prop, key)[0] : prop?.targetMeta;
|
|
338
345
|
}
|
|
339
346
|
/**
|
|
340
347
|
* Routes conditions on polymorphic to-one relations to the targets that define all the queried properties,
|
|
@@ -373,6 +380,34 @@ export class QueryHelper {
|
|
|
373
380
|
}
|
|
374
381
|
return ret;
|
|
375
382
|
}
|
|
383
|
+
/**
|
|
384
|
+
* Routes ordering by properties of polymorphic to-one relations to the targets that define them, e.g.
|
|
385
|
+
* `{ imageable: { name: 'asc' } }` becomes `{ 'imageable[Product,Article]': { name: 'asc' } }`, ordered by
|
|
386
|
+
* the first non-null value. Nested relations and formulas are ordered via the first target defining them.
|
|
387
|
+
*/
|
|
388
|
+
static splitPolymorphicOrderBy(meta, orderBy) {
|
|
389
|
+
const ret = {};
|
|
390
|
+
for (const key of Utils.getObjectQueryKeys(orderBy)) {
|
|
391
|
+
const prop = meta.properties[key];
|
|
392
|
+
const value = orderBy[key];
|
|
393
|
+
if (!prop?.polymorphTargets ||
|
|
394
|
+
![ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) ||
|
|
395
|
+
!Utils.isPlainObject(value)) {
|
|
396
|
+
ret[key] = value;
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
for (const field of Utils.getObjectQueryKeys(value)) {
|
|
400
|
+
const found = prop.polymorphTargets.filter(target => field in target.properties);
|
|
401
|
+
const sharedPK = found.length === prop.polymorphTargets.length && found.every(target => target.primaryKeys.includes(field));
|
|
402
|
+
const single = Utils.isPlainObject(value[field]) || found.some(target => target.properties[field].formula);
|
|
403
|
+
const targets = found.length === 0 ? [prop.targetMeta] : single ? [found[0]] : found;
|
|
404
|
+
// shared PKs are ordered by the FK column without a join
|
|
405
|
+
const targetKey = sharedPK ? key : `${key}[${targets.map(target => target.className).join(',')}]`;
|
|
406
|
+
ret[targetKey] = { ...ret[targetKey], [field]: value[field] };
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return ret;
|
|
410
|
+
}
|
|
376
411
|
/** Property names used in a condition, including those nested in group operators. */
|
|
377
412
|
static collectConditionKeys(payload) {
|
|
378
413
|
return Object.keys(payload).flatMap(k => {
|
package/utils/Utils.js
CHANGED
|
@@ -153,7 +153,7 @@ export function parseJsonSafe(value) {
|
|
|
153
153
|
/** Collection of general-purpose utility methods used throughout the ORM. */
|
|
154
154
|
export class Utils {
|
|
155
155
|
static PK_SEPARATOR = '~~~';
|
|
156
|
-
static #ORM_VERSION = '7.3.0-dev.
|
|
156
|
+
static #ORM_VERSION = '7.3.0-dev.5';
|
|
157
157
|
/** Default session variable name backing an RLS filter argument (`current_setting('mikro.<filter>.<arg>')`). */
|
|
158
158
|
static getRlsSettingName(filterName, argName) {
|
|
159
159
|
return `mikro.${filterName}.${argName}`;
|