@zenstackhq/runtime 3.0.0-alpha.27 → 3.0.0-alpha.29

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,5 +1,5 @@
1
1
  import * as kysely from 'kysely';
2
- import { R as RuntimePlugin, V as OnKyselyQueryArgs } from '../../contract-c8GpEAl3.cjs';
2
+ import { R as RuntimePlugin, V as OnKyselyQueryArgs } from '../../contract-B8DJmviN.cjs';
3
3
  import { SchemaDef } from '@zenstackhq/sdk/schema';
4
4
  import 'decimal.js';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import * as kysely from 'kysely';
2
- import { R as RuntimePlugin, V as OnKyselyQueryArgs } from '../../contract-c8GpEAl3.js';
2
+ import { R as RuntimePlugin, V as OnKyselyQueryArgs } from '../../contract-B8DJmviN.js';
3
3
  import { SchemaDef } from '@zenstackhq/sdk/schema';
4
4
  import 'decimal.js';
5
5
 
@@ -262,7 +262,9 @@ function buildFieldRef(schema, model, field, options, eb, modelAlias, inlineComp
262
262
  if (!computer) {
263
263
  throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
264
264
  }
265
- return computer(eb);
265
+ return computer(eb, {
266
+ currentModel: modelAlias
267
+ });
266
268
  }
267
269
  }
268
270
  __name(buildFieldRef, "buildFieldRef");
@@ -305,11 +307,33 @@ function getManyToManyRelation(schema, model, field) {
305
307
  model,
306
308
  fieldDef.type
307
309
  ].sort();
310
+ let orderedFK;
311
+ if (model !== fieldDef.type) {
312
+ orderedFK = sortedModelNames[0] === model ? [
313
+ "A",
314
+ "B"
315
+ ] : [
316
+ "B",
317
+ "A"
318
+ ];
319
+ } else {
320
+ const sortedFieldNames = [
321
+ field,
322
+ oppositeFieldDef.name
323
+ ].sort();
324
+ orderedFK = sortedFieldNames[0] === field ? [
325
+ "A",
326
+ "B"
327
+ ] : [
328
+ "B",
329
+ "A"
330
+ ];
331
+ }
308
332
  return {
309
- parentFkName: sortedModelNames[0] === model ? "A" : "B",
333
+ parentFkName: orderedFK[0],
310
334
  otherModel: fieldDef.type,
311
335
  otherField: fieldDef.relation.opposite,
312
- otherFkName: sortedModelNames[0] === fieldDef.type ? "A" : "B",
336
+ otherFkName: orderedFK[1],
313
337
  joinTable: fieldDef.relation.name ? `_${fieldDef.relation.name}` : `_${sortedModelNames[0]}To${sortedModelNames[1]}`
314
338
  };
