@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.
package/dist/index.d.cts CHANGED
@@ -1,11 +1,11 @@
1
- import { C as ClientConstructor } from './contract-c8GpEAl3.cjs';
2
- export { K as AggregateArgs, L as AggregateResult, B as BatchResult, i as BooleanFilter, h as BytesFilter, c as ClientContract, d as ClientOptions, G as CountArgs, H as CountResult, u as CreateArgs, w as CreateManyAndReturnArgs, v as CreateManyArgs, D as DateTimeFilter, A as DeleteArgs, E as DeleteManyArgs, F as FindArgs, s as FindFirstArgs, r as FindManyArgs, t as FindUniqueArgs, P as GroupByArgs, Q as GroupByResult, I as IncludeInput, J as JsonArray, a as JsonObject, b as JsonValue, M as ModelResult, k as NullsOrder, N as NumberFilter, m as OmitInput, O as OrderBy, n as SelectIncludeOmit, o as SelectInput, q as SelectSubset, S as SimplifiedModelResult, j as SortOrder, g as StringFilter, p as Subset, T as ToKysely, f as TypeDefResult, U as UpdateArgs, y as UpdateManyAndReturnArgs, x as UpdateManyArgs, z as UpsertArgs, W as WhereInput, l as WhereUniqueInput, e as definePlugin } from './contract-c8GpEAl3.cjs';
1
+ import { C as ClientConstructor } from './contract-B8DJmviN.cjs';
2
+ export { K as AggregateArgs, L as AggregateResult, B as BatchResult, i as BooleanFilter, h as BytesFilter, c as ClientContract, d as ClientOptions, G as CountArgs, H as CountResult, u as CreateArgs, w as CreateManyAndReturnArgs, v as CreateManyArgs, D as DateTimeFilter, A as DeleteArgs, E as DeleteManyArgs, F as FindArgs, s as FindFirstArgs, r as FindManyArgs, t as FindUniqueArgs, P as GroupByArgs, Q as GroupByResult, I as IncludeInput, J as JsonArray, a as JsonObject, b as JsonValue, M as ModelResult, k as NullsOrder, N as NumberFilter, m as OmitInput, O as OrderBy, n as SelectIncludeOmit, o as SelectInput, q as SelectSubset, S as SimplifiedModelResult, j as SortOrder, g as StringFilter, p as Subset, T as ToKysely, f as TypeDefResult, U as UpdateArgs, y as UpdateManyAndReturnArgs, x as UpdateManyArgs, z as UpsertArgs, W as WhereInput, l as WhereUniqueInput, e as definePlugin } from './contract-B8DJmviN.cjs';
3
3
  import 'decimal.js';
4
4
  import '@zenstackhq/sdk/schema';
5
5
  import 'kysely';
6
6
 
7
7
  /**
8
- * ZenStack client.
8
+ * ZenStack ORM client.
9
9
  */
10
10
  declare const ZenStackClient: ClientConstructor;
