@strapi/database 5.0.0-beta.13 → 5.0.0-beta.14

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.
@@ -1 +1 @@
1
- {"version":3,"file":"regular-relations.d.ts","sourceRoot":"","sources":["../../src/entity-manager/regular-relations.ts"],"names":[],"mappings":";;;;;AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAYjC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACnC,OAAO,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAS,MAAM,UAAU,CAAC;AAEpD,OAAO,QAAQ,MAAM,CAAC;IACpB,UAAU,IAAI,CAAC;QACb,UAAU,kBAAkB;YAC1B,WAAW,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;SAC3C;KACF;CACF;AA6BD;;GAEG;AACH,QAAA,MAAM,+BAA+B,0DAMlC;IACD,EAAE,EAAE,EAAE,CAAC;IACP,SAAS,EAAE,SAAS,aAAa,CAAC;IAClC,WAAW,EAAE,EAAE,EAAE,CAAC;IAClB,EAAE,EAAE,QAAQ,CAAC;IACb,WAAW,CAAC,EAAE,KAAK,WAAW,CAAC;CAChC,kBA0BA,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,+BAA+B,yDAMlC;IACD,EAAE,EAAE,EAAE,CAAC;IACP,SAAS,EAAE,SAAS,aAAa,CAAC;IAClC,UAAU,EAAE,EAAE,CAAC;IACf,EAAE,EAAE,QAAQ,CAAC;IACb,WAAW,CAAC,EAAE,KAAK,WAAW,CAAC;CAChC,kBAoDA,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,eAAe,gFAOlB;IACD,EAAE,EAAE,EAAE,CAAC;IACP,SAAS,EAAE,SAAS,aAAa,CAAC;IAClC,EAAE,EAAE,QAAQ,CAAC;IACb,iBAAiB,CAAC,EAAE,EAAE,EAAE,CAAC;IACzB,cAAc,CAAC,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC;IAC9B,WAAW,CAAC,EAAE,KAAK,WAAW,CAAC;CAChC,kBAsDA,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,iBAAiB,4DAMpB;IACD,EAAE,CAAC,EAAE,EAAE,CAAC;IACR,SAAS,EAAE,SAAS,aAAa,CAAC;IAClC,EAAE,EAAE,QAAQ,CAAC;IACb,aAAa,CAAC,EAAE,EAAE,EAAE,CAAC;IACrB,WAAW,CAAC,EAAE,KAAK,WAAW,CAAC;CAChC,sCAiIA,CAAC;AAEF,OAAO,EACL,+BAA+B,EAC/B,+BAA+B,EAC/B,eAAe,EACf,iBAAiB,GAClB,CAAC"}
1
+ {"version":3,"file":"regular-relations.d.ts","sourceRoot":"","sources":["../../src/entity-manager/regular-relations.ts"],"names":[],"mappings":";;;;;AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAYjC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACnC,OAAO,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAS,MAAM,UAAU,CAAC;AAEpD,OAAO,QAAQ,MAAM,CAAC;IACpB,UAAU,IAAI,CAAC;QACb,UAAU,kBAAkB;YAC1B,WAAW,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;SAC3C;KACF;CACF;AAiCD;;GAEG;AACH,QAAA,MAAM,+BAA+B,0DAMlC;IACD,EAAE,EAAE,EAAE,CAAC;IACP,SAAS,EAAE,SAAS,aAAa,CAAC;IAClC,WAAW,EAAE,EAAE,EAAE,CAAC;IAClB,EAAE,EAAE,QAAQ,CAAC;IACb,WAAW,CAAC,EAAE,KAAK,WAAW,CAAC;CAChC,kBAsBA,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,+BAA+B,yDAMlC;IACD,EAAE,EAAE,EAAE,CAAC;IACP,SAAS,EAAE,SAAS,aAAa,CAAC;IAClC,UAAU,EAAE,EAAE,CAAC;IACf,EAAE,EAAE,QAAQ,CAAC;IACb,WAAW,CAAC,EAAE,KAAK,WAAW,CAAC;CAChC,kBAkDA,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,eAAe,gFAOlB;IACD,EAAE,EAAE,EAAE,CAAC;IACP,SAAS,EAAE,SAAS,aAAa,CAAC;IAClC,EAAE,EAAE,QAAQ,CAAC;IACb,iBAAiB,CAAC,EAAE,EAAE,EAAE,CAAC;IACzB,cAAc,CAAC,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC;IAC9B,WAAW,CAAC,EAAE,KAAK,WAAW,CAAC;CAChC,kBAsDA,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,iBAAiB,4DAMpB;IACD,EAAE,CAAC,EAAE,EAAE,CAAC;IACR,SAAS,EAAE,SAAS,aAAa,CAAC;IAClC,EAAE,EAAE,QAAQ,CAAC;IACb,aAAa,CAAC,EAAE,EAAE,EAAE,CAAC;IACrB,WAAW,CAAC,EAAE,KAAK,WAAW,CAAC;CAChC,sCAiIA,CAAC;AAEF,OAAO,EACL,+BAA+B,EAC/B,+BAA+B,EAC/B,eAAe,EACf,iBAAiB,GAClB,CAAC"}
package/dist/index.js CHANGED
@@ -7,11 +7,11 @@ const _ = require("lodash/fp");
7
7
  const crypto = require("crypto");
