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

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.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  import path from "path";
2
2
  import fse from "fs-extra";
3
3
  import createDebug from "debug";
4
- import _, { isNil, castArray, prop, omit, isInteger, snakeCase, partition, sumBy, cloneDeep, toString, toNumber, isString as isString$1, padCharsEnd, isArray, keys, isPlainObject, isFinite, groupBy, pipe, mapValues, map, isEmpty, maxBy, pick, has, uniqBy, isNull, differenceWith, isEqual, compact, difference, isObject, isNumber as isNumber$1, isUndefined, uniqWith } from "lodash/fp";
4
+ import _, { isNil, castArray, prop, omit, isInteger, snakeCase, partition, sumBy, cloneDeep, toString, toNumber, isString as isString$1, padCharsEnd, isArray, isPlainObject, isFinite, groupBy, pipe, mapValues, map, isEmpty, maxBy, pick, has, uniqBy, isNull, differenceWith, isEqual, compact, difference, isObject, isNumber as isNumber$1, isUndefined, uniqWith } from "lodash/fp";
5
5
  import crypto from "crypto";
6
6
  import crypto$1 from "node:crypto";
7
7
  import * as dateFns from "date-fns";
8
- import { isOperatorOfType } from "@strapi/utils";
8
+ import { isOperatorOfType, isOperator } from "@strapi/utils";
9
9
  import KnexBuilder from "knex/lib/query/querybuilder";
10
10
  import KnexRaw from "knex/lib/raw";
11
11
  import { Readable } from "stream";