11
11
 
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { C as ClientConstructor } from './contract-c8GpEAl3.js';
2
- export { K as AggregateArgs, L as AggregateResult, B as BatchResult, i as BooleanFilter, h as BytesFilter, c as ClientContract, d as ClientOptions, G as CountArgs, H as CountResult, u as CreateArgs, w as CreateManyAndReturnArgs, v as CreateManyArgs, D as DateTimeFilter, A as DeleteArgs, E as DeleteManyArgs, F as FindArgs, s as FindFirstArgs, r as FindManyArgs, t as FindUniqueArgs, P as GroupByArgs, Q as GroupByResult, I as IncludeInput, J as JsonArray, a as JsonObject, b as JsonValue, M as ModelResult, k as NullsOrder, N as NumberFilter, m as OmitInput, O as OrderBy, n as SelectIncludeOmit, o as SelectInput, q as SelectSubset, S as SimplifiedModelResult, j as SortOrder, g as StringFilter, p as Subset, T as ToKysely, f as TypeDefResult, U as UpdateArgs, y as UpdateManyAndReturnArgs, x as UpdateManyArgs, z as UpsertArgs, W as WhereInput, l as WhereUniqueInput, e as definePlugin } from './contract-c8GpEAl3.js';
1
+ import { C as ClientConstructor } from './contract-B8DJmviN.js';
2
+ export { K as AggregateArgs, L as AggregateResult, B as BatchResult, i as BooleanFilter, h as BytesFilter, c as ClientContract, d as ClientOptions, G as CountArgs, H as CountResult, u as CreateArgs, w as CreateManyAndReturnArgs, v as CreateManyArgs, D as DateTimeFilter, A as DeleteArgs, E as DeleteManyArgs, F as FindArgs, s as FindFirstArgs, r as FindManyArgs, t as FindUniqueArgs, P as GroupByArgs, Q as GroupByResult, I as IncludeInput, J as JsonArray, a as JsonObject, b as JsonValue, M as ModelResult, k as NullsOrder, N as NumberFilter, m as OmitInput, O as OrderBy, n as SelectIncludeOmit, o as SelectInput, q as SelectSubset, S as SimplifiedModelResult, j as SortOrder, g as StringFilter, p as Subset, T as ToKysely, f as TypeDefResult, U as UpdateArgs, y as UpdateManyAndReturnArgs, x as UpdateManyArgs, z as UpsertArgs, W as WhereInput, l as WhereUniqueInput, e as definePlugin } from './contract-B8DJmviN.js';
3
3
  import 'decimal.js';
4
4
  import '@zenstackhq/sdk/schema';
5
5
  import 'kysely';
6
6
 
7
7
  /**
8
- * ZenStack client.
8
+ * ZenStack ORM client.
9
9
  */
10
10
  declare const ZenStackClient: ClientConstructor;
11
11
 
package/dist/index.js CHANGED
@@ -286,7 +286,9 @@ function buildFieldRef(schema, model, field, options, eb, modelAlias, inlineComp
286
286
  if (!computer) {
287
287
  throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
288
288
  }
289
- return computer(eb);
289
+ return computer(eb, {
290
+ currentModel: modelAlias
291
+ });
290
292
  }
291
293
  }
292
294
  __name(buildFieldRef, "buildFieldRef");
@@ -337,11 +339,33 @@ function getManyToManyRelation(schema, model, field) {
337
339
  model,
338
340
  fieldDef.type
339
341
  ].sort();
342
+ let orderedFK;
343
+ if (model !== fieldDef.type) {
344
+ orderedFK = sortedModelNames[0] === model ? [
345
+ "A",
346
+ "B"
347
+ ] : [
348
+ "B",
349
+ "A"
350
+ ];
351
+ } else {
352
+ const sortedFieldNames = [
353
+ field,
354
+ oppositeFieldDef.name
355
+ ].sort();
356
+ orderedFK = sortedFieldNames[0] === field ? [
357
+ "A",
358
+ "B"
359
+ ] : [
360
+ "B",
361
+ "A"
362
+ ];
363
+ }
340
364
  return {
341
- parentFkName: sortedModelNames[0] === model ? "A" : "B",
365
+ parentFkName: orderedFK[0],
342
366
  otherModel: fieldDef.type,
343
367
  otherField: fieldDef.relation.opposite,
344
- otherFkName: sortedModelNames[0] === fieldDef.type ? "A" : "B",
368
+ otherFkName: orderedFK[1],
345
369
  joinTable: fieldDef.relation.name ? `_${fieldDef.relation.name}` : `_${sortedModelNames[0]}To${sortedModelNames[1]}`
346
370
  };
