@zenstackhq/runtime 3.0.0-alpha.28 → 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.
@@ -531,8 +531,8 @@ declare abstract class BaseCrudDialect<Schema extends SchemaDef> {
531
531
  protected readonly options: ClientOptions<Schema>;
532
532
  constructor(schema: Schema, options: ClientOptions<Schema>);
533
533
  transformPrimitive(value: unknown, _type: BuiltinType, _forArrayField: boolean): unknown;
534
- buildSelectModel(eb: ExpressionBuilder<any, any>, model: string): SelectQueryBuilder<any, any, {}>;
535
- buildFilterSortTake(model: GetModels<Schema>, args: FindArgs<Schema, GetModels<Schema>, true>, query: SelectQueryBuilder<any, any, {}>): SelectQueryBuilder<any, any, {}>;
534
+ buildSelectModel(eb: ExpressionBuilder<any, any>, model: string, modelAlias: string): SelectQueryBuilder<any, any, {}>;
535
+ buildFilterSortTake(model: GetModels<Schema>, args: FindArgs<Schema, GetModels<Schema>, true>, query: SelectQueryBuilder<any, any, {}>, modelAlias: string): SelectQueryBuilder<any, any, {}>;
536
536
  buildFilter(eb: ExpressionBuilder<any, any>, model: string, modelAlias: string, where: boolean | object | undefined): Expression<SqlBool>;
537
537
  private buildCursorFilter;
538
538
  private isLogicalCombinator;
@@ -552,9 +552,9 @@ declare abstract class BaseCrudDialect<Schema extends SchemaDef> {
552
552
  private buildBytesFilter;
553
553
  private buildEnumFilter;
554
554
  buildOrderBy(query: SelectQueryBuilder<any, any, any>, model: string, modelAlias: string, orderBy: OrArray<OrderBy<Schema, GetModels<Schema>, boolean, boolean>> | undefined, useDefaultIfEmpty: boolean, negated: boolean): SelectQueryBuilder<any, any, any>;
555
- buildSelectAllFields(model: string, query: SelectQueryBuilder<any, any, any>, omit?: Record<string, boolean | undefined>): SelectQueryBuilder<any, any, any>;
555
+ buildSelectAllFields(model: string, query: SelectQueryBuilder<any, any, any>, omit: Record<string, boolean | undefined> | undefined, modelAlias: string): SelectQueryBuilder<any, any, any>;
556
556
  buildSelectField(query: SelectQueryBuilder<any, any, any>, model: string, modelAlias: string, field: string): SelectQueryBuilder<any, any, any>;
557
- buildDelegateJoin(thisModel: string, otherModel: string, query: SelectQueryBuilder<any, any, any>): SelectQueryBuilder<any, any, any>;
557
+ buildDelegateJoin(thisModel: string, thisModelAlias: string, otherModelAlias: string, query: SelectQueryBuilder<any, any, any>): SelectQueryBuilder<any, any, any>;
558
558
  buildCountJson(model: string, eb: ExpressionBuilder<any, any>, parentAlias: string, payload: any): ExpressionWrapper<any, any, unknown>;
559
559
  private negateSort;
560
560
  true(eb: ExpressionBuilder<any, any>): Expression<SqlBool>;
@@ -531,8 +531,8 @@ declare abstract class BaseCrudDialect<Schema extends SchemaDef> {
531
531
  protected readonly options: ClientOptions<Schema>;
532
532
  constructor(schema: Schema, options: ClientOptions<Schema>);
533
533
  transformPrimitive(value: unknown, _type: BuiltinType, _forArrayField: boolean): unknown;
534
- buildSelectModel(eb: ExpressionBuilder<any, any>, model: string): SelectQueryBuilder<any, any, {}>;
535
- buildFilterSortTake(model: GetModels<Schema>, args: FindArgs<Schema, GetModels<Schema>, true>, query: SelectQueryBuilder<any, any, {}>): SelectQueryBuilder<any, any, {}>;
534
+ buildSelectModel(eb: ExpressionBuilder<any, any>, model: string, modelAlias: string): SelectQueryBuilder<any, any, {}>;
535
+ buildFilterSortTake(model: GetModels<Schema>, args: FindArgs<Schema, GetModels<Schema>, true>, query: SelectQueryBuilder<any, any, {}>, modelAlias: string): SelectQueryBuilder<any, any, {}>;
536
536
  buildFilter(eb: ExpressionBuilder<any, any>, model: string, modelAlias: string, where: boolean | object | undefined): Expression<SqlBool>;
537
537
  private buildCursorFilter;
538
538
  private isLogicalCombinator;
@@ -552,9 +552,9 @@ declare abstract class BaseCrudDialect<Schema extends SchemaDef> {
552
552
  private buildBytesFilter;
553
553
  private buildEnumFilter;
554
554
  buildOrderBy(query: SelectQueryBuilder<any, any, any>, model: string, modelAlias: string, orderBy: OrArray<OrderBy<Schema, GetModels<Schema>, boolean, boolean>> | undefined, useDefaultIfEmpty: boolean, negated: boolean): SelectQueryBuilder<any, any, any>;
555
- buildSelectAllFields(model: string, query: SelectQueryBuilder<any, any, any>, omit?: Record<string, boolean | undefined>): SelectQueryBuilder<any, any, any>;
555
+ buildSelectAllFields(model: string, query: SelectQueryBuilder<any, any, any>, omit: Record<string, boolean | undefined> | undefined, modelAlias: string): SelectQueryBuilder<any, any, any>;
556
556
  buildSelectField(query: SelectQueryBuilder<any, any, any>, model: string, modelAlias: string, field: string): SelectQueryBuilder<any, any, any>;
557
- buildDelegateJoin(thisModel: string, otherModel: string, query: SelectQueryBuilder<any, any, any>): SelectQueryBuilder<any, any, any>;
557
+ buildDelegateJoin(thisModel: string, thisModelAlias: string, otherModelAlias: string, query: SelectQueryBuilder<any, any, any>): SelectQueryBuilder<any, any, any>;
558
558
  buildCountJson(model: string, eb: ExpressionBuilder<any, any>, parentAlias: string, payload: any): ExpressionWrapper<any, any, unknown>;
559
559
  private negateSort;
560
560
  true(eb: ExpressionBuilder<any, any>): Expression<SqlBool>;
package/dist/index.cjs CHANGED
@@ -321,7 +321,9 @@ function buildFieldRef(schema, model, field, options, eb, modelAlias, inlineComp
321
321
  if (!computer) {
322
322
  throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
323
323
  }
324
- return computer(eb);
324
+ return computer(eb, {
325
+ currentModel: modelAlias
326
+ });
325
327
  }
326
328
  }
327
329
  __name(buildFieldRef, "buildFieldRef");
@@ -372,11 +374,33 @@ function getManyToManyRelation(schema, model, field) {
372
374
  model,
373
375
  fieldDef.type
374
376
  ].sort();
377
+ let orderedFK;
378
+ if (model !== fieldDef.type) {
379
+ orderedFK = sortedModelNames[0] === model ? [
380
+ "A",
381
+ "B"
382
+ ] : [
383
+ "B",
384
+ "A"
385
+ ];
386
+ } else {
387
+ const sortedFieldNames = [
388
+ field,
389
+ oppositeFieldDef.name
390
+ ].sort();
391
+ orderedFK = sortedFieldNames[0] === field ? [
392
+ "A",
393
+ "B"
394
+ ] : [
395
+ "B",
396
+ "A"
397
+ ];
398
+ }
375
399
  return {
376
- parentFkName: sortedModelNames[0] === model ? "A" : "B",
400
+ parentFkName: orderedFK[0],
377
401
  otherModel: fieldDef.type,
378
402
  otherField: fieldDef.relation.opposite,
379
- otherFkName: sortedModelNames[0] === fieldDef.type ? "A" : "B",
403
+ otherFkName: orderedFK[1],
380
404
  joinTable: fieldDef.relation.name ? `_${fieldDef.relation.name}` : `_${sortedModelNames[0]}To${sortedModelNames[1]}`
381
405
  };
382
406
  } else {
@@ -539,20 +563,20 @@ var BaseCrudDialect = class {
539
563
  return value;
540
564
  }
541
565
  // #region common query builders
542
- buildSelectModel(eb, model) {
566
+ buildSelectModel(eb, model, modelAlias) {
543
567
  const modelDef = requireModel(this.schema, model);
544
- let result = eb.selectFrom(model);
568
+ let result = eb.selectFrom(model === modelAlias ? model : `${model} as ${modelAlias}`);
545
569
  let joinBase = modelDef.baseModel;
546
570
  while (joinBase) {
547
- result = this.buildDelegateJoin(model, joinBase, result);
571
+ result = this.buildDelegateJoin(model, modelAlias, joinBase, result);
548
572
  joinBase = requireModel(this.schema, joinBase).baseModel;
549
573
  }
550
574
  return result;
551
575
  }
552
- buildFilterSortTake(model, args, query) {
576
+ buildFilterSortTake(model, args, query, modelAlias) {
553
577
  let result = query;
554
578
  if (args.where) {
555
- result = result.where((eb) => this.buildFilter(eb, model, model, args?.where));
579
+ result = result.where((eb) => this.buildFilter(eb, model, modelAlias, args?.where));
556
580
  }
557
581
  let negateOrderBy = false;
558
582
  const skip = args.skip;
@@ -562,17 +586,17 @@ var BaseCrudDialect = class {
562
586
  take = -take;
563
587
  }
564
588
  result = this.buildSkipTake(result, skip, take);
565
- result = this.buildOrderBy(result, model, model, args.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
589
+ result = this.buildOrderBy(result, model, modelAlias, args.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
566
590
  if ("distinct" in args && args.distinct) {
567
591
  const distinct = ensureArray(args.distinct);
568
592
  if (this.supportsDistinctOn) {
569
- result = result.distinctOn(distinct.map((f) => import_kysely.sql.ref(`${model}.${f}`)));
593
+ result = result.distinctOn(distinct.map((f) => import_kysely.sql.ref(`${modelAlias}.${f}`)));
570
594
  } else {
571
595
  throw new QueryError(`"distinct" is not supported by "${this.schema.provider.type}" provider`);
572
596
  }
573
597
  }
574
598
  if (args.cursor) {
575
- result = this.buildCursorFilter(model, result, args.cursor, args.orderBy, negateOrderBy);
599
+ result = this.buildCursorFilter(model, result, args.cursor, args.orderBy, negateOrderBy, modelAlias);
576
600
  }
577
601
  return result;
578
602
  }
@@ -613,11 +637,12 @@ var BaseCrudDialect = class {
613
637
  }
614
638
  return result;
615
639
  }
616
- buildCursorFilter(model, query, cursor, orderBy, negateOrderBy) {
640
+ buildCursorFilter(model, query, cursor, orderBy, negateOrderBy, modelAlias) {
617
641
  const _orderBy = orderBy ?? makeDefaultOrderBy(this.schema, model);
618
642
  const orderByItems = ensureArray(_orderBy).flatMap((obj) => Object.entries(obj));
619
643
  const eb = (0, import_kysely.expressionBuilder)();
620
- const cursorFilter = this.buildFilter(eb, model, model, cursor);
644
+ const subQueryAlias = `${model}$cursor$sub`;
645
+ const cursorFilter = this.buildFilter(eb, model, subQueryAlias, cursor);
621
646
  let result = query;
622
647
  const filters = [];
623
648
  for (let i = orderByItems.length - 1; i >= 0; i--) {
@@ -626,7 +651,7 @@ var BaseCrudDialect = class {
626
651
  const [field, order] = orderByItems[j];
627
652
  const _order = negateOrderBy ? order === "asc" ? "desc" : "asc" : order;
628
653
  const op = j === i ? _order === "asc" ? ">=" : "<=" : "=";
629
- andFilters.push(eb(eb.ref(`${model}.${field}`), op, eb.selectFrom(model).select(`${model}.${field}`).where(cursorFilter)));
654
+ andFilters.push(eb(eb.ref(`${modelAlias}.${field}`), op, this.buildSelectModel(eb, model, subQueryAlias).select(`${subQueryAlias}.${field}`).where(cursorFilter)));
630
655
  }
631
656
  filters.push(eb.and(andFilters));
632
657
  }
@@ -695,25 +720,26 @@ var BaseCrudDialect = class {
695
720
  }
696
721
  return this.and(eb, ...conditions);
697
722
  }
698
- buildToManyRelationFilter(eb, model, table, field, fieldDef, payload) {
723
+ buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
699
724
  if (payload === null) {
700
- return eb(import_kysely.sql.ref(`${table}.${field}`), "is", null);
725
+ return eb(import_kysely.sql.ref(`${modelAlias}.${field}`), "is", null);
701
726
  }
702
727
  const relationModel = fieldDef.type;
728
+ const relationFilterSelectAlias = `${modelAlias}$${field}$filter`;
703
729
  const buildPkFkWhereRefs = /* @__PURE__ */ __name((eb2) => {
704
730
  const m2m = getManyToManyRelation(this.schema, model, field);
705
731
  if (m2m) {
706
732
  const modelIdField = getIdFields(this.schema, model)[0];
707
733
  const relationIdField = getIdFields(this.schema, relationModel)[0];
708
- return eb2(import_kysely.sql.ref(`${relationModel}.${relationIdField}`), "in", eb2.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(import_kysely.sql.ref(`${m2m.joinTable}.${m2m.parentFkName}`), "=", import_kysely.sql.ref(`${table}.${modelIdField}`)));
734
+ return eb2(import_kysely.sql.ref(`${relationFilterSelectAlias}.${relationIdField}`), "in", eb2.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(import_kysely.sql.ref(`${m2m.joinTable}.${m2m.parentFkName}`), "=", import_kysely.sql.ref(`${modelAlias}.${modelIdField}`)));
709
735
  } else {
710
736
  const relationKeyPairs = getRelationForeignKeyFieldPairs(this.schema, model, field);
711
737
  let result2 = this.true(eb2);
712
738
  for (const { fk, pk } of relationKeyPairs.keyPairs) {
713
739
  if (relationKeyPairs.ownedByModel) {
714
- result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${table}.${fk}`), "=", import_kysely.sql.ref(`${relationModel}.${pk}`)));
740
+ result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${modelAlias}.${fk}`), "=", import_kysely.sql.ref(`${relationFilterSelectAlias}.${pk}`)));
715
741
  } else {
716
- result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${table}.${pk}`), "=", import_kysely.sql.ref(`${relationModel}.${fk}`)));
742
+ result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${modelAlias}.${pk}`), "=", import_kysely.sql.ref(`${relationFilterSelectAlias}.${fk}`)));
717
743
  }
718
744
  }
719
745
  return result2;
@@ -726,15 +752,15 @@ var BaseCrudDialect = class {
726
752
  }
727
753
  switch (key) {
728
754
  case "some": {
729
- 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));
755
+ 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));
730
756
  break;
731
757
  }
732
758
  case "every": {
733
- 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));
759
+ 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));
734
760
  break;