@@ -2266,13 +2266,9 @@ const createManyToMany = (attributeName, attribute, meta, metadata) => {
2266
2266
  const createMorphToOne = (attributeName, attribute) => {
2267
2267
  const idColumnName = identifiers.getJoinColumnAttributeIdName("target");
2268
2268
  const typeColumnName = identifiers.getMorphColumnTypeName("target");
2269
- if ("morphColumn" in attribute && attribute.morphColumn) {
2270
- return;
2271
- }
2272
2269
  Object.assign(attribute, {
2273
2270
  owner: true,
2274
- morphColumn: {
2275
- // TODO: add referenced column
2271
+ morphColumn: attribute.morphColumn ?? {
2276
2272
  typeColumn: {
2277
2273
  name: typeColumnName
2278
2274
  },
@@ -3034,11 +3030,54 @@ const createPivotJoin = (ctx, { alias, refAlias, joinTable, targetMeta }) => {
3034
3030
  return subAlias;
3035
3031
  };
3036
3032
  const createJoin = (ctx, { alias, refAlias, attributeName, attribute }) => {
3037
- const { db, qb } = ctx;
3033
+ const { db, qb, uid } = ctx;
3038
3034
  if (attribute.type !== "relation") {
3039
3035
  throw new Error(`Cannot join on non relational field ${attributeName}`);
3040
3036
  }
3041
3037
  const targetMeta = db.metadata.get(attribute.target);
3038
+ if (["morphOne", "morphMany"].includes(attribute.relation)) {
3039
+ const targetAttribute = targetMeta.attributes[attribute.morphBy];
3040
+ const { joinTable: joinTable2, morphColumn } = targetAttribute;
3041
+ if (morphColumn) {
3042
+ const subAlias = refAlias || qb.getAlias();
3043
+ qb.join({
3044
+ alias: subAlias,
3045
+ referencedTable: targetMeta.tableName,
3046
+ referencedColumn: morphColumn.idColumn.name,
3047
+ rootColumn: morphColumn.idColumn.referencedColumn,
3048
+ rootTable: alias,
3049
+ on: {
3050
+ [morphColumn.typeColumn.name]: uid,
3051
+ ...morphColumn.on
3052
+ }
3053
+ });
3054
+ return subAlias;
3055
+ }
3056
+ if (joinTable2) {
3057
+ const joinAlias = qb.getAlias();
3058
+ qb.join({
3059
+ alias: joinAlias,
3060
+ referencedTable: joinTable2.name,
3061
+ referencedColumn: joinTable2.morphColumn.idColumn.name,
3062
+ rootColumn: joinTable2.morphColumn.idColumn.referencedColumn,
3063
+ rootTable: alias,
3064
+ on: {
3065
+ [joinTable2.morphColumn.typeColumn.name]: uid,
3066
+ field: attributeName
3067
+ }
3068
+ });
3069
+ const subAlias = refAlias || qb.getAlias();
3070
+ qb.join({
3071
+ alias: subAlias,
3072
+ referencedTable: targetMeta.tableName,
3073
+ referencedColumn: joinTable2.joinColumn.referencedColumn,
3074
+ rootColumn: joinTable2.joinColumn.name,
3075
+ rootTable: joinAlias
3076
+ });
3077
+ return subAlias;
3078
+ }
3079
+ return alias;
3080
+ }
3042
3081
  const { joinColumn } = attribute;
3043
3082
  if (joinColumn) {
3044
3083
  const subAlias = refAlias || qb.getAlias();
@@ -3697,6 +3736,28 @@ const processNested = (where, ctx) => {
3697
3736
  }
3698
3737
  return processWhere(where, ctx);
3699
3738
  };
3739
+ const processRelationWhere = (where, ctx) => {
3740
+ const { qb, alias } = ctx;
3741
+ const idAlias = qb.aliasColumn("id", alias);
3742
+ if (!isRecord$1(where)) {
3743
+ return { [idAlias]: where };
3744
+ }
3745
+ const keys = Object.keys(where);
3746
+ const operatorKeys = keys.filter((key) => isOperator(key));
3747
+ if (operatorKeys.length > 0 && operatorKeys.length !== keys.length) {
3748
+ throw new Error(`Operator and non-operator keys cannot be mixed in a relation where clause`);
3749
+ }
3750
+ if (operatorKeys.length > 1) {
3751
+ throw new Error(
3752
+ `Only one operator key is allowed in a relation where clause, but found: ${operatorKeys}`
3753
+ );
3754
+ }
3755
+ if (operatorKeys.length === 1) {
3756
+ const operator = operatorKeys[0];
3757
+ return { [idAlias]: { [operator]: processNested(where[operator], ctx) } };
3758
+ }
3759
+ return processWhere(where, ctx);
3760
+ };
3700
3761
  function processWhere(where, ctx) {
3701
3762
  if (!isArray(where) && !isRecord$1(where)) {
3702
3763
  throw new Error("Where must be an array or an object");
@@ -3709,7 +3770,10 @@ function processWhere(where, ctx) {
3709
3770
  const filters = {};
3710
3771
  for (const key of Object.keys(where)) {
3711
3772
  const value = where[key];
3712
- if (isOperatorOfType("group", key) && Array.isArray(value)) {
3773
+ if (isOperatorOfType("group", key)) {
3774
+ if (!Array.isArray(value)) {
3775
+ throw new Error(`Operator ${key} must be an array`);
3776
+ }
3713
3777
  filters[key] = value.map((sub) => processNested(sub, ctx));
3714
3778
  continue;
3715
3779
  }
@@ -3733,15 +3797,12 @@ function processWhere(where, ctx) {
3733
3797
  attributeName: key,
3734
3798
  attribute
3735
3799
  });
3736
- let nestedWhere = processNested(value, {
3800
+ const nestedWhere = processRelationWhere(value, {
3737
3801
  db,
3738
3802
  qb,
3739
3803
  alias: subAlias,
3740
3804
  uid: attribute.target
3741
3805
  });
3742
- if (!isRecord$1(nestedWhere) || isOperatorOfType("where", keys(nestedWhere)[0])) {
3743
- nestedWhere = { [qb.aliasColumn("id", subAlias)]: nestedWhere };
3744
- }
3745
3806
  Object.assign(filters, nestedWhere);
3746
3807
  continue;
3747
3808
  }
@@ -3894,8 +3955,8 @@ const applyWhereToColumn = (qb, column, columnWhere) => {
3894
3955
  }
3895
3956
  return qb.where(column, columnWhere);
3896
3957
  }
3897
- const keys2 = Object.keys(columnWhere);
3898
- keys2.forEach((operator) => {
3958
+ const keys = Object.keys(columnWhere);
3959
+ keys.forEach((operator) => {
3899
3960
  const value = columnWhere[operator];
3900
3961
  applyOperator(qb, column, operator, value);
3901
3962
  });