8
8
  const crypto$1 = require("node:crypto");
9
9
  const dateFns = require("date-fns");
10
- const utils = require("@strapi/utils");
10
+ const node_async_hooks = require("node:async_hooks");
11
11
  const KnexBuilder = require("knex/lib/query/querybuilder");
12
12
  const KnexRaw = require("knex/lib/raw");
13
+ const utils = require("@strapi/utils");
13
14
  const stream = require("stream");
14
- const node_async_hooks = require("node:async_hooks");
15
15
  const _$1 = require("lodash");
16
16
  const umzug = require("umzug");
17
17
  const cuid2 = require("@paralleldrive/cuid2");
@@ -2927,6 +2927,68 @@ const createField = (attribute) => {
2927
2927
  }
2928
2928
  throw new Error(`Undefined field for type ${type}`);
2929
2929
  };
2930
+ const storage = new node_async_hooks.AsyncLocalStorage();
2931
+ const transactionCtx = {
2932
+ async run(trx, cb) {
2933
+ const store = storage.getStore();
2934
+ return storage.run(
2935
+ {
2936
+ trx,
2937
+ // Fill with existing callbacks if nesting transactions
2938
+ commitCallbacks: store?.commitCallbacks || [],
2939
+ rollbackCallbacks: store?.rollbackCallbacks || []
2940
+ },
2941
+ cb
2942
+ );
2943
+ },
2944
+ get() {
2945
+ const store = storage.getStore();
2946
+ return store?.trx;
2947
+ },
2948
+ async commit(trx) {
2949
+ const store = storage.getStore();
2950
+ if (store?.trx) {
2951
+ store.trx = null;
2952
+ }
2953
+ await trx.commit();
2954
+ if (!store?.commitCallbacks.length) {
2955
+ return;
2956
+ }
2957
+ store.commitCallbacks.forEach((cb) => cb());
2958
+ store.commitCallbacks = [];
2959
+ },
2960
+ async rollback(trx) {
2961
+ const store = storage.getStore();
2962
+ if (store?.trx) {
2963
+ store.trx = null;
2964
+ }
2965
+ await trx.rollback();
2966
+ if (!store?.rollbackCallbacks.length) {
2967
+ return;
2968
+ }
2969
+ store.rollbackCallbacks.forEach((cb) => cb());
2970
+ store.rollbackCallbacks = [];
2971
+ },
2972
+ onCommit(cb) {
2973
+ const store = storage.getStore();
2974
+ if (store?.commitCallbacks) {
2975
+ store.commitCallbacks.push(cb);
2976
+ }
2977
+ },
2978
+ onRollback(cb) {
2979
+ const store = storage.getStore();
2980
+ if (store?.rollbackCallbacks) {
2981
+ store.rollbackCallbacks.push(cb);
2982
+ }
2983
+ }
2984
+ };
2985
+ function isKnexQuery(value) {
2986
+ return value instanceof KnexBuilder__default.default || value instanceof KnexRaw__default.default;
2987
+ }
2988
+ const addSchema = (db, tableName) => {
2989
+ const schemaName = db.getSchemaName();
2990
+ return schemaName ? `${schemaName}.${tableName}` : tableName;
2991
+ };
2930
2992
  const fromSingleRow = (meta, row) => {
2931
2993
  const { attributes } = meta;
2932
2994
  if (___default.default.isNil(row)) {
@@ -3049,7 +3111,7 @@ const escapeQuery = (query, charsToEscape, escapeChar = "\\") => {
3049
3111
  ""
3050
3112
  );
3051
3113
  };
3052
- const createPivotJoin = (ctx, { alias, refAlias, joinTable, targetMeta }) => {
3114
+ const createPivotJoin = (ctx, { alias: alias2, refAlias, joinTable, targetMeta }) => {
3053
3115
  const { qb } = ctx;
3054
3116
  const joinAlias = qb.getAlias();
3055
3117
  qb.join({
@@ -3057,7 +3119,7 @@ const createPivotJoin = (ctx, { alias, refAlias, joinTable, targetMeta }) => {
3057
3119
  referencedTable: joinTable.name,
3058
3120
  referencedColumn: joinTable.joinColumn.name,
3059
3121
  rootColumn: joinTable.joinColumn.referencedColumn,
3060
- rootTable: alias,
3122
+ rootTable: alias2,
3061
3123
  on: joinTable.on
3062
3124
  });
3063
3125
  const subAlias = refAlias || qb.getAlias();
@@ -3070,7 +3132,7 @@ const createPivotJoin = (ctx, { alias, refAlias, joinTable, targetMeta }) => {
3070
3132
  });
3071
3133
  return subAlias;
3072
3134
  };
3073
- const createJoin = (ctx, { alias, refAlias, attributeName, attribute }) => {
3135
+ const createJoin = (ctx, { alias: alias2, refAlias, attributeName, attribute }) => {
3074
3136
  const { db, qb, uid } = ctx;
3075
3137
  if (attribute.type !== "relation") {
3076
3138
  throw new Error(`Cannot join on non relational field ${attributeName}`);
@@ -3086,7 +3148,7 @@ const createJoin = (ctx, { alias, refAlias, attributeName, attribute }) => {
3086
3148
  referencedTable: targetMeta.tableName,
3087
3149
  referencedColumn: morphColumn.idColumn.name,
3088
3150
  rootColumn: morphColumn.idColumn.referencedColumn,
3089
- rootTable: alias,
3151
+ rootTable: alias2,
3090
3152
  on: {
3091
3153
  [morphColumn.typeColumn.name]: uid,
3092
3154
  ...morphColumn.on
@@ -3101,7 +3163,7 @@ const createJoin = (ctx, { alias, refAlias, attributeName, attribute }) => {
3101
3163
  referencedTable: joinTable2.name,
3102
3164
  referencedColumn: joinTable2.morphColumn.idColumn.name,
3103
3165
  rootColumn: joinTable2.morphColumn.idColumn.referencedColumn,
3104
- rootTable: alias,
3166
+ rootTable: alias2,
3105
3167
  on: {
3106
3168
  [joinTable2.morphColumn.typeColumn.name]: uid,
3107
3169
  field: attributeName
@@ -3117,7 +3179,7 @@ const createJoin = (ctx, { alias, refAlias, attributeName, attribute }) => {
3117
3179
  });
3118
3180
  return subAlias;
3119
3181
  }
3120
- return alias;
3182
+ return alias2;
3121
3183
  }
3122
3184
  const { joinColumn } = attribute;
3123
3185
  if (joinColumn) {
@@ -3127,20 +3189,20 @@ const createJoin = (ctx, { alias, refAlias, attributeName, attribute }) => {
3127
3189
  referencedTable: targetMeta.tableName,
3128
3190
  referencedColumn: joinColumn.referencedColumn,
3129
3191
  rootColumn: joinColumn.name,
3130
- rootTable: alias
3192
+ rootTable: alias2
3131
3193
  });
3132
3194
  return subAlias;
3133
3195
  }
3134
3196
  const { joinTable } = attribute;
3135
3197
  if (joinTable) {
3136
- return createPivotJoin(ctx, { alias, refAlias, joinTable, targetMeta });
3198
+ return createPivotJoin(ctx, { alias: alias2, refAlias, joinTable, targetMeta });
3137
3199
  }
3138
- return alias;
3200
+ return alias2;
3139
3201
  };
3140
3202
  const applyJoin = (qb, join) => {
3141
3203
  const {
3142
3204
  method = "leftJoin",
3143
- alias,
3205
+ alias: alias2,
3144
3206
  referencedTable,
3145
3207
  referencedColumn,
3146
3208
  rootColumn,
@@ -3150,26 +3212,28 @@ const applyJoin = (qb, join) => {
3150
3212
  on,
3151
3213
  orderBy
3152
3214
  } = join;
3153
- qb[method](`${referencedTable} as ${alias}`, (inner) => {
3154
- inner.on(`${rootTable}.${rootColumn}`, `${alias}.${referencedColumn}`);
3215
+ qb[method](`${referencedTable} as ${alias2}`, (inner) => {
3216
+ inner.on(`${rootTable}.${rootColumn}`, `${alias2}.${referencedColumn}`);
3155
3217
  if (on) {
3156
3218
  for (const key of Object.keys(on)) {
3157
- inner.onVal(`${alias}.${key}`, on[key]);
3219
+ inner.onVal(`${alias2}.${key}`, on[key]);
3158
3220
  }
3159
3221
  }
3160
3222
  });
3161
3223
  if (orderBy) {
3162
3224
  Object.keys(orderBy).forEach((column) => {
3163
3225
  const direction = orderBy[column];
3164
- qb.orderBy(`${alias}.${column}`, direction);
3226
+ qb.orderBy(`${alias2}.${column}`, direction);
3165
3227
  });
3166
3228
  }
3167
3229
  };
3168
3230
  const applyJoins = (qb, joins) => {
3169
3231
  return joins.forEach((join) => applyJoin(qb, join));
3170
3232
  };
3233
+ const COL_STRAPI_ROW_NUMBER = "__strapi_row_number";
3234
+ const COL_STRAPI_ORDER_BY_PREFIX = "__strapi_order_by";
3171
3235
  const processOrderBy = (orderBy, ctx) => {
3172
- const { db, uid, qb, alias } = ctx;
3236
+ const { db, uid, qb, alias: alias2 } = ctx;
3173
3237
  const meta = db.metadata.get(uid);
3174
3238
  const { attributes } = meta;
3175
3239
  if (typeof orderBy === "string") {
@@ -3178,7 +3242,7 @@ const processOrderBy = (orderBy, ctx) => {
3178
3242
  throw new Error(`Attribute ${orderBy} not found on model ${uid}`);
3179
3243
  }
3180
3244
  const columnName = toColumnName(meta, orderBy);
3181
- return [{ column: qb.aliasColumn(columnName, alias) }];
3245
+ return [{ column: qb.aliasColumn(columnName, alias2) }];
3182
3246
  }
3183
3247
  if (Array.isArray(orderBy)) {
3184
3248
  return orderBy.flatMap((value) => processOrderBy(value, ctx));
@@ -3192,11 +3256,11 @@ const processOrderBy = (orderBy, ctx) => {
3192
3256
  }
3193
3257
  if (isScalar(attribute.type)) {
3194
3258
  const columnName = toColumnName(meta, key);
3195
- return { column: qb.aliasColumn(columnName, alias), order: direction };
3259
+ return { column: qb.aliasColumn(columnName, alias2), order: direction };
3196
3260
  }
3197
3261
  if (attribute.type === "relation" && "target" in attribute) {
3198
3262
  const subAlias = createJoin(ctx, {
3199
- alias: alias || qb.alias,
3263
+ alias: alias2 || qb.alias,
3200
3264
  attributeName: key,
3201
3265
  attribute
3202
3266
  });
@@ -3212,6 +3276,75 @@ const processOrderBy = (orderBy, ctx) => {
3212
3276
  }
3213
3277
  throw new Error("Invalid orderBy syntax");
3214
3278
  };
3279
+ const getStrapiOrderColumnAlias = (column) => {
3280
+ const trimmedColumnName = column.replaceAll(".", "_");
3281
+ return `${COL_STRAPI_ORDER_BY_PREFIX}__${trimmedColumnName}`;
3282
+ };
3283
+ const wrapWithDeepSort = (originalQuery, ctx) => {
3284
+ const { db, qb, uid } = ctx;
3285
+ const { tableName } = db.metadata.get(uid);
3286
+ const orderBy = ___default.default.cloneDeep(qb.state.orderBy);
3287
+ const resultQueryAlias = qb.getAlias();
3288
+ const aliasedTableName = qb.mustUseAlias() ? alias(resultQueryAlias, tableName) : tableName;
3289
+ const resultQuery = db.getConnection(aliasedTableName);
3290
+ const baseQuery = originalQuery.clone();
3291
+ const baseQueryAlias = qb.getAlias();
3292
+ baseQuery.clear("select").clear("order").clear("limit").clear("offset");
3293
+ baseQuery.select(
3294
+ // Always select the row id for future manipulation
3295
+ prefix(qb.alias, "id"),
3296
+ ...orderBy.map(
3297
+ (orderByClause) => alias(getStrapiOrderColumnAlias(orderByClause.column), orderByClause.column)
3298
+ )
3299
+ );
3300
+ const partitionedQueryAlias = qb.getAlias();
3301
+ const selectRowsAsNumberedPartitions = (partitionedQuery) => {
3302
+ const prefixedOrderBy = orderBy.map((orderByClause) => ({
3303
+ column: prefix(baseQueryAlias, getStrapiOrderColumnAlias(orderByClause.column)),
3304
+ order: orderByClause.order
3305
+ }));
3306
+ const orderByColumns = prefixedOrderBy.map(___default.default.prop("column"));
3307
+ partitionedQuery.select(
3308
+ // Always select baseQuery.id
3309
+ prefix(baseQueryAlias, "id"),
3310
+ ...orderByColumns
3311
+ ).rowNumber(COL_STRAPI_ROW_NUMBER, (subQuery) => {
3312
+ for (const orderByClause of prefixedOrderBy) {
3313
+ subQuery.orderBy(orderByClause.column, orderByClause.order, "last");
3314
+ }
3315
+ subQuery.partitionBy(`${baseQueryAlias}.id`);
3316
+ }).from(baseQuery.as(baseQueryAlias)).as(partitionedQueryAlias);
3317
+ };
3318
+ const originalSelect = ___default.default.difference(
3319
+ qb.state.select,
3320
+ // Remove order by columns from the initial select
3321
+ qb.state.orderBy.map(___default.default.prop("column"))
3322
+ ).map(prefix(resultQueryAlias));
3323
+ resultQuery.select(originalSelect).innerJoin(selectRowsAsNumberedPartitions, function() {
3324
+ this.on(`${partitionedQueryAlias}.id`, `${resultQueryAlias}.id`).andOnVal(`${partitionedQueryAlias}.${COL_STRAPI_ROW_NUMBER}`, "=", 1);
3325
+ });
3326
+ if (qb.state.limit) {
3327
+ resultQuery.limit(qb.state.limit);
3328
+ }
3329
+ if (qb.state.offset) {
3330
+ resultQuery.offset(qb.state.offset);
3331
+ }
3332
+ if (qb.state.first) {
3333
+ resultQuery.first();
3334
+ }
3335
+ resultQuery.orderBy([
3336
+ // Transform "order by" clause to their T alias and prefix them with T alias
3337
+ ...orderBy.map((orderByClause) => ({
3338
+ column: prefix(partitionedQueryAlias, getStrapiOrderColumnAlias(orderByClause.column)),
3339
+ order: orderByClause.order
3340
+ })),
3341
+ // Add T.id to the order by clause to get consistent results in case several rows have the exact same order
3342
+ { column: `${partitionedQueryAlias}.id`, order: "asc" }
3343
+ ]);
3344
+ return resultQuery;
3345
+ };
3346
+ const alias = ___default.default.curry((alias2, value) => `${value} as ${alias2}`);
3347
+ const prefix = ___default.default.curry((prefix2, value) => `${prefix2}.${value}`);
3215
3348
  const joinColPrefix = "__strapi";
3216
3349
  const XtoOne = async (input, ctx) => {
3217
3350
  const { attribute, attributeName, results, populateValue, targetMeta, isCount } = input;
@@ -3239,8 +3372,8 @@ const XtoOne = async (input, ctx) => {
3239
3372
  const { joinTable } = attribute;
3240
3373
  const qb2 = db.entityManager.createQueryBuilder(targetMeta.uid);
3241
3374
  const { name: joinColumnName, referencedColumn: referencedColumnName } = joinTable.joinColumn;
3242
- const alias = qb2.getAlias();
3243
- const joinColAlias = `${alias}.${joinColumnName}`;
3375
+ const alias2 = qb2.getAlias();
3376
+ const joinColAlias = `${alias2}.${joinColumnName}`;
3244
3377
  const joinColRenameAs = `${joinColPrefix}${joinColumnName}`;
3245
3378
  const joinColSelect = `${joinColAlias} as ${joinColRenameAs}`;
3246
3379
  const referencedValues = ___default.default.uniq(
@@ -3254,7 +3387,7 @@ const XtoOne = async (input, ctx) => {
3254
3387
  return;
3255
3388
  }
3256
3389
  const rows2 = await qb2.init(populateValue).join({
3257
- alias,
3390
+ alias: alias2,
3258
3391
  referencedTable: joinTable.name,
3259
3392
  referencedColumn: joinTable.inverseJoinColumn.name,
3260
3393
  rootColumn: joinTable.inverseJoinColumn.referencedColumn,
@@ -3280,7 +3413,7 @@ const XtoOne = async (input, ctx) => {
3280
3413
  return;
3281
3414
  }
3282
3415
  const rows = await qb2.init(populateValue).join({
3283
- alias,
3416
+ alias: alias2,
3284
3417
  referencedTable: joinTable.name,
3285
3418
  referencedColumn: joinTable.inverseJoinColumn.name,
3286
3419
  rootColumn: joinTable.inverseJoinColumn.referencedColumn,
@@ -3320,8 +3453,8 @@ const oneToMany = async (input, ctx) => {
3320
3453
  const { joinTable } = attribute;
3321
3454
  const qb2 = db.entityManager.createQueryBuilder(targetMeta.uid);
3322
3455
  const { name: joinColumnName, referencedColumn: referencedColumnName } = joinTable.joinColumn;
3323
- const alias = qb2.getAlias();
3324
- const joinColAlias = `${alias}.${joinColumnName}`;
3456
+ const alias2 = qb2.getAlias();
3457
+ const joinColAlias = `${alias2}.${joinColumnName}`;
3325
3458
  const joinColRenameAs = `${joinColPrefix}${joinColumnName}`;
3326
3459
  const joinColSelect = `${joinColAlias} as ${joinColRenameAs}`;
3327
3460
  const referencedValues = ___default.default.uniq(
@@ -3335,7 +3468,7 @@ const oneToMany = async (input, ctx) => {
3335
3468
  return;
3336
3469
  }
3337
3470
  const rows2 = await qb2.init(populateValue).join({
3338
- alias,
3471
+ alias: alias2,
3339
3472
  referencedTable: joinTable.name,
3340
3473
  referencedColumn: joinTable.inverseJoinColumn.name,
3341
3474
  rootColumn: joinTable.inverseJoinColumn.referencedColumn,
@@ -3361,7 +3494,7 @@ const oneToMany = async (input, ctx) => {
3361
3494
  return;
3362
3495
  }
3363
3496
  const rows = await qb2.init(populateValue).join({
3364
- alias,
3497
+ alias: alias2,
3365
3498
  referencedTable: joinTable.name,
3366
3499
  referencedColumn: joinTable.inverseJoinColumn.name,
3367
3500
  rootColumn: joinTable.inverseJoinColumn.referencedColumn,
@@ -3382,8 +3515,8 @@ const manyToMany = async (input, ctx) => {
3382
3515
  const { joinTable } = attribute;
3383
3516
  const populateQb = db.entityManager.createQueryBuilder(targetMeta.uid);
3384
3517
  const { name: joinColumnName, referencedColumn: referencedColumnName } = joinTable.joinColumn;
3385
- const alias = populateQb.getAlias();
3386
- const joinColAlias = `${alias}.${joinColumnName}`;
3518
+ const alias2 = populateQb.getAlias();
3519
+ const joinColAlias = `${alias2}.${joinColumnName}`;
3387
3520
  const joinColRenameAs = `${joinColPrefix}${joinColumnName}`;
3388
3521
  const joinColSelect = `${joinColAlias} as ${joinColRenameAs}`;
3389
3522
  const referencedValues = ___default.default.uniq(
@@ -3397,7 +3530,7 @@ const manyToMany = async (input, ctx) => {
3397
3530
  return;
3398
3531
  }
3399
3532
  const rows2 = await populateQb.init(populateValue).join({
3400
- alias,
3533
+ alias: alias2,
3401
3534
  referencedTable: joinTable.name,
3402
3535
  referencedColumn: joinTable.inverseJoinColumn.name,
3403
3536
  rootColumn: joinTable.inverseJoinColumn.referencedColumn,
@@ -3423,7 +3556,7 @@ const manyToMany = async (input, ctx) => {
3423
3556
  return;
3424
3557
  }
3425
3558
  const rows = await populateQb.init(populateValue).join({
3426
- alias,
3559
+ alias: alias2,
3427
3560
  referencedTable: joinTable.name,
3428
3561
  referencedColumn: joinTable.inverseJoinColumn.name,
3429
3562
  rootColumn: joinTable.inverseJoinColumn.referencedColumn,
@@ -3474,9 +3607,9 @@ const morphX = async (input, ctx) => {
3474
3607
  return;
3475
3608
  }
3476
3609
  const qb = db.entityManager.createQueryBuilder(target);
3477
- const alias = qb.getAlias();
3610
+ const alias2 = qb.getAlias();
3478
3611
  const rows = await qb.init(populateValue).join({
3479
- alias,
3612
+ alias: alias2,
3480
3613
  referencedTable: joinTable.name,
3481
3614
  referencedColumn: joinColumn.name,
3482
3615
  rootColumn: joinColumn.referencedColumn,
@@ -3486,9 +3619,9 @@ const morphX = async (input, ctx) => {
3486
3619
  field: attributeName
3487
3620
  },
3488
3621
  orderBy: ___default.default.mapValues((v) => populateValue.ordering || v, joinTable.orderBy)
3489
- }).addSelect([`${alias}.${idColumn.name}`, `${alias}.${typeColumn.name}`]).where({
3490
- [`${alias}.${idColumn.name}`]: referencedValues,
3491
- [`${alias}.${typeColumn.name}`]: uid
3622
+ }).addSelect([`${alias2}.${idColumn.name}`, `${alias2}.${typeColumn.name}`]).where({
3623
+ [`${alias2}.${idColumn.name}`]: referencedValues,
3624
+ [`${alias2}.${typeColumn.name}`]: uid
3492
3625
  }).execute({ mapResults: false });
3493
3626
  const map = ___default.default.groupBy(idColumn.name)(rows);
3494
3627
  results.forEach((result) => {
@@ -3737,13 +3870,6 @@ const processPopulate = (populate, ctx) => {
3737
3870
  }
3738
3871
  return finalPopulate;
3739
3872
  };
3740
- function isKnexQuery(value) {
3741
- return value instanceof KnexBuilder__default.default || value instanceof KnexRaw__default.default;
3742
- }
3743
- const addSchema = (db, tableName) => {
3744
- const schemaName = db.getSchemaName();
3745
- return schemaName ? `${schemaName}.${tableName}` : tableName;
3746
- };
3747
3873
  const isRecord$1 = (value) => _.isPlainObject(value);
3748
3874
  const castValue = (value, attribute) => {
3749
3875
  if (!attribute) {
@@ -3785,8 +3911,8 @@ const processNested = (where, ctx) => {
3785
3911
  return processWhere(where, ctx);
3786
3912
  };
3787
3913
  const processRelationWhere = (where, ctx) => {
3788
- const { qb, alias } = ctx;
3789
- const idAlias = qb.aliasColumn("id", alias);
3914
+ const { qb, alias: alias2 } = ctx;
3915
+ const idAlias = qb.aliasColumn("id", alias2);
3790
3916
  if (!isRecord$1(where)) {
3791
3917
  return { [idAlias]: where };
3792
3918
  }
@@ -3816,7 +3942,7 @@ function processWhere(where, ctx) {
3816
3942
  if (_.isArray(where)) {
3817
3943
  return where.map((sub) => processWhere(sub, ctx));
3818
3944
  }
3819
- const { db, uid, qb, alias } = ctx;
3945
+ const { db, uid, qb, alias: alias2 } = ctx;
3820
3946
  const meta = db.metadata.get(uid);
3821
3947
  const filters = {};
3822
3948
  for (const key of Object.keys(where)) {
@@ -3839,12 +3965,12 @@ function processWhere(where, ctx) {
3839
3965
  }
3840
3966
  const attribute = meta.attributes[key];
3841
3967
  if (!attribute) {
3842
- filters[qb.aliasColumn(key, alias)] = processAttributeWhere(null, value);
3968
+ filters[qb.aliasColumn(key, alias2)] = processAttributeWhere(null, value);
3843
3969
  continue;
3844
3970
  }
3845
3971
  if (isRelation(attribute.type) && "target" in attribute) {
3846
3972
  const subAlias = createJoin(ctx, {
3847
- alias: alias || qb.alias,
3973
+ alias: alias2 || qb.alias,
3848
3974
  attributeName: key,
3849
3975
  attribute
3850
3976
  });
@@ -3859,7 +3985,7 @@ function processWhere(where, ctx) {
3859
3985
  }
3860
3986
  if (isScalar(attribute.type)) {
3861
3987
  const columnName = toColumnName(meta, key);
3862
- const aliasedColumnName = qb.aliasColumn(columnName, alias);
3988
+ const aliasedColumnName = qb.aliasColumn(columnName, alias2);
3863
3989
  filters[aliasedColumnName] = processAttributeWhere(attribute, value);
3864
3990
  continue;
3865
3991
  }
@@ -4087,7 +4213,7 @@ class ReadableStrapiQuery extends stream.Readable {
4087
4213
  * Custom ._read() implementation
4088
4214
  *
4089
4215
  * NOTE: Here "size" means the number of entities to be read from the database.
4090
- * Not the actual byte size, as it would means that we need to return partial entities.
4216
+ * Not the actual byte size, as it would mean that we need to return partial entities.
4091
4217
  *
4092
4218
  */
4093
4219
  async _read(size) {
@@ -4150,61 +4276,6 @@ class ReadableStrapiQuery extends stream.Readable {
4150
4276
  }
4151
4277
  }
4152
4278
  }
4153
- const storage = new node_async_hooks.AsyncLocalStorage();
4154
- const transactionCtx = {
4155
- async run(trx, cb) {
4156
- const store = storage.getStore();
4157
- return storage.run(
4158
- {
4159
- trx,
4160
- // Fill with existing callbacks if nesting transactions
4161
- commitCallbacks: store?.commitCallbacks || [],
4162
- rollbackCallbacks: store?.rollbackCallbacks || []
4163
- },
4164
- cb
4165
- );
4166
- },
4167
- get() {
4168
- const store = storage.getStore();
4169
- return store?.trx;
4170
- },
4171
- async commit(trx) {
4172
- const store = storage.getStore();
4173
- if (store?.trx) {
4174
- store.trx = null;
4175
- }
4176
- await trx.commit();
4177
- if (!store?.commitCallbacks.length) {
4178
- return;
4179
- }
4180
- store.commitCallbacks.forEach((cb) => cb());
4181
- store.commitCallbacks = [];
4182
- },
4183
- async rollback(trx) {
4184
- const store = storage.getStore();
4185
- if (store?.trx) {
4186
- store.trx = null;
4187
- }
4188
- await trx.rollback();
4189
- if (!store?.rollbackCallbacks.length) {
4190
- return;
4191
- }
4192
- store.rollbackCallbacks.forEach((cb) => cb());
4193
- store.rollbackCallbacks = [];
4194
- },
4195
- onCommit(cb) {
4196
- const store = storage.getStore();
4197
- if (store?.commitCallbacks) {
4198
- store.commitCallbacks.push(cb);
4199
- }
4200
- },
4201
- onRollback(cb) {
4202
- const store = storage.getStore();
4203
- if (store?.rollbackCallbacks) {
4204
- store.rollbackCallbacks.push(cb);
4205
- }
4206
- }
4207
- };
4208
4279
  const createQueryBuilder = (uid, db, initialState = {}) => {
4209
4280
  const meta = db.metadata.get(uid);
4210
4281
  const { tableName } = meta;
@@ -4237,9 +4308,9 @@ const createQueryBuilder = (uid, db, initialState = {}) => {
4237
4308
  initialState
4238
4309
  );
4239
4310
  const getAlias = () => {
4240
- const alias = `t${state.aliasCounter}`;
4311
+ const alias2 = `t${state.aliasCounter}`;
4241
4312
  state.aliasCounter += 1;
4242
- return alias;
4313
+ return alias2;
4243
4314
  };
4244
4315
  return {
4245
4316
  alias: getAlias(),
@@ -4406,15 +4477,15 @@ const createQueryBuilder = (uid, db, initialState = {}) => {
4406
4477
  mustUseAlias() {
4407
4478
  return ["select", "count"].includes(state.type);
4408
4479
  },
4409
- aliasColumn(key, alias) {
4480
+ aliasColumn(key, alias2) {
4410
4481
  if (typeof key !== "string") {
4411
4482
  return key;
4412
4483
  }
4413
4484
  if (key.indexOf(".") >= 0) {
4414
4485
  return key;
4415
4486
  }
4416
- if (!___default.default.isNil(alias)) {
4417
- return `${alias}.${key}`;
4487
+ if (!___default.default.isNil(alias2)) {
4488
+ return `${alias2}.${key}`;
4418
4489
  }
4419
4490
  return this.mustUseAlias() ? `${this.alias}.${key}` : key;
4420
4491
  },
@@ -4449,6 +4520,20 @@ const createQueryBuilder = (uid, db, initialState = {}) => {
4449
4520
  shouldUseDistinct() {
4450
4521
  return state.joins.length > 0 && ___default.default.isEmpty(state.groupBy);
4451
4522
  },
4523
+ shouldUseDeepSort() {
4524
+ return state.orderBy.filter(({ column }) => column.indexOf(".") >= 0).filter(({ column }) => {
4525
+ const col = column.split(".");
4526
+ for (let i = 0; i < col.length - 1; i += 1) {
4527
+ const el = col[i];
4528
+ const isRelationAttribute = meta.attributes[el]?.type === "relation";
4529
+ const isAliasedRelation = Object.values(state.joins).map((join) => join.alias).includes(el);
4530
+ if (isRelationAttribute || isAliasedRelation) {
4531
+ return true;
4532
+ }
4533
+ }
4534
+ return false;
4535
+ }).length > 0;
4536
+ },
4452
4537
  processSelect() {
4453
4538
  state.select = state.select.map((field) => {
4454
4539
  if (isKnexQuery(field)) {
@@ -4566,6 +4651,9 @@ const createQueryBuilder = (uid, db, initialState = {}) => {
4566
4651
  if (state.joins.length > 0) {
4567
4652
  applyJoins(qb, state.joins);
4568
4653
  }
4654
+ if (this.shouldUseDeepSort()) {
4655
+ return wrapWithDeepSort(qb, { qb: this, db, uid });
4656
+ }
4569
4657
  return qb;
4570
4658
  },
4571
4659
  async execute({ mapResults = true } = {}) {
@@ -4775,11 +4863,10 @@ const getDocumentSiblingIdsQuery = (tableName, id) => {
4775
4863
  if (!isContentType) {
4776
4864
  return [id];
4777
4865
  }
4778
- return (con) => {
4779
- con.from(tableName).select("id").where(
4780
- "document_id",
4781
- (con2) => con2.select("document_id").from(tableName).where("id", id)
4782
- );
4866
+ return function(query) {
4867
+ query.select("id").from(tableName).whereIn("document_id", (documentIDSubQuery) => {
4868
+ documentIDSubQuery.from(tableName).select("document_id").where("id", id);
4869
+ });
4783
4870
  };
4784
4871
  };
4785
4872
  const deletePreviousOneToAnyRelations = async ({
@@ -4797,11 +4884,7 @@ const deletePreviousOneToAnyRelations = async ({
4797
4884
  const { joinTable } = attribute;
4798
4885
  const { joinColumn, inverseJoinColumn } = joinTable;
4799
4886
  const con = db.getConnection();
4800
- await con.delete().from(joinTable.name).whereNotIn(
4801
- // @ts-expect-error - knex incorrectly expects a string array
4802
- joinColumn.name,
4803
- getDocumentSiblingIdsQuery(joinColumn.referencedTable, id)
4804
- ).whereIn(inverseJoinColumn.name, relIdsToadd).where(joinTable.on || {}).transacting(trx);
4887
+ await con.delete().from(joinTable.name).whereNotIn(joinColumn.name, getDocumentSiblingIdsQuery(joinColumn.referencedTable, id)).whereIn(inverseJoinColumn.name, relIdsToadd).where(joinTable.on || {}).transacting(trx);
4805
4888
  await cleanOrderColumns({ attribute, db, inverseRelIds: relIdsToadd, transaction: trx });
4806
4889
  };
4807
4890
  const deletePreviousAnyToOneRelations = async ({
@@ -4819,7 +4902,6 @@ const deletePreviousAnyToOneRelations = async ({
4819
4902
  }
4820
4903
  if (isManyToAny(attribute)) {
4821
4904
  const relsToDelete = await con.select(inverseJoinColumn.name).from(joinTable.name).where(joinColumn.name, id).whereNotIn(
4822
- // @ts-expect-error - knex incorrectly expects a string array
4823
4905
  inverseJoinColumn.name,
4824
4906
  getDocumentSiblingIdsQuery(inverseJoinColumn.referencedTable, relIdToadd)
4825
4907
  ).where(joinTable.on || {}).transacting(trx);
@@ -4831,7 +4913,6 @@ const deletePreviousAnyToOneRelations = async ({
4831
4913
  await cleanOrderColumns({ attribute, db, inverseRelIds: relIdsToDelete, transaction: trx });
4832
4914
  } else {
4833
4915
  await con.delete().from(joinTable.name).where(joinColumn.name, id).whereNotIn(
4834
- // @ts-expect-error - knex incorrectly expects a string array
4835
4916
  inverseJoinColumn.name,
4836
4917
  getDocumentSiblingIdsQuery(inverseJoinColumn.referencedTable, relIdToadd)
4837
4918
  ).where(joinTable.on || {}).transacting(trx);