347
371
  } else {
@@ -420,7 +444,6 @@ import { createId } from "@paralleldrive/cuid2";
420
444
  import { invariant as invariant7, isPlainObject as isPlainObject3 } from "@zenstackhq/common-helpers";
421
445
  import { expressionBuilder as expressionBuilder3, sql as sql4 } from "kysely";
422
446
  import { nanoid } from "nanoid";
423
- import { inspect } from "util";
424
447
  import { match as match9 } from "ts-pattern";
425
448
  import { ulid } from "ulid";
426
449
  import * as uuid from "uuid";
@@ -505,20 +528,20 @@ var BaseCrudDialect = class {
505
528
  return value;
506
529
  }
507
530
  // #region common query builders
508
- buildSelectModel(eb, model) {
531
+ buildSelectModel(eb, model, modelAlias) {
509
532
  const modelDef = requireModel(this.schema, model);
510
- let result = eb.selectFrom(model);
533
+ let result = eb.selectFrom(model === modelAlias ? model : `${model} as ${modelAlias}`);
511
534
  let joinBase = modelDef.baseModel;
512
535
  while (joinBase) {
513
- result = this.buildDelegateJoin(model, joinBase, result);
536
+ result = this.buildDelegateJoin(model, modelAlias, joinBase, result);
514
537
  joinBase = requireModel(this.schema, joinBase).baseModel;
515
538
  }
516
539
  return result;
517
540
  }
518
- buildFilterSortTake(model, args, query) {
541
+ buildFilterSortTake(model, args, query, modelAlias) {
519
542
  let result = query;
520
543
  if (args.where) {
521
- result = result.where((eb) => this.buildFilter(eb, model, model, args?.where));
544
+ result = result.where((eb) => this.buildFilter(eb, model, modelAlias, args?.where));
522
545
  }
523
546
  let negateOrderBy = false;
524
547
  const skip = args.skip;
@@ -528,17 +551,17 @@ var BaseCrudDialect = class {
528
551
  take = -take;
529
552
  }
530
553
  result = this.buildSkipTake(result, skip, take);
531
- result = this.buildOrderBy(result, model, model, args.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
554
+ result = this.buildOrderBy(result, model, modelAlias, args.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
532
555
  if ("distinct" in args && args.distinct) {
533
556
  const distinct = ensureArray(args.distinct);
534
557
  if (this.supportsDistinctOn) {
535
- result = result.distinctOn(distinct.map((f) => sql.ref(`${model}.${f}`)));
558
+ result = result.distinctOn(distinct.map((f) => sql.ref(`${modelAlias}.${f}`)));
536
559
  } else {
537
560
  throw new QueryError(`"distinct" is not supported by "${this.schema.provider.type}" provider`);
538
561
  }
539
562
  }
540
563
  if (args.cursor) {
541
- result = this.buildCursorFilter(model, result, args.cursor, args.orderBy, negateOrderBy);
564
+ result = this.buildCursorFilter(model, result, args.cursor, args.orderBy, negateOrderBy, modelAlias);
542
565
  }
543
566
  return result;
544
567
  }
@@ -579,11 +602,12 @@ var BaseCrudDialect = class {
579
602
  }
580
603
  return result;
581
604
  }
582
- buildCursorFilter(model, query, cursor, orderBy, negateOrderBy) {
605
+ buildCursorFilter(model, query, cursor, orderBy, negateOrderBy, modelAlias) {
583
606
  const _orderBy = orderBy ?? makeDefaultOrderBy(this.schema, model);
584
607
  const orderByItems = ensureArray(_orderBy).flatMap((obj) => Object.entries(obj));
585
608
  const eb = expressionBuilder();
586
- const cursorFilter = this.buildFilter(eb, model, model, cursor);
609
+ const subQueryAlias = `${model}$cursor$sub`;
610
+ const cursorFilter = this.buildFilter(eb, model, subQueryAlias, cursor);
587
611
  let result = query;
588
612
  const filters = [];
589
613
  for (let i = orderByItems.length - 1; i >= 0; i--) {
@@ -592,7 +616,7 @@ var BaseCrudDialect = class {
592
616
  const [field, order] = orderByItems[j];
593
617
  const _order = negateOrderBy ? order === "asc" ? "desc" : "asc" : order;
594
618
  const op = j === i ? _order === "asc" ? ">=" : "<=" : "=";
595
- andFilters.push(eb(eb.ref(`${model}.${field}`), op, eb.selectFrom(model).select(`${model}.${field}`).where(cursorFilter)));
619
+ andFilters.push(eb(eb.ref(`${modelAlias}.${field}`), op, this.buildSelectModel(eb, model, subQueryAlias).select(`${subQueryAlias}.${field}`).where(cursorFilter)));
596
620
  }
597
621
  filters.push(eb.and(andFilters));
598
622
  }
@@ -661,25 +685,26 @@ var BaseCrudDialect = class {
661
685
  }
662
686
  return this.and(eb, ...conditions);
663
687
  }
664
- buildToManyRelationFilter(eb, model, table, field, fieldDef, payload) {
688
+ buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
665
689
  if (payload === null) {
666
- return eb(sql.ref(`${table}.${field}`), "is", null);
690
+ return eb(sql.ref(`${modelAlias}.${field}`), "is", null);
667
691
  }
668
692
  const relationModel = fieldDef.type;
693
+ const relationFilterSelectAlias = `${modelAlias}$${field}$filter`;
669
694
  const buildPkFkWhereRefs = /* @__PURE__ */ __name((eb2) => {
670
695
  const m2m = getManyToManyRelation(this.schema, model, field);
671
696
  if (m2m) {
672
697
  const modelIdField = getIdFields(this.schema, model)[0];
673
698
  const relationIdField = getIdFields(this.schema, relationModel)[0];
674
- 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}`)));
699
+ 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}`)));
675
700
  } else {
676
701
  const relationKeyPairs = getRelationForeignKeyFieldPairs(this.schema, model, field);
677
702
  let result2 = this.true(eb2);
678
703
  for (const { fk, pk } of relationKeyPairs.keyPairs) {
679
704
  if (relationKeyPairs.ownedByModel) {
680
- result2 = this.and(eb2, result2, eb2(sql.ref(`${table}.${fk}`), "=", sql.ref(`${relationModel}.${pk}`)));
705
+ result2 = this.and(eb2, result2, eb2(sql.ref(`${modelAlias}.${fk}`), "=", sql.ref(`${relationFilterSelectAlias}.${pk}`)));
681
706
  } else {
682
- result2 = this.and(eb2, result2, eb2(sql.ref(`${table}.${pk}`), "=", sql.ref(`${relationModel}.${fk}`)));
707
+ result2 = this.and(eb2, result2, eb2(sql.ref(`${modelAlias}.${pk}`), "=", sql.ref(`${relationFilterSelectAlias}.${fk}`)));
683
708
  }
684
709
  }
685
710
  return result2;
@@ -692,15 +717,15 @@ var BaseCrudDialect = class {
692
717
  }
693
718
  switch (key) {
694
719
  case "some": {
695
- 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));
720
+ 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));
696
721
  break;
697
722
  }
698
723
  case "every": {
699
- 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));
724
+ 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));
700
725
  break;
