@strapi/database 4.22.1 → 4.23.1-alpha.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 CHANGED
@@ -1954,12 +1954,11 @@ const createManyToMany = (attributeName, attribute, meta, metadata) => {
1954
1954
  }
1955
1955
  };
1956
1956
  const createMorphToOne = (attributeName, attribute) => {
1957
- const idColumnName = "target_id";
1958
- const typeColumnName = "target_type";
1957
+ const idColumnName = `target_id`;
1958
+ const typeColumnName = `target_type`;
1959
1959
  Object.assign(attribute, {
1960
1960
  owner: true,
1961
- morphColumn: {
1962
- // TODO: add referenced column
1961
+ morphColumn: attribute.morphColumn ?? {
1963
1962
  typeColumn: {
1964
1963
  name: typeColumnName
1965
1964
  },
@@ -2831,11 +2830,54 @@ const createPivotJoin = (ctx, { alias, refAlias, joinTable, targetMeta }) => {
2831
2830
  return subAlias;
2832
2831
  };
2833
2832
  const createJoin = (ctx, { alias, refAlias, attributeName, attribute }) => {
2834
- const { db, qb } = ctx;
2833
+ const { db, qb, uid } = ctx;
2835
2834
  if (attribute.type !== "relation") {
2836
2835
  throw new Error(`Cannot join on non relational field ${attributeName}`);
2837
2836
  }
2838
2837
  const targetMeta = db.metadata.get(attribute.target);
2838
+ if (["morphOne", "morphMany"].includes(attribute.relation)) {
2839
+ const targetAttribute = targetMeta.attributes[attribute.morphBy];
2840
+ const { joinTable: joinTable2, morphColumn } = targetAttribute;
2841
+ if (morphColumn) {
2842
+ const subAlias = refAlias || qb.getAlias();
2843
+ qb.join({
2844
+ alias: subAlias,
2845
+ referencedTable: targetMeta.tableName,
2846
+ referencedColumn: morphColumn.idColumn.name,
2847
+ rootColumn: morphColumn.idColumn.referencedColumn,
2848
+ rootTable: alias,
2849
+ on: {
2850
+ [morphColumn.typeColumn.name]: uid,
2851
+ ...morphColumn.on
2852
+ }
2853
+ });
2854
+ return subAlias;
2855
+ }
2856
+ if (joinTable2) {
2857
+ const joinAlias = qb.getAlias();
2858
+ qb.join({
2859
+ alias: joinAlias,
2860
+ referencedTable: joinTable2.name,
2861
+ referencedColumn: joinTable2.morphColumn.idColumn.name,
2862
+ rootColumn: joinTable2.morphColumn.idColumn.referencedColumn,
2863
+ rootTable: alias,
2864
+ on: {
2865
+ [joinTable2.morphColumn.typeColumn.name]: uid,
2866
+ field: attributeName
2867
+ }
2868
+ });
2869
+ const subAlias = refAlias || qb.getAlias();
2870
+ qb.join({
2871
+ alias: subAlias,
2872
+ referencedTable: targetMeta.tableName,
2873
+ referencedColumn: joinTable2.joinColumn.referencedColumn,
2874
+ rootColumn: joinTable2.joinColumn.name,
2875
+ rootTable: joinAlias
2876
+ });
2877
+ return subAlias;
2878
+ }
2879
+ return alias;
2880
+ }
2839
2881
  const { joinColumn } = attribute;
2840
2882
  if (joinColumn) {
2841
2883
  const subAlias = refAlias || qb.getAlias();
@@ -3485,6 +3527,28 @@ const processNested = (where, ctx) => {
3485
3527
  }
3486
3528
  return processWhere(where, ctx);
3487
3529
  };
3530
+ const processRelationWhere = (where, ctx) => {
3531
+ const { qb, alias } = ctx;
3532
+ const idAlias = qb.aliasColumn("id", alias);
3533
+ if (!isRecord$1(where)) {
3534
+ return { [idAlias]: where };
3535
+ }
3536
+ const keys = Object.keys(where);
3537
+ const operatorKeys = keys.filter((key) => utils.isOperator(key));
3538
+ if (operatorKeys.length > 0 && operatorKeys.length !== keys.length) {
3539
+ throw new Error(`Operator and non-operator keys cannot be mixed in a relation where clause`);
3540
+ }
3541
+ if (operatorKeys.length > 1) {
3542
+ throw new Error(
3543
+ `Only one operator key is allowed in a relation where clause, but found: ${operatorKeys}`
3544
+ );
3545
+ }
3546
+ if (operatorKeys.length === 1) {
3547
+ const operator = operatorKeys[0];
3548
+ return { [idAlias]: { [operator]: processNested(where[operator], ctx) } };
3549
+ }
3550
+ return processWhere(where, ctx);
3551
+ };
3488
3552
  function processWhere(where, ctx) {
3489
3553
  if (!_.isArray(where) && !isRecord$1(where)) {
3490
3554
  throw new Error("Where must be an array or an object");
@@ -3497,7 +3561,10 @@ function processWhere(where, ctx) {
3497
3561
  const filters = {};
3498
3562
  for (const key of Object.keys(where)) {
3499
3563
  const value = where[key];
3500
- if (utils.isOperatorOfType("group", key) && Array.isArray(value)) {
3564
+ if (utils.isOperatorOfType("group", key)) {
3565
+ if (!Array.isArray(value)) {
3566
+ throw new Error(`Operator ${key} must be an array`);
3567
+ }
3501
3568
  filters[key] = value.map((sub) => processNested(sub, ctx));
3502
3569
  continue;
3503
3570
  }
@@ -3521,15 +3588,12 @@ function processWhere(where, ctx) {
3521
3588
  attributeName: key,
3522
3589
  attribute
3523
3590
  });
3524
- let nestedWhere = processNested(value, {
3591
+ const nestedWhere = processRelationWhere(value, {
3525
3592
  db,
3526
3593
  qb,
3527
3594
  alias: subAlias,
3528
3595
  uid: attribute.target
3529
3596
  });
3530
- if (!isRecord$1(nestedWhere) || utils.isOperatorOfType("where", _.keys(nestedWhere)[0])) {
3531
- nestedWhere = { [qb.aliasColumn("id", subAlias)]: nestedWhere };
3532
- }
3533
3597
  Object.assign(filters, nestedWhere);
3534
3598
  continue;
3535
3599
  }
@@ -3682,8 +3746,8 @@ const applyWhereToColumn = (qb, column, columnWhere) => {
3682
3746
  }
3683
3747
  return qb.where(column, columnWhere);
3684
3748
  }
3685
- const keys2 = Object.keys(columnWhere);
3686
- keys2.forEach((operator) => {
3749
+ const keys = Object.keys(columnWhere);
3750
+ keys.forEach((operator) => {
3687
3751
  const value = columnWhere[operator];
3688
3752
  applyOperator(qb, column, operator, value);
3689
3753
  });