315
339
  } else {
@@ -399,20 +423,20 @@ var BaseCrudDialect = class {
399
423
  return value;
400
424
  }
401
425
  // #region common query builders
402
- buildSelectModel(eb, model) {
426
+ buildSelectModel(eb, model, modelAlias) {
403
427
  const modelDef = requireModel(this.schema, model);
404
- let result = eb.selectFrom(model);
428
+ let result = eb.selectFrom(model === modelAlias ? model : `${model} as ${modelAlias}`);
405
429
  let joinBase = modelDef.baseModel;
406
430
  while (joinBase) {
407
- result = this.buildDelegateJoin(model, joinBase, result);
431
+ result = this.buildDelegateJoin(model, modelAlias, joinBase, result);
408
432
  joinBase = requireModel(this.schema, joinBase).baseModel;
409
433
  }
410
434
  return result;
411
435
  }
412
- buildFilterSortTake(model, args, query) {
436
+ buildFilterSortTake(model, args, query, modelAlias) {
413
437
  let result = query;
414
438
  if (args.where) {
415
- result = result.where((eb) => this.buildFilter(eb, model, model, args?.where));
439
+ result = result.where((eb) => this.buildFilter(eb, model, modelAlias, args?.where));
416
440
  }
417
441
  let negateOrderBy = false;
418
442
  const skip = args.skip;
@@ -422,17 +446,17 @@ var BaseCrudDialect = class {
422
446
  take = -take;
423
447
  }
424
448
  result = this.buildSkipTake(result, skip, take);
425
- result = this.buildOrderBy(result, model, model, args.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
449
+ result = this.buildOrderBy(result, model, modelAlias, args.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
426
450
  if ("distinct" in args && args.distinct) {
427
451
  const distinct = ensureArray(args.distinct);
428
452
  if (this.supportsDistinctOn) {
429
- result = result.distinctOn(distinct.map((f) => sql.ref(`${model}.${f}`)));
453
+ result = result.distinctOn(distinct.map((f) => sql.ref(`${modelAlias}.${f}`)));
430
454
  } else {
431
455
  throw new QueryError(`"distinct" is not supported by "${this.schema.provider.type}" provider`);
432
456
  }
433
457
  }
434
458
  if (args.cursor) {
435
- result = this.buildCursorFilter(model, result, args.cursor, args.orderBy, negateOrderBy);
459
+ result = this.buildCursorFilter(model, result, args.cursor, args.orderBy, negateOrderBy, modelAlias);
436
460
  }
437
461
  return result;
438
462
  }
@@ -473,11 +497,12 @@ var BaseCrudDialect = class {
473
497
  }
474
498
  return result;
475
499
  }
476
- buildCursorFilter(model, query, cursor, orderBy, negateOrderBy) {
500
+ buildCursorFilter(model, query, cursor, orderBy, negateOrderBy, modelAlias) {
477
501
  const _orderBy = orderBy ?? makeDefaultOrderBy(this.schema, model);
478
502
  const orderByItems = ensureArray(_orderBy).flatMap((obj) => Object.entries(obj));
479
503
  const eb = expressionBuilder();
480
- const cursorFilter = this.buildFilter(eb, model, model, cursor);
504
+ const subQueryAlias = `${model}$cursor$sub`;
505
+ const cursorFilter = this.buildFilter(eb, model, subQueryAlias, cursor);
481
506
  let result = query;
482
507
  const filters = [];
483
508
  for (let i = orderByItems.length - 1; i >= 0; i--) {
@@ -486,7 +511,7 @@ var BaseCrudDialect = class {
486
511
  const [field, order] = orderByItems[j];
487
512
  const _order = negateOrderBy ? order === "asc" ? "desc" : "asc" : order;
488
513
  const op = j === i ? _order === "asc" ? ">=" : "<=" : "=";
489
- andFilters.push(eb(eb.ref(`${model}.${field}`), op, eb.selectFrom(model).select(`${model}.${field}`).where(cursorFilter)));
514
+ andFilters.push(eb(eb.ref(`${modelAlias}.${field}`), op, this.buildSelectModel(eb, model, subQueryAlias).select(`${subQueryAlias}.${field}`).where(cursorFilter)));
490
515
  }
491
516
  filters.push(eb.and(andFilters));
492
517
  }
@@ -555,25 +580,26 @@ var BaseCrudDialect = class {
555
580
  }
556
581
  return this.and(eb, ...conditions);
557
582
  }
558
- buildToManyRelationFilter(eb, model, table, field, fieldDef, payload) {
583
+ buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
559
584
  if (payload === null) {
560
- return eb(sql.ref(`${table}.${field}`), "is", null);
585
+ return eb(sql.ref(`${modelAlias}.${field}`), "is", null);
561
586
  }
562
587
  const relationModel = fieldDef.type;
588
+ const relationFilterSelectAlias = `${modelAlias}$${field}$filter`;
563
589
  const buildPkFkWhereRefs = /* @__PURE__ */ __name((eb2) => {
564
590
  const m2m = getManyToManyRelation(this.schema, model, field);
565
591
  if (m2m) {
566
592
  const modelIdField = getIdFields(this.schema, model)[0];
567
593
  const relationIdField = getIdFields(this.schema, relationModel)[0];
568
- return eb2(sql.ref(`${relationModel}.${relationIdField}`), "in", eb2.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(sql.ref(`${m2m.joinTable}.${m2m.parentFkName}`), "=", sql.ref(`${table}.${modelIdField}`)));
594
+ return eb2(sql.ref(`${relationFilterSelectAlias}.${relationIdField}`), "in", eb2.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(sql.ref(`${m2m.joinTable}.${m2m.parentFkName}`), "=", sql.ref(`${modelAlias}.${modelIdField}`)));
569
595
  } else {
570
596
  const relationKeyPairs = getRelationForeignKeyFieldPairs(this.schema, model, field);
571
597
  let result2 = this.true(eb2);
572
598
  for (const { fk, pk } of relationKeyPairs.keyPairs) {
573
599
  if (relationKeyPairs.ownedByModel) {
574
- result2 = this.and(eb2, result2, eb2(sql.ref(`${table}.${fk}`), "=", sql.ref(`${relationModel}.${pk}`)));
600
+ result2 = this.and(eb2, result2, eb2(sql.ref(`${modelAlias}.${fk}`), "=", sql.ref(`${relationFilterSelectAlias}.${pk}`)));
575
601
  } else {
576
- result2 = this.and(eb2, result2, eb2(sql.ref(`${table}.${pk}`), "=", sql.ref(`${relationModel}.${fk}`)));
602
+ result2 = this.and(eb2, result2, eb2(sql.ref(`${modelAlias}.${pk}`), "=", sql.ref(`${relationFilterSelectAlias}.${fk}`)));
577
603
  }
578
604
  }
579
605
  return result2;
@@ -586,15 +612,15 @@ var BaseCrudDialect = class {
586
612
  }
587
613
  switch (key) {
588
614
  case "some": {
589
- result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationModel, subPayload)), ">", 0));
615
+ result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel, relationFilterSelectAlias).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationFilterSelectAlias, subPayload)), ">", 0));
590
616
  break;
591
617
  }
592
618
  case "every": {
593
- result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => eb1.not(this.buildFilter(eb1, relationModel, relationModel, subPayload))), "=", 0));
619
+ result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel, relationFilterSelectAlias).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => eb1.not(this.buildFilter(eb1, relationModel, relationFilterSelectAlias, subPayload))), "=", 0));
594
620
  break;