735
761
  }
736
762
  case "none": {
737
- 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));
763
+ 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));
738
764
  break;
739
765
  }
740
766
  }
@@ -977,8 +1003,9 @@ var BaseCrudDialect = class {
977
1003
  (0, import_common_helpers.invariant)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
978
1004
  const sort = this.negateSort(value._count, negated);
979
1005
  result = result.orderBy((eb) => {
980
- let subQuery = this.buildSelectModel(eb, relationModel);
981
- const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, relationModel);
1006
+ const subQueryAlias = `${modelAlias}$orderBy$${field}$count`;
1007
+ let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
1008
+ const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, subQueryAlias);
982
1009
  subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely.sql.ref(left), "=", import_kysely.sql.ref(right)))));
983
1010
  subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
984
1011
  return subQuery;
@@ -996,7 +1023,7 @@ var BaseCrudDialect = class {
996
1023
  });
997
1024
  return result;
998
1025
  }
999
- buildSelectAllFields(model, query, omit) {
1026
+ buildSelectAllFields(model, query, omit, modelAlias) {
1000
1027
  const modelDef = requireModel(this.schema, model);
1001
1028
  let result = query;
1002
1029
  for (const field of Object.keys(modelDef.fields)) {
@@ -1006,11 +1033,11 @@ var BaseCrudDialect = class {
1006
1033
  if (omit?.[field] === true) {
1007
1034
  continue;
1008
1035
  }
1009
- result = this.buildSelectField(result, model, model, field);
1036
+ result = this.buildSelectField(result, model, modelAlias, field);
1010
1037
  }
1011
1038
  const descendants = getDelegateDescendantModels(this.schema, model);
1012
1039
  for (const subModel of descendants) {
1013
- result = this.buildDelegateJoin(model, subModel.name, result);
1040
+ result = this.buildDelegateJoin(model, modelAlias, subModel.name, result);
1014
1041
  result = result.select((eb) => {
1015
1042
  const jsonObject = {};
1016
1043
  for (const field of Object.keys(subModel.fields)) {
@@ -1034,11 +1061,11 @@ var BaseCrudDialect = class {
1034
1061
  return this.buildSelectField(query, fieldDef.originModel, fieldDef.originModel, field);
1035
1062
  }
1036
1063
  }
1037
- buildDelegateJoin(thisModel, otherModel, query) {
1064
+ buildDelegateJoin(thisModel, thisModelAlias, otherModelAlias, query) {
1038
1065
  const idFields = getIdFields(this.schema, thisModel);
1039
- query = query.leftJoin(otherModel, (qb) => {
1066
+ query = query.leftJoin(otherModelAlias, (qb) => {
1040
1067
  for (const idField of idFields) {
1041
- qb = qb.onRef(`${thisModel}.${idField}`, "=", `${otherModel}.${idField}`);
1068
+ qb = qb.onRef(`${thisModelAlias}.${idField}`, "=", `${otherModelAlias}.${idField}`);
1042
1069
  }
1043
1070
  return qb;
1044
1071
  });
@@ -1155,11 +1182,12 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1155
1182
  return qb.leftJoinLateral((eb) => {
1156
1183
  const joinTableName = `${parentName}$${relationField}`;
1157
1184
  let result = eb.selectFrom(`${relationModel} as ${joinTableName}`);
1185
+ const subQueryAlias = `${relationModel}$${relationField}$sub`;
1158
1186
  result = eb.selectFrom(() => {
1159
- let subQuery = this.buildSelectModel(eb, relationModel);
1160
- subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
1187
+ let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
1188
+ subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
1161
1189
  if (payload && typeof payload === "object") {
1162
- subQuery = this.buildFilterSortTake(relationModel, payload, subQuery);
1190
+ subQuery = this.buildFilterSortTake(relationModel, payload, subQuery, subQueryAlias);
1163
1191
  }
1164
1192
  const m2m = getManyToManyRelation(this.schema, model, relationField);
1165
1193
  if (m2m) {
@@ -1167,21 +1195,21 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1167
1195
  const relationIds = getIdFields(this.schema, relationModel);
1168
1196
  (0, import_common_helpers2.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1169
1197
  (0, import_common_helpers2.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1170
- 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}`)));
1198
+ 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}`)));
1171
1199
  } else {
1172
- const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, relationModel);
1200
+ const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, subQueryAlias);
1173
1201
  subQuery = subQuery.where((eb2) => this.and(eb2, ...joinPairs.map(([left, right]) => eb2(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right)))));
1174
1202
  }
1175
1203
  return subQuery.as(joinTableName);
1176
1204
  });
1177
- result = this.buildRelationObjectSelect(relationModel, relationField, relationFieldDef, result, payload, parentName);
1205
+ result = this.buildRelationObjectSelect(relationModel, joinTableName, relationField, relationFieldDef, result, payload, parentName);
1178
1206
  result = this.buildRelationJoins(relationModel, relationField, result, payload, parentName);
1179
1207
  return result.as(joinTableName);
1180
1208
  }, (join) => join.onTrue());
1181
1209
  }
1182
- buildRelationObjectSelect(relationModel, relationField, relationFieldDef, qb, payload, parentName) {
1210
+ buildRelationObjectSelect(relationModel, relationModelAlias, relationField, relationFieldDef, qb, payload, parentName) {
1183
1211
  qb = qb.select((eb) => {
1184
- const objArgs = this.buildRelationObjectArgs(relationModel, relationField, eb, payload, parentName);
1212
+ const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias, relationField, eb, payload, parentName);
1185
1213
  if (relationFieldDef.array) {
1186
1214
  return eb.fn.coalesce(import_kysely2.sql`jsonb_agg(jsonb_build_object(${import_kysely2.sql.join(objArgs)}))`, import_kysely2.sql`'[]'::jsonb`).as("$j");
1187
1215
  } else {
@@ -1190,7 +1218,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1190
1218
  });
1191
1219
  return qb;
1192
1220
  }
1193
- buildRelationObjectArgs(relationModel, relationField, eb, payload, parentAlias) {
1221
+ buildRelationObjectArgs(relationModel, relationModelAlias, relationField, eb, payload, parentAlias) {
1194
1222
  const relationModelDef = requireModel(this.schema, relationModel);
1195
1223
  const objArgs = [];
1196
1224
  const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
@@ -1203,7 +1231,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1203
1231
  if (payload === true || !payload.select) {
1204
1232
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
1205
1233
  import_kysely2.sql.lit(field),
1206
- this.fieldRef(relationModel, field, eb, void 0, false)
1234
+ this.fieldRef(relationModel, field, eb, relationModelAlias, false)
1207
1235
  ]).flatMap((v) => v));
1208
1236
  } else if (payload.select) {
1209
1237
  objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
@@ -1319,10 +1347,11 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1319
1347
  const relationModelDef = requireModel(this.schema, relationModel);
1320
1348
  const subQueryName = `${parentAlias}$${relationField}`;
1321
1349
  let tbl = eb.selectFrom(() => {
1322
- let subQuery = this.buildSelectModel(eb, relationModel);
1323
- subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
1350
+ const subQueryAlias = `${parentAlias}$${relationField}$sub`;
1351
+ let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
1352
+ subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
1324
1353
  if (payload && typeof payload === "object") {
1325
- subQuery = this.buildFilterSortTake(relationModel, payload, subQuery);
1354
+ subQuery = this.buildFilterSortTake(relationModel, payload, subQuery, subQueryAlias);
1326
1355
  }
1327
1356
  const m2m = getManyToManyRelation(this.schema, model, relationField);
1328
1357
  if (m2m) {
@@ -1330,14 +1359,14 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1330
1359
  const relationIds = getIdFields(this.schema, relationModel);
1331
1360
  (0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1332
1361
  (0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1333
- 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}`)));
1362
+ 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}`)));
1334
1363
  } else {
1335
1364
  const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
1336
1365
  keyPairs.forEach(({ fk, pk }) => {
1337
1366
  if (ownedByModel) {
1338
- subQuery = subQuery.whereRef(`${relationModel}.${pk}`, "=", `${parentAlias}.${fk}`);
1367
+ subQuery = subQuery.whereRef(`${subQueryAlias}.${pk}`, "=", `${parentAlias}.${fk}`);
1339
1368
  } else {
1340
- subQuery = subQuery.whereRef(`${relationModel}.${fk}`, "=", `${parentAlias}.${pk}`);
1369
+ subQuery = subQuery.whereRef(`${subQueryAlias}.${fk}`, "=", `${parentAlias}.${pk}`);
1341
1370
  }
1342
1371
  });
1343
1372
  }
@@ -2763,14 +2792,14 @@ var BaseOperationHandler = class {
2763
2792
  return this.executeQueryTakeFirst(kysely, query, "exists");
2764
2793
  }
2765
2794
  async read(kysely, model, args) {
2766
- let query = this.dialect.buildSelectModel((0, import_kysely8.expressionBuilder)(), model);
2795
+ let query = this.dialect.buildSelectModel((0, import_kysely8.expressionBuilder)(), model, model);
2767
2796
  if (args) {
2768
- query = this.dialect.buildFilterSortTake(model, args, query);
2797
+ query = this.dialect.buildFilterSortTake(model, args, query, model);
2769
2798
  }
2770
2799
  if (args && "select" in args && args.select) {
2771
2800
  query = this.buildFieldSelection(model, query, args.select, model);
2772
2801
  } else {
2773
- query = this.dialect.buildSelectAllFields(model, query, args?.omit);
2802
+ query = this.dialect.buildSelectAllFields(model, query, args?.omit, model);
2774
2803
  }
2775
2804
  if (args && "include" in args && args.include) {
2776
2805
  query = this.buildFieldSelection(model, query, args.include, model);
@@ -2956,7 +2985,12 @@ var BaseOperationHandler = class {
2956
2985
  field: rightField,
2957
2986
  entity: rightEntity
2958
2987
  }
2959
- ].sort((a, b) => a.model.localeCompare(b.model));
2988
+ ].sort((a, b) => (
2989
+ // the implement m2m join table's "A", "B" fk fields' order is determined
2990
+ // by model name's sort order, and when identical (for self-relations),
2991
+ // field name's sort order
2992
+ a.model !== b.model ? a.model.localeCompare(b.model) : a.field.localeCompare(b.field)
2993
+ ));
2960
2994
  const firstIds = getIdFields(this.schema, sortedRecords[0].model);
2961
2995
  const secondIds = getIdFields(this.schema, sortedRecords[1].model);
2962
2996
  (0, import_common_helpers8.invariant)(firstIds.length === 1, "many-to-many relation must have exactly one id field");
@@ -3461,7 +3495,7 @@ var BaseOperationHandler = class {
3461
3495
  } else {
3462
3496
  query = query.where((eb) => eb(eb.refTuple(
3463
3497
  ...this.buildIdFieldRefs(kysely, model)
3464
- ), "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))));
3498
+ ), "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))));
3465
3499
  }
3466
3500
  query = query.modifyEnd(this.makeContextComment({
3467
3501
  model,
@@ -3879,7 +3913,7 @@ var BaseOperationHandler = class {
3879
3913
  } else {
3880
3914
  query = query.where((eb) => eb(eb.refTuple(
3881
3915
  ...this.buildIdFieldRefs(kysely, model)
3882
- ), "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))));
3916
+ ), "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))));
3883
3917
  }
3884
3918
  await this.processDelegateRelationDelete(kysely, modelDef, where, limit);
3885
3919
  query = query.modifyEnd(this.makeContextComment({
@@ -4015,7 +4049,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
4015
4049
  const normalizedArgs = this.normalizeArgs(args);
4016
4050
  const parsedArgs = this.inputValidator.validateAggregateArgs(this.model, normalizedArgs);
4017
4051
  let query = this.kysely.selectFrom((eb) => {
4018
- let subQuery = this.dialect.buildSelectModel(eb, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
4052
+ let subQuery = this.dialect.buildSelectModel(eb, this.model, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
4019
4053
  const selectedFields = [];
4020
4054
  for (const [key, value] of Object.entries(parsedArgs)) {
4021
4055
  if (key.startsWith("_") && value && typeof value === "object") {
@@ -4125,7 +4159,7 @@ var CountOperationHandler = class extends BaseOperationHandler {
4125
4159
  const parsedArgs = this.inputValidator.validateCountArgs(this.model, normalizedArgs);
4126
4160
  const subQueryName = "$sub";
4127
4161
  let query = this.kysely.selectFrom((eb) => {
4128
- let subQuery = this.dialect.buildSelectModel(eb, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
4162
+ let subQuery = this.dialect.buildSelectModel(eb, this.model, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
4129
4163
  if (parsedArgs?.select && typeof parsedArgs.select === "object") {
4130
4164
  for (const [key, value] of Object.entries(parsedArgs.select)) {
4131
4165
  if (key !== "_all" && value === true) {