701
726
  }
702
727
  case "none": {
703
- 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));
728
+ 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));
704
729
  break;
705
730
  }
706
731
  }
@@ -943,8 +968,9 @@ var BaseCrudDialect = class {
943
968
  invariant(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
944
969
  const sort = this.negateSort(value._count, negated);
945
970
  result = result.orderBy((eb) => {
946
- let subQuery = this.buildSelectModel(eb, relationModel);
947
- const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, relationModel);
971
+ const subQueryAlias = `${modelAlias}$orderBy$${field}$count`;
972
+ let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
973
+ const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, subQueryAlias);
948
974
  subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(sql.ref(left), "=", sql.ref(right)))));
949
975
  subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
950
976
  return subQuery;
@@ -962,7 +988,7 @@ var BaseCrudDialect = class {
962
988
  });
963
989
  return result;
964
990
  }
965
- buildSelectAllFields(model, query, omit) {
991
+ buildSelectAllFields(model, query, omit, modelAlias) {
966
992
  const modelDef = requireModel(this.schema, model);
967
993
  let result = query;
968
994
  for (const field of Object.keys(modelDef.fields)) {
@@ -972,11 +998,11 @@ var BaseCrudDialect = class {
972
998
  if (omit?.[field] === true) {
973
999
  continue;
974
1000
  }
975
- result = this.buildSelectField(result, model, model, field);
1001
+ result = this.buildSelectField(result, model, modelAlias, field);
976
1002
  }
977
1003
  const descendants = getDelegateDescendantModels(this.schema, model);
978
1004
  for (const subModel of descendants) {
979
- result = this.buildDelegateJoin(model, subModel.name, result);
1005
+ result = this.buildDelegateJoin(model, modelAlias, subModel.name, result);
980
1006
  result = result.select((eb) => {
981
1007
  const jsonObject = {};
982
1008
  for (const field of Object.keys(subModel.fields)) {
@@ -1000,11 +1026,11 @@ var BaseCrudDialect = class {
1000
1026
  return this.buildSelectField(query, fieldDef.originModel, fieldDef.originModel, field);
1001
1027
  }
1002
1028
  }
1003
- buildDelegateJoin(thisModel, otherModel, query) {
1029
+ buildDelegateJoin(thisModel, thisModelAlias, otherModelAlias, query) {
1004
1030
  const idFields = getIdFields(this.schema, thisModel);
1005
- query = query.leftJoin(otherModel, (qb) => {
1031
+ query = query.leftJoin(otherModelAlias, (qb) => {
1006
1032
  for (const idField of idFields) {
1007
- qb = qb.onRef(`${thisModel}.${idField}`, "=", `${otherModel}.${idField}`);
1033
+ qb = qb.onRef(`${thisModelAlias}.${idField}`, "=", `${otherModelAlias}.${idField}`);
1008
1034
  }
1009
1035
  return qb;
1010
1036
  });
@@ -1121,11 +1147,12 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1121
1147
  return qb.leftJoinLateral((eb) => {
1122
1148
  const joinTableName = `${parentName}$${relationField}`;
1123
1149
  let result = eb.selectFrom(`${relationModel} as ${joinTableName}`);
1150
+ const subQueryAlias = `${relationModel}$${relationField}$sub`;
1124
1151
  result = eb.selectFrom(() => {
1125
- let subQuery = this.buildSelectModel(eb, relationModel);
1126
- subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
1152
+ let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
1153
+ subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
1127
1154
  if (payload && typeof payload === "object") {
1128
- subQuery = this.buildFilterSortTake(relationModel, payload, subQuery);
1155
+ subQuery = this.buildFilterSortTake(relationModel, payload, subQuery, subQueryAlias);
1129
1156
  }
1130
1157
  const m2m = getManyToManyRelation(this.schema, model, relationField);
1131
1158
  if (m2m) {
@@ -1133,21 +1160,21 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1133
1160
  const relationIds = getIdFields(this.schema, relationModel);
1134
1161
  invariant2(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1135
1162
  invariant2(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1136
- 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}`)));
1163
+ 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}`)));
1137
1164
  } else {
1138
- const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, relationModel);
1165
+ const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, subQueryAlias);
1139
1166
  subQuery = subQuery.where((eb2) => this.and(eb2, ...joinPairs.map(([left, right]) => eb2(sql2.ref(left), "=", sql2.ref(right)))));
1140
1167
  }
1141
1168
  return subQuery.as(joinTableName);
1142
1169
  });
1143
- result = this.buildRelationObjectSelect(relationModel, relationField, relationFieldDef, result, payload, parentName);
1170
+ result = this.buildRelationObjectSelect(relationModel, joinTableName, relationField, relationFieldDef, result, payload, parentName);
1144
1171
  result = this.buildRelationJoins(relationModel, relationField, result, payload, parentName);
1145
1172
  return result.as(joinTableName);
1146
1173
  }, (join) => join.onTrue());
1147
1174
  }
1148
- buildRelationObjectSelect(relationModel, relationField, relationFieldDef, qb, payload, parentName) {
1175
+ buildRelationObjectSelect(relationModel, relationModelAlias, relationField, relationFieldDef, qb, payload, parentName) {
1149
1176
  qb = qb.select((eb) => {
1150
- const objArgs = this.buildRelationObjectArgs(relationModel, relationField, eb, payload, parentName);
1177
+ const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias, relationField, eb, payload, parentName);
1151
1178
  if (relationFieldDef.array) {
1152
1179
  return eb.fn.coalesce(sql2`jsonb_agg(jsonb_build_object(${sql2.join(objArgs)}))`, sql2`'[]'::jsonb`).as("$j");
1153
1180
  } else {
@@ -1156,7 +1183,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1156
1183
  });
1157
1184
  return qb;
1158
1185
  }
1159
- buildRelationObjectArgs(relationModel, relationField, eb, payload, parentAlias) {
1186
+ buildRelationObjectArgs(relationModel, relationModelAlias, relationField, eb, payload, parentAlias) {
1160
1187
  const relationModelDef = requireModel(this.schema, relationModel);
1161
1188
  const objArgs = [];
1162
1189
  const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
@@ -1169,7 +1196,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1169
1196
  if (payload === true || !payload.select) {
1170
1197
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
1171
1198
  sql2.lit(field),
1172
- this.fieldRef(relationModel, field, eb, void 0, false)
1199
+ this.fieldRef(relationModel, field, eb, relationModelAlias, false)
1173
1200
  ]).flatMap((v) => v));
1174
1201
  } else if (payload.select) {
1175
1202
  objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
@@ -1285,10 +1312,11 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1285
1312
  const relationModelDef = requireModel(this.schema, relationModel);
1286
1313
  const subQueryName = `${parentAlias}$${relationField}`;
1287
1314
  let tbl = eb.selectFrom(() => {
1288
- let subQuery = this.buildSelectModel(eb, relationModel);
1289
- subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
1315
+ const subQueryAlias = `${parentAlias}$${relationField}$sub`;
1316
+ let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
1317
+ subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
1290
1318
  if (payload && typeof payload === "object") {
1291
- subQuery = this.buildFilterSortTake(relationModel, payload, subQuery);
1319
+ subQuery = this.buildFilterSortTake(relationModel, payload, subQuery, subQueryAlias);
1292
1320
  }
1293
1321
  const m2m = getManyToManyRelation(this.schema, model, relationField);
1294
1322
  if (m2m) {
@@ -1296,14 +1324,14 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1296
1324
  const relationIds = getIdFields(this.schema, relationModel);
1297
1325
  invariant3(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1298
1326
  invariant3(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1299
- 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}`)));
1327
+ 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}`)));
1300
1328
  } else {
1301
1329
  const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
1302
1330
  keyPairs.forEach(({ fk, pk }) => {
1303
1331
  if (ownedByModel) {
1304
- subQuery = subQuery.whereRef(`${relationModel}.${pk}`, "=", `${parentAlias}.${fk}`);
1332
+ subQuery = subQuery.whereRef(`${subQueryAlias}.${pk}`, "=", `${parentAlias}.${fk}`);
1305
1333
  } else {
1306
- subQuery = subQuery.whereRef(`${relationModel}.${fk}`, "=", `${parentAlias}.${pk}`);
1334
+ subQuery = subQuery.whereRef(`${subQueryAlias}.${fk}`, "=", `${parentAlias}.${pk}`);
1307
1335
  }
1308
1336
  });
1309
1337
  }
@@ -2729,14 +2757,14 @@ var BaseOperationHandler = class {
2729
2757
  return this.executeQueryTakeFirst(kysely, query, "exists");
2730
2758
  }
2731
2759
  async read(kysely, model, args) {
2732
- let query = this.dialect.buildSelectModel(expressionBuilder3(), model);
2760
+ let query = this.dialect.buildSelectModel(expressionBuilder3(), model, model);
2733
2761
  if (args) {
2734
- query = this.dialect.buildFilterSortTake(model, args, query);
2762
+ query = this.dialect.buildFilterSortTake(model, args, query, model);
2735
2763
  }
2736
2764
  if (args && "select" in args && args.select) {
2737
2765
  query = this.buildFieldSelection(model, query, args.select, model);
2738
2766
  } else {
2739
- query = this.dialect.buildSelectAllFields(model, query, args?.omit);
2767
+ query = this.dialect.buildSelectAllFields(model, query, args?.omit, model);
2740
2768
  }
2741
2769
  if (args && "include" in args && args.include) {
2742
2770
  query = this.buildFieldSelection(model, query, args.include, model);
@@ -2754,11 +2782,7 @@ var BaseOperationHandler = class {
2754
2782
  const r = await kysely.getExecutor().executeQuery(compiled, queryId);
2755
2783
  result = r.rows;
2756
2784
  } catch (err) {
2757
- let message = `Failed to execute query: ${err}, sql: ${compiled.sql}`;
2758
- if (this.options.debug) {
2759
- message += `, parameters:
2760
- ${compiled.parameters.map((p) => inspect(p)).join("\n")}`;
2761
- }
2785
+ const message = `Failed to execute query: ${err}, sql: ${compiled.sql}`;
2762
2786
  throw new QueryError(message, err);
2763
2787
  }
2764
2788
  return result;
@@ -2926,7 +2950,12 @@ ${compiled.parameters.map((p) => inspect(p)).join("\n")}`;
2926
2950
  field: rightField,
2927
2951
  entity: rightEntity
2928
2952
  }
2929
- ].sort((a, b) => a.model.localeCompare(b.model));
2953
+ ].sort((a, b) => (
2954
+ // the implement m2m join table's "A", "B" fk fields' order is determined
2955
+ // by model name's sort order, and when identical (for self-relations),
2956
+ // field name's sort order
2957
+ a.model !== b.model ? a.model.localeCompare(b.model) : a.field.localeCompare(b.field)
2958
+ ));
2930
2959
  const firstIds = getIdFields(this.schema, sortedRecords[0].model);
2931
2960
  const secondIds = getIdFields(this.schema, sortedRecords[1].model);
2932
2961
  invariant7(firstIds.length === 1, "many-to-many relation must have exactly one id field");
@@ -3431,7 +3460,7 @@ ${compiled.parameters.map((p) => inspect(p)).join("\n")}`;
3431
3460
  } else {
3432
3461
  query = query.where((eb) => eb(eb.refTuple(
3433
3462
  ...this.buildIdFieldRefs(kysely, model)
3434
- ), "in", this.dialect.buildSelectModel(eb, filterModel).where(this.dialect.buildFilter(eb, filterModel, filterModel, where)).select(this.buildIdFieldRefs(kysely, filterModel)).$if(limit !== void 0, (qb) => qb.limit(limit))));
3463
+ ), "in", this.dialect.buildSelectModel(eb, filterModel, filterModel).where(this.dialect.buildFilter(eb, filterModel, filterModel, where)).select(this.buildIdFieldRefs(kysely, filterModel)).$if(limit !== void 0, (qb) => qb.limit(limit))));
3435
3464
  }
3436
3465
  query = query.modifyEnd(this.makeContextComment({
3437
3466
  model,
@@ -3849,7 +3878,7 @@ ${compiled.parameters.map((p) => inspect(p)).join("\n")}`;
3849
3878
  } else {
3850
3879
  query = query.where((eb) => eb(eb.refTuple(
3851
3880
  ...this.buildIdFieldRefs(kysely, model)
3852
- ), "in", this.dialect.buildSelectModel(eb, filterModel).where((eb2) => this.dialect.buildFilter(eb2, filterModel, filterModel, where)).select(this.buildIdFieldRefs(kysely, filterModel)).$if(limit !== void 0, (qb) => qb.limit(limit))));
3881
+ ), "in", this.dialect.buildSelectModel(eb, filterModel, filterModel).where((eb2) => this.dialect.buildFilter(eb2, filterModel, filterModel, where)).select(this.buildIdFieldRefs(kysely, filterModel)).$if(limit !== void 0, (qb) => qb.limit(limit))));
3853
3882
  }
3854
3883
  await this.processDelegateRelationDelete(kysely, modelDef, where, limit);
3855
3884
  query = query.modifyEnd(this.makeContextComment({
@@ -3985,7 +4014,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
3985
4014
  const normalizedArgs = this.normalizeArgs(args);
3986
4015
  const parsedArgs = this.inputValidator.validateAggregateArgs(this.model, normalizedArgs);
3987
4016
  let query = this.kysely.selectFrom((eb) => {
3988
- let subQuery = this.dialect.buildSelectModel(eb, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
4017
+ let subQuery = this.dialect.buildSelectModel(eb, this.model, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
3989
4018
  const selectedFields = [];
3990
4019
  for (const [key, value] of Object.entries(parsedArgs)) {
3991
4020
  if (key.startsWith("_") && value && typeof value === "object") {
@@ -4095,7 +4124,7 @@ var CountOperationHandler = class extends BaseOperationHandler {
4095
4124
  const parsedArgs = this.inputValidator.validateCountArgs(this.model, normalizedArgs);
4096
4125
  const subQueryName = "$sub";
4097
4126
  let query = this.kysely.selectFrom((eb) => {
4098
- let subQuery = this.dialect.buildSelectModel(eb, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
4127
+ let subQuery = this.dialect.buildSelectModel(eb, this.model, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
4099
4128
  if (parsedArgs?.select && typeof parsedArgs.select === "object") {
4100
4129
  for (const [key, value] of Object.entries(parsedArgs.select)) {
4101
4130
  if (key !== "_all" && value === true) {
@@ -5598,7 +5627,6 @@ __name(performanceNow, "performanceNow");
5598
5627
  // src/client/executor/zenstack-query-executor.ts
5599
5628
  import { AndNode as AndNode2, DefaultQueryExecutor, DeleteQueryNode as DeleteQueryNode2, InsertQueryNode as InsertQueryNode2, ReturningNode as ReturningNode3, SelectionNode as SelectionNode4, UpdateQueryNode as UpdateQueryNode2, WhereNode as WhereNode3 } from "kysely";
5600
5629
  import { nanoid as nanoid2 } from "nanoid";
5601
- import { inspect as inspect2 } from "util";
5602
5630
  import { match as match16 } from "ts-pattern";
5603
5631
 
5604
5632
  // src/client/executor/name-mapper.ts
@@ -5906,11 +5934,7 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends DefaultQueryExe
5906
5934
  };
5907
5935
  });
5908
5936
  } catch (err) {
5909
- let message = `Failed to execute query: ${err}, sql: ${compiled.sql}`;
5910
- if (this.options.debug) {
5911
- message += `, parameters:
5912
- ${compiled.parameters.map((p) => inspect2(p)).join("\n")}`;
5913
- }
5937
+ const message = `Failed to execute query: ${err}, sql: ${compiled.sql}`;
5914
5938
  throw new QueryError(message, err);
5915
5939
  }
5916
5940
  }