595
621
  }
596
622
  case "none": {
597
- result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationModel, subPayload)), "=", 0));
623
+ result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel, relationFilterSelectAlias).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationFilterSelectAlias, subPayload)), "=", 0));
598
624
  break;
599
625
  }
600
626
  }
@@ -837,8 +863,9 @@ var BaseCrudDialect = class {
837
863
  invariant(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
838
864
  const sort = this.negateSort(value._count, negated);
839
865
  result = result.orderBy((eb) => {
840
- let subQuery = this.buildSelectModel(eb, relationModel);
841
- const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, relationModel);
866
+ const subQueryAlias = `${modelAlias}$orderBy$${field}$count`;
867
+ let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
868
+ const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, subQueryAlias);
842
869
  subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(sql.ref(left), "=", sql.ref(right)))));
843
870
  subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
844
871
  return subQuery;
@@ -856,7 +883,7 @@ var BaseCrudDialect = class {
856
883
  });
857
884
  return result;
858
885
  }
859
- buildSelectAllFields(model, query, omit) {
886
+ buildSelectAllFields(model, query, omit, modelAlias) {
860
887
  const modelDef = requireModel(this.schema, model);
861
888
  let result = query;
862
889
  for (const field of Object.keys(modelDef.fields)) {
@@ -866,11 +893,11 @@ var BaseCrudDialect = class {
866
893
  if (omit?.[field] === true) {
867
894
  continue;
868
895
  }
869
- result = this.buildSelectField(result, model, model, field);
896
+ result = this.buildSelectField(result, model, modelAlias, field);
870
897
  }
871
898
  const descendants = getDelegateDescendantModels(this.schema, model);
872
899
  for (const subModel of descendants) {
873
- result = this.buildDelegateJoin(model, subModel.name, result);
900
+ result = this.buildDelegateJoin(model, modelAlias, subModel.name, result);
874
901
  result = result.select((eb) => {
875
902
  const jsonObject = {};
876
903
  for (const field of Object.keys(subModel.fields)) {
@@ -894,11 +921,11 @@ var BaseCrudDialect = class {
894
921
  return this.buildSelectField(query, fieldDef.originModel, fieldDef.originModel, field);
895
922
  }
896
923
  }
897
- buildDelegateJoin(thisModel, otherModel, query) {
924
+ buildDelegateJoin(thisModel, thisModelAlias, otherModelAlias, query) {
898
925
  const idFields = getIdFields(this.schema, thisModel);
899
- query = query.leftJoin(otherModel, (qb) => {
926
+ query = query.leftJoin(otherModelAlias, (qb) => {
900
927
  for (const idField of idFields) {
901
- qb = qb.onRef(`${thisModel}.${idField}`, "=", `${otherModel}.${idField}`);
928
+ qb = qb.onRef(`${thisModelAlias}.${idField}`, "=", `${otherModelAlias}.${idField}`);
902
929
  }
903
930
  return qb;
904
931
  });
@@ -1015,11 +1042,12 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1015
1042
  return qb.leftJoinLateral((eb) => {
1016
1043
  const joinTableName = `${parentName}$${relationField}`;
1017
1044
  let result = eb.selectFrom(`${relationModel} as ${joinTableName}`);
1045
+ const subQueryAlias = `${relationModel}$${relationField}$sub`;
1018
1046
  result = eb.selectFrom(() => {
1019
- let subQuery = this.buildSelectModel(eb, relationModel);
1020
- subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
1047
+ let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
1048
+ subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
1021
1049
  if (payload && typeof payload === "object") {
1022
- subQuery = this.buildFilterSortTake(relationModel, payload, subQuery);
1050
+ subQuery = this.buildFilterSortTake(relationModel, payload, subQuery, subQueryAlias);
1023
1051
  }
1024
1052
  const m2m = getManyToManyRelation(this.schema, model, relationField);
1025
1053
  if (m2m) {
@@ -1027,21 +1055,21 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1027
1055
  const relationIds = getIdFields(this.schema, relationModel);
1028
1056
  invariant2(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1029
1057
  invariant2(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1030
- subQuery = subQuery.where(eb(eb.ref(`${relationModel}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentName}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
1058
+ subQuery = subQuery.where(eb(eb.ref(`${subQueryAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentName}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
1031
1059
  } else {
1032
- const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, relationModel);
1060
+ const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, subQueryAlias);
1033
1061
  subQuery = subQuery.where((eb2) => this.and(eb2, ...joinPairs.map(([left, right]) => eb2(sql2.ref(left), "=", sql2.ref(right)))));
1034
1062
  }
1035
1063
  return subQuery.as(joinTableName);
1036
1064
  });
1037
- result = this.buildRelationObjectSelect(relationModel, relationField, relationFieldDef, result, payload, parentName);
1065
+ result = this.buildRelationObjectSelect(relationModel, joinTableName, relationField, relationFieldDef, result, payload, parentName);
1038
1066
  result = this.buildRelationJoins(relationModel, relationField, result, payload, parentName);
1039
1067
  return result.as(joinTableName);
1040
1068
  }, (join) => join.onTrue());
1041
1069
  }
1042
- buildRelationObjectSelect(relationModel, relationField, relationFieldDef, qb, payload, parentName) {
1070
+ buildRelationObjectSelect(relationModel, relationModelAlias, relationField, relationFieldDef, qb, payload, parentName) {
1043
1071
  qb = qb.select((eb) => {
1044
- const objArgs = this.buildRelationObjectArgs(relationModel, relationField, eb, payload, parentName);
1072
+ const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias, relationField, eb, payload, parentName);
1045
1073
  if (relationFieldDef.array) {
1046
1074
  return eb.fn.coalesce(sql2`jsonb_agg(jsonb_build_object(${sql2.join(objArgs)}))`, sql2`'[]'::jsonb`).as("$j");
1047
1075
  } else {
@@ -1050,7 +1078,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1050
1078
  });
1051
1079
  return qb;
1052
1080
  }
1053
- buildRelationObjectArgs(relationModel, relationField, eb, payload, parentAlias) {
1081
+ buildRelationObjectArgs(relationModel, relationModelAlias, relationField, eb, payload, parentAlias) {
1054
1082
  const relationModelDef = requireModel(this.schema, relationModel);
1055
1083
  const objArgs = [];
1056
1084
  const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
@@ -1063,7 +1091,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1063
1091
  if (payload === true || !payload.select) {
1064
1092
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
1065
1093
  sql2.lit(field),
1066
- this.fieldRef(relationModel, field, eb, void 0, false)
1094
+ this.fieldRef(relationModel, field, eb, relationModelAlias, false)
1067
1095
  ]).flatMap((v) => v));
1068
1096
  } else if (payload.select) {
1069
1097
  objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
@@ -1179,10 +1207,11 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1179
1207
  const relationModelDef = requireModel(this.schema, relationModel);
1180
1208
  const subQueryName = `${parentAlias}$${relationField}`;
1181
1209
  let tbl = eb.selectFrom(() => {
1182
- let subQuery = this.buildSelectModel(eb, relationModel);
1183
- subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
1210
+ const subQueryAlias = `${parentAlias}$${relationField}$sub`;
1211
+ let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
1212
+ subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
1184
1213
  if (payload && typeof payload === "object") {
1185
- subQuery = this.buildFilterSortTake(relationModel, payload, subQuery);
1214
+ subQuery = this.buildFilterSortTake(relationModel, payload, subQuery, subQueryAlias);
1186
1215
  }
1187
1216
  const m2m = getManyToManyRelation(this.schema, model, relationField);
1188
1217
  if (m2m) {
@@ -1190,14 +1219,14 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1190
1219
  const relationIds = getIdFields(this.schema, relationModel);
1191
1220
  invariant3(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1192
1221
  invariant3(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1193
- subQuery = subQuery.where(eb(eb.ref(`${relationModel}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
1222
+ subQuery = subQuery.where(eb(eb.ref(`${subQueryAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
1194
1223
  } else {
1195
1224
  const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
1196
1225
  keyPairs.forEach(({ fk, pk }) => {
1197
1226
  if (ownedByModel) {
1198
- subQuery = subQuery.whereRef(`${relationModel}.${pk}`, "=", `${parentAlias}.${fk}`);
1227
+ subQuery = subQuery.whereRef(`${subQueryAlias}.${pk}`, "=", `${parentAlias}.${fk}`);
1199
1228
  } else {
1200
- subQuery = subQuery.whereRef(`${relationModel}.${fk}`, "=", `${parentAlias}.${pk}`);
1229
+ subQuery = subQuery.whereRef(`${subQueryAlias}.${fk}`, "=", `${parentAlias}.${pk}`);
1201
1230
  }
1202
1231
  });
1203
1232
  }