@strapi/database 4.22.0 → 4.23.0
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/dist/index.js +76 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +78 -14
- package/dist/index.mjs.map +1 -1
- package/dist/metadata/relations.d.ts.map +1 -1
- package/dist/query/helpers/join.d.ts.map +1 -1
- package/dist/query/helpers/where.d.ts +1 -0
- package/dist/query/helpers/where.d.ts.map +1 -1
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -2,9 +2,9 @@ import semver from "semver";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import fse from "fs-extra";
|
|
4
4
|
import createDebug from "debug";
|
|
5
|
-
import _, { isNil, castArray, prop, omit, toString, toNumber, isString as isString$1, padCharsEnd, isArray,
|
|
5
|
+
import _, { isNil, castArray, prop, omit, toString, toNumber, isString as isString$1, padCharsEnd, isArray, isPlainObject, isFinite, groupBy, pipe, mapValues, map, isEmpty, maxBy, pick, flow, mergeWith, has, uniqBy, isNull, differenceWith, isEqual, compact, difference, isObject, isInteger, isNumber as isNumber$1, isUndefined, uniqWith } from "lodash/fp";
|
|
6
6
|
import crypto, { randomBytes } from "crypto";
|
|
7
|
-
import { isOperatorOfType, mapAsync } from "@strapi/utils";
|
|
7
|
+
import { isOperatorOfType, isOperator, mapAsync } from "@strapi/utils";
|
|
8
8
|
import * as dateFns from "date-fns";
|
|
9
9
|
import KnexBuilder from "knex/lib/query/querybuilder";
|
|
10
10
|
import KnexRaw from "knex/lib/raw";
|
|
@@ -1920,12 +1920,11 @@ const createManyToMany = (attributeName, attribute, meta, metadata) => {
|
|
|
1920
1920
|
}
|
|
1921
1921
|
};
|
|
1922
1922
|
const createMorphToOne = (attributeName, attribute) => {
|
|
1923
|
-
const idColumnName =
|
|
1924
|
-
const typeColumnName =
|
|
1923
|
+
const idColumnName = `target_id`;
|
|
1924
|
+
const typeColumnName = `target_type`;
|
|
1925
1925
|
Object.assign(attribute, {
|
|
1926
1926
|
owner: true,
|
|
1927
|
-
morphColumn: {
|
|
1928
|
-
// TODO: add referenced column
|
|
1927
|
+
morphColumn: attribute.morphColumn ?? {
|
|
1929
1928
|
typeColumn: {
|
|
1930
1929
|
name: typeColumnName
|
|
1931
1930
|
},
|
|
@@ -2797,11 +2796,54 @@ const createPivotJoin = (ctx, { alias, refAlias, joinTable, targetMeta }) => {
|
|
|
2797
2796
|
return subAlias;
|
|
2798
2797
|
};
|
|
2799
2798
|
const createJoin = (ctx, { alias, refAlias, attributeName, attribute }) => {
|
|
2800
|
-
const { db, qb } = ctx;
|
|
2799
|
+
const { db, qb, uid } = ctx;
|
|
2801
2800
|
if (attribute.type !== "relation") {
|
|
2802
2801
|
throw new Error(`Cannot join on non relational field ${attributeName}`);
|
|
2803
2802
|
}
|
|
2804
2803
|
const targetMeta = db.metadata.get(attribute.target);
|
|
2804
|
+
if (["morphOne", "morphMany"].includes(attribute.relation)) {
|
|
2805
|
+
const targetAttribute = targetMeta.attributes[attribute.morphBy];
|
|
2806
|
+
const { joinTable: joinTable2, morphColumn } = targetAttribute;
|
|
2807
|
+
if (morphColumn) {
|
|
2808
|
+
const subAlias = refAlias || qb.getAlias();
|
|
2809
|
+
qb.join({
|
|
2810
|
+
alias: subAlias,
|
|
2811
|
+
referencedTable: targetMeta.tableName,
|
|
2812
|
+
referencedColumn: morphColumn.idColumn.name,
|
|
2813
|
+
rootColumn: morphColumn.idColumn.referencedColumn,
|
|
2814
|
+
rootTable: alias,
|
|
2815
|
+
on: {
|
|
2816
|
+
[morphColumn.typeColumn.name]: uid,
|
|
2817
|
+
...morphColumn.on
|
|
2818
|
+
}
|
|
2819
|
+
});
|
|
2820
|
+
return subAlias;
|
|
2821
|
+
}
|
|
2822
|
+
if (joinTable2) {
|
|
2823
|
+
const joinAlias = qb.getAlias();
|
|
2824
|
+
qb.join({
|
|
2825
|
+
alias: joinAlias,
|
|
2826
|
+
referencedTable: joinTable2.name,
|
|
2827
|
+
referencedColumn: joinTable2.morphColumn.idColumn.name,
|
|
2828
|
+
rootColumn: joinTable2.morphColumn.idColumn.referencedColumn,
|
|
2829
|
+
rootTable: alias,
|
|
2830
|
+
on: {
|
|
2831
|
+
[joinTable2.morphColumn.typeColumn.name]: uid,
|
|
2832
|
+
field: attributeName
|
|
2833
|
+
}
|
|
2834
|
+
});
|
|
2835
|
+
const subAlias = refAlias || qb.getAlias();
|
|
2836
|
+
qb.join({
|
|
2837
|
+
alias: subAlias,
|
|
2838
|
+
referencedTable: targetMeta.tableName,
|
|
2839
|
+
referencedColumn: joinTable2.joinColumn.referencedColumn,
|
|
2840
|
+
rootColumn: joinTable2.joinColumn.name,
|
|
2841
|
+
rootTable: joinAlias
|
|
2842
|
+
});
|
|
2843
|
+
return subAlias;
|
|
2844
|
+
}
|
|
2845
|
+
return alias;
|
|
2846
|
+
}
|
|
2805
2847
|
const { joinColumn } = attribute;
|
|
2806
2848
|
if (joinColumn) {
|
|
2807
2849
|
const subAlias = refAlias || qb.getAlias();
|
|
@@ -3451,6 +3493,28 @@ const processNested = (where, ctx) => {
|
|
|
3451
3493
|
}
|
|
3452
3494
|
return processWhere(where, ctx);
|
|
3453
3495
|
};
|
|
3496
|
+
const processRelationWhere = (where, ctx) => {
|
|
3497
|
+
const { qb, alias } = ctx;
|
|
3498
|
+
const idAlias = qb.aliasColumn("id", alias);
|
|
3499
|
+
if (!isRecord$1(where)) {
|
|
3500
|
+
return { [idAlias]: where };
|
|
3501
|
+
}
|
|
3502
|
+
const keys = Object.keys(where);
|
|
3503
|
+
const operatorKeys = keys.filter((key) => isOperator(key));
|
|
3504
|
+
if (operatorKeys.length > 0 && operatorKeys.length !== keys.length) {
|
|
3505
|
+
throw new Error(`Operator and non-operator keys cannot be mixed in a relation where clause`);
|
|
3506
|
+
}
|
|
3507
|
+
if (operatorKeys.length > 1) {
|
|
3508
|
+
throw new Error(
|
|
3509
|
+
`Only one operator key is allowed in a relation where clause, but found: ${operatorKeys}`
|
|
3510
|
+
);
|
|
3511
|
+
}
|
|
3512
|
+
if (operatorKeys.length === 1) {
|
|
3513
|
+
const operator = operatorKeys[0];
|
|
3514
|
+
return { [idAlias]: { [operator]: processNested(where[operator], ctx) } };
|
|
3515
|
+
}
|
|
3516
|
+
return processWhere(where, ctx);
|
|
3517
|
+
};
|
|
3454
3518
|
function processWhere(where, ctx) {
|
|
3455
3519
|
if (!isArray(where) && !isRecord$1(where)) {
|
|
3456
3520
|
throw new Error("Where must be an array or an object");
|
|
@@ -3463,7 +3527,10 @@ function processWhere(where, ctx) {
|
|
|
3463
3527
|
const filters = {};
|
|
3464
3528
|
for (const key of Object.keys(where)) {
|
|
3465
3529
|
const value = where[key];
|
|
3466
|
-
if (isOperatorOfType("group", key)
|
|
3530
|
+
if (isOperatorOfType("group", key)) {
|
|
3531
|
+
if (!Array.isArray(value)) {
|
|
3532
|
+
throw new Error(`Operator ${key} must be an array`);
|
|
3533
|
+
}
|
|
3467
3534
|
filters[key] = value.map((sub) => processNested(sub, ctx));
|
|
3468
3535
|
continue;
|
|
3469
3536
|
}
|
|
@@ -3487,15 +3554,12 @@ function processWhere(where, ctx) {
|
|
|
3487
3554
|
attributeName: key,
|
|
3488
3555
|
attribute
|
|
3489
3556
|
});
|
|
3490
|
-
|
|
3557
|
+
const nestedWhere = processRelationWhere(value, {
|
|
3491
3558
|
db,
|
|
3492
3559
|
qb,
|
|
3493
3560
|
alias: subAlias,
|
|
3494
3561
|
uid: attribute.target
|
|
3495
3562
|
});
|
|
3496
|
-
if (!isRecord$1(nestedWhere) || isOperatorOfType("where", keys(nestedWhere)[0])) {
|
|
3497
|
-
nestedWhere = { [qb.aliasColumn("id", subAlias)]: nestedWhere };
|
|
3498
|
-
}
|
|
3499
3563
|
Object.assign(filters, nestedWhere);
|
|
3500
3564
|
continue;
|
|
3501
3565
|
}
|
|
@@ -3648,8 +3712,8 @@ const applyWhereToColumn = (qb, column, columnWhere) => {
|
|
|
3648
3712
|
}
|
|
3649
3713
|
return qb.where(column, columnWhere);
|
|
3650
3714
|
}
|
|
3651
|
-
const
|
|
3652
|
-
|
|
3715
|
+
const keys = Object.keys(columnWhere);
|
|
3716
|
+
keys.forEach((operator) => {
|
|
3653
3717
|
const value = columnWhere[operator];
|
|
3654
3718
|
applyOperator(qb, column, operator, value);
|
|
3655
3719
|
});
|