@strapi/database 5.0.0-beta.2 → 5.0.0-beta.3

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
@@ -2298,13 +2298,9 @@ const createManyToMany = (attributeName, attribute, meta, metadata) => {
2298
2298
  const createMorphToOne = (attributeName, attribute) => {
2299
2299
  const idColumnName = identifiers.getJoinColumnAttributeIdName("target");
2300
2300
  const typeColumnName = identifiers.getMorphColumnTypeName("target");
2301
- if ("morphColumn" in attribute && attribute.morphColumn) {
2302
- return;
2303
- }
2304
2301
  Object.assign(attribute, {
2305
2302
  owner: true,
2306
- morphColumn: {
2307
- // TODO: add referenced column
2303
+ morphColumn: attribute.morphColumn ?? {
2308
2304
  typeColumn: {
2309
2305
  name: typeColumnName
2310
2306
  },
@@ -3066,11 +3062,54 @@ const createPivotJoin = (ctx, { alias, refAlias, joinTable, targetMeta }) => {
3066
3062
  return subAlias;
3067
3063
  };
3068
3064
  const createJoin = (ctx, { alias, refAlias, attributeName, attribute }) => {
3069
- const { db, qb } = ctx;
3065
+ const { db, qb, uid } = ctx;
3070
3066
  if (attribute.type !== "relation") {
3071
3067
  throw new Error(`Cannot join on non relational field ${attributeName}`);
3072
3068
  }
3073
3069
  const targetMeta = db.metadata.get(attribute.target);
3070
+ if (["morphOne", "morphMany"].includes(attribute.relation)) {
3071
+ const targetAttribute = targetMeta.attributes[attribute.morphBy];
3072
+ const { joinTable: joinTable2, morphColumn } = targetAttribute;
3073
+ if (morphColumn) {
3074
+ const subAlias = refAlias || qb.getAlias();
3075
+ qb.join({
3076
+ alias: subAlias,
3077
+ referencedTable: targetMeta.tableName,
3078
+ referencedColumn: morphColumn.idColumn.name,
3079
+ rootColumn: morphColumn.idColumn.referencedColumn,
3080
+ rootTable: alias,
3081
+ on: {
3082
+ [morphColumn.typeColumn.name]: uid,
3083
+ ...morphColumn.on
3084
+ }
3085
+ });
3086
+ return subAlias;
3087
+ }
3088
+ if (joinTable2) {
3089
+ const joinAlias = qb.getAlias();
3090
+ qb.join({
3091
+ alias: joinAlias,
3092
+ referencedTable: joinTable2.name,
3093
+ referencedColumn: joinTable2.morphColumn.idColumn.name,
3094
+ rootColumn: joinTable2.morphColumn.idColumn.referencedColumn,
3095
+ rootTable: alias,
3096
+ on: {
3097
+ [joinTable2.morphColumn.typeColumn.name]: uid,
3098
+ field: attributeName
3099
+ }
3100
+ });
3101
+ const subAlias = refAlias || qb.getAlias();
3102
+ qb.join({
3103
+ alias: subAlias,
3104
+ referencedTable: targetMeta.tableName,
3105
+ referencedColumn: joinTable2.joinColumn.referencedColumn,
3106
+ rootColumn: joinTable2.joinColumn.name,
3107
+ rootTable: joinAlias
3108
+ });
3109
+ return subAlias;
3110
+ }
3111
+ return alias;
3112
+ }
3074
3113
  const { joinColumn } = attribute;
3075
3114
  if (joinColumn) {
3076
3115
  const subAlias = refAlias || qb.getAlias();
@@ -3729,6 +3768,28 @@ const processNested = (where, ctx) => {
3729
3768
  }
3730
3769
  return processWhere(where, ctx);
3731
3770
  };
3771
+ const processRelationWhere = (where, ctx) => {
3772
+ const { qb, alias } = ctx;
3773
+ const idAlias = qb.aliasColumn("id", alias);
3774
+ if (!isRecord$1(where)) {
3775
+ return { [idAlias]: where };
3776
+ }
3777
+ const keys = Object.keys(where);
3778
+ const operatorKeys = keys.filter((key) => utils.isOperator(key));
3779
+ if (operatorKeys.length > 0 && operatorKeys.length !== keys.length) {
3780
+ throw new Error(`Operator and non-operator keys cannot be mixed in a relation where clause`);
3781
+ }
3782
+ if (operatorKeys.length > 1) {
3783
+ throw new Error(
3784
+ `Only one operator key is allowed in a relation where clause, but found: ${operatorKeys}`
3785
+ );
3786
+ }
3787
+ if (operatorKeys.length === 1) {
3788
+ const operator = operatorKeys[0];
3789
+ return { [idAlias]: { [operator]: processNested(where[operator], ctx) } };
3790
+ }
3791
+ return processWhere(where, ctx);
3792
+ };
3732
3793
  function processWhere(where, ctx) {
3733
3794
  if (!_.isArray(where) && !isRecord$1(where)) {
3734
3795
  throw new Error("Where must be an array or an object");
@@ -3741,7 +3802,10 @@ function processWhere(where, ctx) {
3741
3802
  const filters = {};
3742
3803
  for (const key of Object.keys(where)) {
3743
3804
  const value = where[key];
3744
- if (utils.isOperatorOfType("group", key) && Array.isArray(value)) {
3805
+ if (utils.isOperatorOfType("group", key)) {
3806
+ if (!Array.isArray(value)) {
3807
+ throw new Error(`Operator ${key} must be an array`);
3808
+ }
3745
3809
  filters[key] = value.map((sub) => processNested(sub, ctx));
3746
3810
  continue;
3747
3811
  }
@@ -3765,15 +3829,12 @@ function processWhere(where, ctx) {
3765
3829
  attributeName: key,
3766
3830
  attribute
3767
3831
  });
3768
- let nestedWhere = processNested(value, {
3832
+ const nestedWhere = processRelationWhere(value, {
3769
3833
  db,
3770
3834
  qb,
3771
3835
  alias: subAlias,
3772
3836
  uid: attribute.target
3773
3837
  });
3774
- if (!isRecord$1(nestedWhere) || utils.isOperatorOfType("where", _.keys(nestedWhere)[0])) {
3775
- nestedWhere = { [qb.aliasColumn("id", subAlias)]: nestedWhere };
3776
- }
3777
3838
  Object.assign(filters, nestedWhere);
3778
3839
  continue;
3779
3840
  }
@@ -3926,8 +3987,8 @@ const applyWhereToColumn = (qb, column, columnWhere) => {
3926
3987
  }
3927
3988
  return qb.where(column, columnWhere);
3928
3989
  }
3929
- const keys2 = Object.keys(columnWhere);
3930
- keys2.forEach((operator) => {
3990
+ const keys = Object.keys(columnWhere);
3991
+ keys.forEach((operator) => {
3931
3992
  const value = columnWhere[operator];
3932
3993
  applyOperator(qb, column, operator, value);
3933
3994
  });