@zenstackhq/runtime 3.0.0-alpha.12 → 3.0.0-alpha.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.
package/dist/index.cjs CHANGED
@@ -49,6 +49,85 @@ var import_ts_pattern19 = require("ts-pattern");
49
49
  var import_kysely9 = require("kysely");
50
50
  var import_ts_pattern9 = require("ts-pattern");
51
51
 
52
+ // src/schema/expression.ts
53
+ var ExpressionUtils = {
54
+ literal: /* @__PURE__ */ __name((value) => {
55
+ return {
56
+ kind: "literal",
57
+ value
58
+ };
59
+ }, "literal"),
60
+ array: /* @__PURE__ */ __name((items) => {
61
+ return {
62
+ kind: "array",
63
+ items
64
+ };
65
+ }, "array"),
66
+ call: /* @__PURE__ */ __name((functionName, args) => {
67
+ return {
68
+ kind: "call",
69
+ function: functionName,
70
+ args
71
+ };
72
+ }, "call"),
73
+ binary: /* @__PURE__ */ __name((left, op, right) => {
74
+ return {
75
+ kind: "binary",
76
+ op,
77
+ left,
78
+ right
79
+ };
80
+ }, "binary"),
81
+ unary: /* @__PURE__ */ __name((op, operand) => {
82
+ return {
83
+ kind: "unary",
84
+ op,
85
+ operand
86
+ };
87
+ }, "unary"),
88
+ field: /* @__PURE__ */ __name((field) => {
89
+ return {
90
+ kind: "field",
91
+ field
92
+ };
93
+ }, "field"),
94
+ member: /* @__PURE__ */ __name((receiver, members) => {
95
+ return {
96
+ kind: "member",
97
+ receiver,
98
+ members
99
+ };
100
+ }, "member"),
101
+ _this: /* @__PURE__ */ __name(() => {
102
+ return {
103
+ kind: "this"
104
+ };
105
+ }, "_this"),
106
+ _null: /* @__PURE__ */ __name(() => {
107
+ return {
108
+ kind: "null"
109
+ };
110
+ }, "_null"),
111
+ and: /* @__PURE__ */ __name((expr2, ...expressions) => {
112
+ return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "&&", exp), expr2);
113
+ }, "and"),
114
+ or: /* @__PURE__ */ __name((expr2, ...expressions) => {
115
+ return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
116
+ }, "or"),
117
+ is: /* @__PURE__ */ __name((value, kind) => {
118
+ return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
119
+ }, "is"),
120
+ isLiteral: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "literal"), "isLiteral"),
121
+ isArray: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "array"), "isArray"),
122
+ isCall: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "call"), "isCall"),
123
+ isNull: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "null"), "isNull"),
124
+ isThis: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "this"), "isThis"),
125
+ isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
126
+ isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
127
+ isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
128
+ isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
129
+ };
130
+
52
131
  // src/client/errors.ts
53
132
  var InputValidationError = class extends Error {
54
133
  static {
@@ -170,6 +249,11 @@ function isRelationField(schema, model, field) {
170
249
  return !!fieldDef.relation;
171
250
  }
172
251
  __name(isRelationField, "isRelationField");
252
+ function isInheritedField(schema, model, field) {
253
+ const fieldDef = requireField(schema, model, field);
254
+ return !!fieldDef.originModel;
255
+ }
256
+ __name(isInheritedField, "isInheritedField");
173
257
  function getUniqueFields(schema, model) {
174
258
  const modelDef = requireModel(schema, model);
175
259
  const result = [];
@@ -322,6 +406,46 @@ function safeJSONStringify(value) {
322
406
  });
323
407
  }
324
408
  __name(safeJSONStringify, "safeJSONStringify");
409
+ function extractFields(object, fields) {
410
+ return fields.reduce((acc, field) => {
411
+ if (field in object) {
412
+ acc[field] = object[field];
413
+ }
414
+ return acc;
415
+ }, {});
416
+ }
417
+ __name(extractFields, "extractFields");
418
+ function extractIdFields(entity, schema, model) {
419
+ const idFields = getIdFields(schema, model);
420
+ return extractFields(entity, idFields);
421
+ }
422
+ __name(extractIdFields, "extractIdFields");
423
+ function getDiscriminatorField(schema, model) {
424
+ const modelDef = requireModel(schema, model);
425
+ const delegateAttr = modelDef.attributes?.find((attr) => attr.name === "@@delegate");
426
+ if (!delegateAttr) {
427
+ return void 0;
428
+ }
429
+ const discriminator = delegateAttr.args?.find((arg) => arg.name === "discriminator");
430
+ if (!discriminator || !ExpressionUtils.isField(discriminator.value)) {
431
+ throw new InternalError(`Discriminator field not defined for model "${model}"`);
432
+ }
433
+ return discriminator.value.field;
434
+ }
435
+ __name(getDiscriminatorField, "getDiscriminatorField");
436
+ function getDelegateDescendantModels(schema, model, collected = /* @__PURE__ */ new Set()) {
437
+ const subModels = Object.values(schema.models).filter((m) => m.baseModel === model);
438
+ subModels.forEach((def) => {
439
+ if (!collected.has(def)) {
440
+ collected.add(def);
441
+ getDelegateDescendantModels(schema, def.name, collected);
442
+ }
443
+ });
444
+ return [
445
+ ...collected
446
+ ];
447
+ }
448
+ __name(getDelegateDescendantModels, "getDelegateDescendantModels");
325
449
 
326
450
  // src/client/crud/operations/base.ts
327
451
  var import_cuid2 = require("@paralleldrive/cuid2");
@@ -358,6 +482,16 @@ var import_common_helpers2 = require("@zenstackhq/common-helpers");
358
482
  var import_kysely2 = require("kysely");
359
483
  var import_ts_pattern2 = require("ts-pattern");
360
484
 
485
+ // src/client/constants.ts
486
+ var CONTEXT_COMMENT_PREFIX = "-- $$context:";
487
+ var NUMERIC_FIELD_TYPES = [
488
+ "Int",
489
+ "Float",
490
+ "BigInt",
491
+ "Decimal"
492
+ ];
493
+ var DELEGATE_JOINED_FIELD_PREFIX = "$delegate$";
494
+
361
495
  // src/client/crud/dialects/base.ts
362
496
  var import_common_helpers = require("@zenstackhq/common-helpers");
363
497
  var import_kysely = require("kysely");
@@ -391,6 +525,17 @@ var BaseCrudDialect = class {
391
525
  transformPrimitive(value, _type, _forArrayField) {
392
526
  return value;
393
527
  }
528
+ // #region common query builders
529
+ buildSelectModel(eb, model) {
530
+ const modelDef = requireModel(this.schema, model);
531
+ let result = eb.selectFrom(model);
532
+ let joinBase = modelDef.baseModel;
533
+ while (joinBase) {
534
+ result = this.buildDelegateJoin(model, joinBase, result);
535
+ joinBase = requireModel(this.schema, joinBase).baseModel;
536
+ }
537
+ return result;
538
+ }
394
539
  buildFilter(eb, model, modelAlias, where) {
395
540
  if (where === true || where === void 0) {
396
541
  return this.true(eb);
@@ -414,10 +559,13 @@ var BaseCrudDialect = class {
414
559
  const fieldDef = requireField(this.schema, model, key);
415
560
  if (fieldDef.relation) {
416
561
  result = this.and(eb, result, this.buildRelationFilter(eb, model, modelAlias, key, fieldDef, payload));
417
- } else if (fieldDef.array) {
418
- result = this.and(eb, result, this.buildArrayFilter(eb, model, modelAlias, key, fieldDef, payload));
419
562
  } else {
420
- result = this.and(eb, result, this.buildPrimitiveFilter(eb, model, modelAlias, key, fieldDef, payload));
563
+ const fieldRef = buildFieldRef(this.schema, fieldDef.originModel ?? model, key, this.options, eb, fieldDef.originModel ?? modelAlias);
564
+ if (fieldDef.array) {
565
+ result = this.and(eb, result, this.buildArrayFilter(eb, fieldRef, fieldDef, payload));
566
+ } else {
567
+ result = this.and(eb, result, this.buildPrimitiveFilter(eb, fieldRef, fieldDef, payload));
568
+ }
421
569
  }
422
570
  }
423
571
  if ("$expr" in _where && typeof _where["$expr"] === "function") {
@@ -435,19 +583,26 @@ var BaseCrudDialect = class {
435
583
  return this.buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload);
436
584
  }
437
585
  }
438
- buildToOneRelationFilter(eb, model, table, field, fieldDef, payload) {
586
+ buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
439
587
  if (payload === null) {
440
588
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, model, field);
441
- if (ownedByModel) {
442
- return this.and(eb, ...keyPairs.map(({ fk }) => eb(import_kysely.sql.ref(`${table}.${fk}`), "is", null)));
589
+ if (ownedByModel && !fieldDef.originModel) {
590
+ return this.and(eb, ...keyPairs.map(({ fk }) => eb(import_kysely.sql.ref(`${modelAlias}.${fk}`), "is", null)));
443
591
  } else {
444
- return this.buildToOneRelationFilter(eb, model, table, field, fieldDef, {
592
+ return this.buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, {
445
593
  is: null
446
594
  });
447
595
  }
448
596
  }
449
- const joinAlias = `${table}$${field}`;
450
- const joinPairs = buildJoinPairs(this.schema, model, table, field, joinAlias);
597
+ const joinAlias = `${modelAlias}$${field}`;
598
+ const joinPairs = buildJoinPairs(
599
+ this.schema,
600
+ model,
601
+ // if field is from a base, use the base model to join
602
+ fieldDef.originModel ?? modelAlias,
603
+ field,
604
+ joinAlias
605
+ );
451
606
  const filterResultField = `${field}$filter`;
452
607
  const joinSelect = eb.selectFrom(`${fieldDef.type} as ${joinAlias}`).where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely.sql.ref(left), "=", import_kysely.sql.ref(right))))).select(() => eb.fn.count(eb.lit(1)).as(filterResultField));
453
608
  const conditions = [];
@@ -508,25 +663,24 @@ var BaseCrudDialect = class {
508
663
  }
509
664
  switch (key) {
510
665
  case "some": {
511
- result = this.and(eb, result, eb(eb.selectFrom(relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationModel, subPayload)), ">", 0));
666
+ 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));
512
667
  break;
513
668
  }
514
669
  case "every": {
515
- result = this.and(eb, result, eb(eb.selectFrom(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));
670
+ 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));
516
671
  break;
517
672
  }
518
673
  case "none": {
519
- result = this.and(eb, result, eb(eb.selectFrom(relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationModel, subPayload)), "=", 0));
674
+ 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));
520
675
  break;
521
676
  }
522
677
  }
523
678
  }
524
679
  return result;
525
680
  }
526
- buildArrayFilter(eb, model, modelAlias, field, fieldDef, payload) {
681
+ buildArrayFilter(eb, fieldRef, fieldDef, payload) {
527
682
  const clauses = [];
528
683
  const fieldType = fieldDef.type;
529
- const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb, modelAlias);
530
684
  for (const [key, _value] of Object.entries(payload)) {
531
685
  if (_value === void 0) {
532
686
  continue;
@@ -562,14 +716,14 @@ var BaseCrudDialect = class {
562
716
  }
563
717
  return this.and(eb, ...clauses);
564
718
  }
565
- buildPrimitiveFilter(eb, model, modelAlias, field, fieldDef, payload) {
719
+ buildPrimitiveFilter(eb, fieldRef, fieldDef, payload) {
566
720
  if (payload === null) {
567
- return eb(import_kysely.sql.ref(`${modelAlias}.${field}`), "is", null);
721
+ return eb(fieldRef, "is", null);
568
722
  }
569
723
  if (isEnum(this.schema, fieldDef.type)) {
570
- return this.buildEnumFilter(eb, modelAlias, field, fieldDef, payload);
724
+ return this.buildEnumFilter(eb, fieldRef, fieldDef, payload);
571
725
  }
572
- return (0, import_ts_pattern.match)(fieldDef.type).with("String", () => this.buildStringFilter(eb, modelAlias, field, payload)).with(import_ts_pattern.P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.buildNumberFilter(eb, model, modelAlias, field, type, payload)).with("Boolean", () => this.buildBooleanFilter(eb, modelAlias, field, payload)).with("DateTime", () => this.buildDateTimeFilter(eb, modelAlias, field, payload)).with("Bytes", () => this.buildBytesFilter(eb, modelAlias, field, payload)).with("Json", () => {
726
+ return (0, import_ts_pattern.match)(fieldDef.type).with("String", () => this.buildStringFilter(eb, fieldRef, payload)).with(import_ts_pattern.P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.buildNumberFilter(eb, fieldRef, type, payload)).with("Boolean", () => this.buildBooleanFilter(eb, fieldRef, payload)).with("DateTime", () => this.buildDateTimeFilter(eb, fieldRef, payload)).with("Bytes", () => this.buildBytesFilter(eb, fieldRef, payload)).with("Json", () => {
573
727
  throw new InternalError("JSON filters are not supported yet");
574
728
  }).with("Unsupported", () => {
575
729
  throw new QueryError(`Unsupported field cannot be used in filters`);
@@ -625,9 +779,7 @@ var BaseCrudDialect = class {
625
779
  consumedKeys
626
780
  };
627
781
  }
628
- buildStringFilter(eb, table, field, payload) {
629
- const fieldDef = getField(this.schema, table, field);
630
- let fieldRef = fieldDef?.computed ? import_kysely.sql.ref(field) : import_kysely.sql.ref(`${table}.${field}`);
782
+ buildStringFilter(eb, fieldRef, payload) {
631
783
  let insensitive = false;
632
784
  if (payload && typeof payload === "object" && "mode" in payload && payload.mode === "insensitive") {
633
785
  insensitive = true;
@@ -635,7 +787,7 @@ var BaseCrudDialect = class {
635
787
  fieldRef
636
788
  ]);
637
789
  }
638
- const { conditions, consumedKeys } = this.buildStandardFilter(eb, "String", payload, fieldRef, (value) => this.prepStringCasing(eb, value, insensitive), (value) => this.buildStringFilter(eb, table, field, value));
790
+ const { conditions, consumedKeys } = this.buildStandardFilter(eb, "String", payload, fieldRef, (value) => this.prepStringCasing(eb, value, insensitive), (value) => this.buildStringFilter(eb, fieldRef, value));
639
791
  if (payload && typeof payload === "object") {
640
792
  for (const [key, value] of Object.entries(payload)) {
641
793
  if (key === "mode" || consumedKeys.includes(key)) {
@@ -662,23 +814,23 @@ var BaseCrudDialect = class {
662
814
  return value === null ? null : import_kysely.sql.lit(value);
663
815
  }
664
816
  }
665
- buildNumberFilter(eb, model, table, field, type, payload) {
666
- const { conditions } = this.buildStandardFilter(eb, type, payload, buildFieldRef(this.schema, model, field, this.options, eb), (value) => this.transformPrimitive(value, type, false), (value) => this.buildNumberFilter(eb, model, table, field, type, value));
817
+ buildNumberFilter(eb, fieldRef, type, payload) {
818
+ const { conditions } = this.buildStandardFilter(eb, type, payload, fieldRef, (value) => this.transformPrimitive(value, type, false), (value) => this.buildNumberFilter(eb, fieldRef, type, value));
667
819
  return this.and(eb, ...conditions);
668
820
  }
669
- buildBooleanFilter(eb, table, field, payload) {
670
- const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, import_kysely.sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Boolean", false), (value) => this.buildBooleanFilter(eb, table, field, value), true, [
821
+ buildBooleanFilter(eb, fieldRef, payload) {
822
+ const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, fieldRef, (value) => this.transformPrimitive(value, "Boolean", false), (value) => this.buildBooleanFilter(eb, fieldRef, value), true, [
671
823
  "equals",
672
824
  "not"
673
825
  ]);
674
826
  return this.and(eb, ...conditions);
675
827
  }
676
- buildDateTimeFilter(eb, table, field, payload) {
677
- const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, import_kysely.sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "DateTime", false), (value) => this.buildDateTimeFilter(eb, table, field, value), true);
828
+ buildDateTimeFilter(eb, fieldRef, payload) {
829
+ const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, fieldRef, (value) => this.transformPrimitive(value, "DateTime", false), (value) => this.buildDateTimeFilter(eb, fieldRef, value), true);
678
830
  return this.and(eb, ...conditions);
679
831
  }
680
- buildBytesFilter(eb, table, field, payload) {
681
- const conditions = this.buildStandardFilter(eb, "Bytes", payload, import_kysely.sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Bytes", false), (value) => this.buildBytesFilter(eb, table, field, value), true, [
832
+ buildBytesFilter(eb, fieldRef, payload) {
833
+ const conditions = this.buildStandardFilter(eb, "Bytes", payload, fieldRef, (value) => this.transformPrimitive(value, "Bytes", false), (value) => this.buildBytesFilter(eb, fieldRef, value), true, [
682
834
  "equals",
683
835
  "in",
684
836
  "notIn",
@@ -686,8 +838,8 @@ var BaseCrudDialect = class {
686
838
  ]);
687
839
  return this.and(eb, ...conditions.conditions);
688
840
  }
689
- buildEnumFilter(eb, table, field, fieldDef, payload) {
690
- const conditions = this.buildStandardFilter(eb, "String", payload, import_kysely.sql.ref(`${table}.${field}`), (value) => value, (value) => this.buildEnumFilter(eb, table, field, fieldDef, value), true, [
841
+ buildEnumFilter(eb, fieldRef, fieldDef, payload) {
842
+ const conditions = this.buildStandardFilter(eb, "String", payload, fieldRef, (value) => value, (value) => this.buildEnumFilter(eb, fieldRef, fieldDef, value), true, [
691
843
  "equals",
692
844
  "in",
693
845
  "notIn",
@@ -754,7 +906,7 @@ var BaseCrudDialect = class {
754
906
  (0, import_common_helpers.invariant)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
755
907
  const sort = this.negateSort(value._count, negated);
756
908
  result = result.orderBy((eb) => {
757
- let subQuery = eb.selectFrom(relationModel);
909
+ let subQuery = this.buildSelectModel(eb, relationModel);
758
910
  const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, relationModel);
759
911
  subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely.sql.ref(left), "=", import_kysely.sql.ref(right)))));
760
912
  subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
@@ -773,6 +925,56 @@ var BaseCrudDialect = class {
773
925
  });
774
926
  return result;
775
927
  }
928
+ buildSelectAllFields(model, query, omit) {
929
+ const modelDef = requireModel(this.schema, model);
930
+ let result = query;
931
+ for (const field of Object.keys(modelDef.fields)) {
932
+ if (isRelationField(this.schema, model, field)) {
933
+ continue;
934
+ }
935
+ if (omit?.[field] === true) {
936
+ continue;
937
+ }
938
+ result = this.buildSelectField(result, model, model, field);
939
+ }
940
+ const descendants = getDelegateDescendantModels(this.schema, model);
941
+ for (const subModel of descendants) {
942
+ result = this.buildDelegateJoin(model, subModel.name, result);
943
+ result = result.select((eb) => {
944
+ const jsonObject = {};
945
+ for (const field of Object.keys(subModel.fields)) {
946
+ if (isRelationField(this.schema, subModel.name, field) || isInheritedField(this.schema, subModel.name, field)) {
947
+ continue;
948
+ }
949
+ jsonObject[field] = eb.ref(`${subModel.name}.${field}`);
950
+ }
951
+ return this.buildJsonObject(eb, jsonObject).as(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`);
952
+ });
953
+ }
954
+ return result;
955
+ }
956
+ buildSelectField(query, model, modelAlias, field) {
957
+ const fieldDef = requireField(this.schema, model, field);
958
+ if (fieldDef.computed) {
959
+ return query.select((eb) => buildFieldRef(this.schema, model, field, this.options, eb).as(field));
960
+ } else if (!fieldDef.originModel) {
961
+ return query.select(import_kysely.sql.ref(`${modelAlias}.${field}`).as(field));
962
+ } else {
963
+ return this.buildSelectField(query, fieldDef.originModel, fieldDef.originModel, field);
964
+ }
965
+ }
966
+ buildDelegateJoin(thisModel, otherModel, query) {
967
+ const idFields = getIdFields(this.schema, thisModel);
968
+ query = query.leftJoin(otherModel, (qb) => {
969
+ for (const idField of idFields) {
970
+ qb = qb.onRef(`${thisModel}.${idField}`, "=", `${otherModel}.${idField}`);
971
+ }
972
+ return qb;
973
+ });
974
+ return query;
975
+ }
976
+ // #endregion
977
+ // #region utils
776
978
  negateSort(sort, negated) {
777
979
  return negated ? sort === "asc" ? "desc" : "asc" : sort;
778
980
  }
@@ -854,7 +1056,8 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
854
1056
  const joinTableName = `${parentName}$${relationField}`;
855
1057
  let result = eb.selectFrom(`${relationModel} as ${joinTableName}`);
856
1058
  result = eb.selectFrom(() => {
857
- let subQuery = eb.selectFrom(`${relationModel}`).selectAll();
1059
+ let subQuery = this.buildSelectModel(eb, relationModel);
1060
+ subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
858
1061
  if (payload && typeof payload === "object") {
859
1062
  if (payload.where) {
860
1063
  subQuery = subQuery.where((eb2) => this.buildFilter(eb2, relationModel, relationModel, payload.where));
@@ -901,6 +1104,13 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
901
1104
  buildRelationObjectArgs(relationModel, relationField, eb, payload, parentName) {
902
1105
  const relationModelDef = requireModel(this.schema, relationModel);
903
1106
  const objArgs = [];
1107
+ const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
1108
+ if (descendantModels.length > 0) {
1109
+ objArgs.push(...descendantModels.map((subModel) => [
1110
+ import_kysely2.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1111
+ eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
1112
+ ]).flatMap((v) => v));
1113
+ }
904
1114
  if (payload === true || !payload.select) {
905
1115
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
906
1116
  import_kysely2.sql.lit(field),
@@ -993,7 +1203,11 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
993
1203
  if (Array.isArray(value)) {
994
1204
  return value.map((v) => this.transformPrimitive(v, type, false));
995
1205
  } else {
996
- return (0, import_ts_pattern3.match)(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => value instanceof Date ? value.toISOString() : value).with("Decimal", () => value.toString()).with("Bytes", () => Buffer.from(value)).with("Json", () => JSON.stringify(value)).otherwise(() => value);
1206
+ if (this.schema.typeDefs && type in this.schema.typeDefs) {
1207
+ return JSON.stringify(value);
1208
+ } else {
1209
+ return (0, import_ts_pattern3.match)(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => value instanceof Date ? value.toISOString() : value).with("Decimal", () => value.toString()).with("Bytes", () => Buffer.from(value)).with("Json", () => JSON.stringify(value)).otherwise(() => value);
1210
+ }
997
1211
  }
998
1212
  }
999
1213
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
@@ -1005,7 +1219,8 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1005
1219
  const relationModelDef = requireModel(this.schema, relationModel);
1006
1220
  const subQueryName = `${parentName}$${relationField}`;
1007
1221
  let tbl = eb.selectFrom(() => {
1008
- let subQuery = eb.selectFrom(relationModel).selectAll();
1222
+ let subQuery = this.buildSelectModel(eb, relationModel);
1223
+ subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
1009
1224
  if (payload && typeof payload === "object") {
1010
1225
  if (payload.where) {
1011
1226
  subQuery = subQuery.where((eb2) => this.buildFilter(eb2, relationModel, relationModel, payload.where));
@@ -1041,6 +1256,13 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1041
1256
  });
1042
1257
  tbl = tbl.select(() => {
1043
1258
  const objArgs = [];
1259
+ const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
1260
+ if (descendantModels.length > 0) {
1261
+ objArgs.push(...descendantModels.map((subModel) => [
1262
+ import_kysely3.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1263
+ eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
1264
+ ]).flatMap((v) => v));
1265
+ }
1044
1266
  if (payload === true || !payload.select) {
1045
1267
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
1046
1268
  import_kysely3.sql.lit(field),
@@ -1123,85 +1345,6 @@ function getCrudDialect(schema, options) {
1123
1345
  }
1124
1346
  __name(getCrudDialect, "getCrudDialect");
1125
1347
 
1126
- // src/schema/expression.ts
1127
- var ExpressionUtils = {
1128
- literal: /* @__PURE__ */ __name((value) => {
1129
- return {
1130
- kind: "literal",
1131
- value
1132
- };
1133
- }, "literal"),
1134
- array: /* @__PURE__ */ __name((items) => {
1135
- return {
1136
- kind: "array",
1137
- items
1138
- };
1139
- }, "array"),
1140
- call: /* @__PURE__ */ __name((functionName, args) => {
1141
- return {
1142
- kind: "call",
1143
- function: functionName,
1144
- args
1145
- };
1146
- }, "call"),
1147
- binary: /* @__PURE__ */ __name((left, op, right) => {
1148
- return {
1149
- kind: "binary",
1150
- op,
1151
- left,
1152
- right
1153
- };
1154
- }, "binary"),
1155
- unary: /* @__PURE__ */ __name((op, operand) => {
1156
- return {
1157
- kind: "unary",
1158
- op,
1159
- operand
1160
- };
1161
- }, "unary"),
1162
- field: /* @__PURE__ */ __name((field) => {
1163
- return {
1164
- kind: "field",
1165
- field
1166
- };
1167
- }, "field"),
1168
- member: /* @__PURE__ */ __name((receiver, members) => {
1169
- return {
1170
- kind: "member",
1171
- receiver,
1172
- members
1173
- };
1174
- }, "member"),
1175
- _this: /* @__PURE__ */ __name(() => {
1176
- return {
1177
- kind: "this"
1178
- };
1179
- }, "_this"),
1180
- _null: /* @__PURE__ */ __name(() => {
1181
- return {
1182
- kind: "null"
1183
- };
1184
- }, "_null"),
1185
- and: /* @__PURE__ */ __name((expr2, ...expressions) => {
1186
- return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "&&", exp), expr2);
1187
- }, "and"),
1188
- or: /* @__PURE__ */ __name((expr2, ...expressions) => {
1189
- return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
1190
- }, "or"),
1191
- is: /* @__PURE__ */ __name((value, kind) => {
1192
- return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
1193
- }, "is"),
1194
- isLiteral: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "literal"), "isLiteral"),
1195
- isArray: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "array"), "isArray"),
1196
- isCall: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "call"), "isCall"),
1197
- isNull: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "null"), "isNull"),
1198
- isThis: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "this"), "isThis"),
1199
- isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
1200
- isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
1201
- isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
1202
- isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
1203
- };
1204
-
1205
1348
  // src/utils/default-operation-node-visitor.ts
1206
1349
  var import_kysely4 = require("kysely");
1207
1350
  var DefaultOperationNodeVisitor = class extends import_kysely4.OperationNodeVisitor {
@@ -2468,10 +2611,10 @@ function clone(value) {
2468
2611
  __name(clone, "clone");
2469
2612
 
2470
2613
  // src/utils/object-utils.ts
2471
- function extractFields(obj, fields) {
2614
+ function extractFields2(obj, fields) {
2472
2615
  return Object.fromEntries(Object.entries(obj).filter(([key]) => fields.includes(key)));
2473
2616
  }
2474
- __name(extractFields, "extractFields");
2617
+ __name(extractFields2, "extractFields");
2475
2618
  function fieldsToSelectObject(fields) {
2476
2619
  return Object.fromEntries(fields.map((f) => [
2477
2620
  f,
@@ -2480,15 +2623,6 @@ function fieldsToSelectObject(fields) {
2480
2623
  }
2481
2624
  __name(fieldsToSelectObject, "fieldsToSelectObject");
2482
2625
 
2483
- // src/client/constants.ts
2484
- var CONTEXT_COMMENT_PREFIX = "-- $$context:";
2485
- var NUMERIC_FIELD_TYPES = [
2486
- "Int",
2487
- "Float",
2488
- "BigInt",
2489
- "Decimal"
2490
- ];
2491
-
2492
2626
  // src/client/crud/operations/base.ts
2493
2627
  var BaseOperationHandler = class {
2494
2628
  static {
@@ -2532,17 +2666,17 @@ var BaseOperationHandler = class {
2532
2666
  getField(model, field) {
2533
2667
  return getField(this.schema, model, field);
2534
2668
  }
2535
- exists(kysely, model, filter) {
2669
+ async exists(kysely, model, filter) {
2536
2670
  const idFields = getIdFields(this.schema, model);
2537
2671
  const _filter = flattenCompoundUniqueFilters(this.schema, model, filter);
2538
2672
  const query = kysely.selectFrom(model).where((eb) => eb.and(_filter)).select(idFields.map((f) => kysely.dynamic.ref(f))).limit(1).modifyEnd(this.makeContextComment({
2539
2673
  model,
2540
2674
  operation: "read"
2541
2675
  }));
2542
- return query.executeTakeFirst();
2676
+ return this.executeQueryTakeFirst(kysely, query, "exists");
2543
2677
  }
2544
2678
  async read(kysely, model, args) {
2545
- let query = kysely.selectFrom(model);
2679
+ let query = this.dialect.buildSelectModel((0, import_kysely8.expressionBuilder)(), model);
2546
2680
  if (args?.where) {
2547
2681
  query = query.where((eb) => this.dialect.buildFilter(eb, model, model, args?.where));
2548
2682
  }
@@ -2567,7 +2701,7 @@ var BaseOperationHandler = class {
2567
2701
  if (args && "select" in args && args.select) {
2568
2702
  query = this.buildFieldSelection(model, query, args.select, model);
2569
2703
  } else {
2570
- query = this.buildSelectAllScalarFields(model, query, args?.omit);
2704
+ query = this.dialect.buildSelectAllFields(model, query, args?.omit);
2571
2705
  }
2572
2706
  if (args && "include" in args && args.include) {
2573
2707
  query = this.buildFieldSelection(model, query, args.include, model);
@@ -2580,14 +2714,18 @@ var BaseOperationHandler = class {
2580
2714
  operation: "read"
2581
2715
  }));
2582
2716
  let result = [];
2717
+ const queryId = {
2718
+ queryId: `zenstack-${(0, import_cuid2.createId)()}`
2719
+ };
2720
+ const compiled = kysely.getExecutor().compileQuery(query.toOperationNode(), queryId);
2583
2721
  try {
2584
- result = await query.execute();
2722
+ const r = await kysely.getExecutor().executeQuery(compiled, queryId);
2723
+ result = r.rows;
2585
2724
  } catch (err) {
2586
- const { sql: sql11, parameters } = query.compile();
2587
- let message = `Failed to execute query: ${err}, sql: ${sql11}`;
2725
+ let message = `Failed to execute query: ${err}, sql: ${compiled.sql}`;
2588
2726
  if (this.options.debug) {
2589
2727
  message += `, parameters:
2590
- ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
2728
+ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
2591
2729
  }
2592
2730
  throw new QueryError(message, err);
2593
2731
  }
@@ -2624,12 +2762,16 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
2624
2762
  }
2625
2763
  const fieldDef = this.requireField(model, field);
2626
2764
  if (!fieldDef.relation) {
2627
- result = this.selectField(result, model, parentAlias, field);
2765
+ result = this.dialect.buildSelectField(result, model, parentAlias, field);
2628
2766
  } else {
2629
2767
  if (!fieldDef.array && !fieldDef.optional && payload.where) {
2630
2768
  throw new QueryError(`Field "${field}" doesn't support filtering`);
2631
2769
  }
2632
- result = this.dialect.buildRelationSelection(result, model, field, parentAlias, payload);
2770
+ if (fieldDef.originModel) {
2771
+ result = this.dialect.buildRelationSelection(result, fieldDef.originModel, field, fieldDef.originModel, payload);
2772
+ } else {
2773
+ result = this.dialect.buildRelationSelection(result, model, field, parentAlias, payload);
2774
+ }
2633
2775
  }
2634
2776
  }
2635
2777
  return result;
@@ -2662,18 +2804,6 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
2662
2804
  query = query.select((eb2) => this.dialect.buildJsonObject(eb2, jsonObject).as("_count"));
2663
2805
  return query;
2664
2806
  }
2665
- buildSelectAllScalarFields(model, query, omit) {
2666
- const modelDef = this.requireModel(model);
2667
- return Object.keys(modelDef.fields).filter((f) => !isRelationField(this.schema, model, f)).filter((f) => omit?.[f] !== true).reduce((acc, f) => this.selectField(acc, model, model, f), query);
2668
- }
2669
- selectField(query, model, modelAlias, field) {
2670
- const fieldDef = this.requireField(model, field);
2671
- if (!fieldDef.computed) {
2672
- return query.select(import_kysely8.sql.ref(`${modelAlias}.${field}`).as(field));
2673
- } else {
2674
- return query.select((eb) => buildFieldRef(this.schema, model, field, this.options, eb).as(field));
2675
- }
2676
- }
2677
2807
  buildCursorFilter(model, query, cursor, orderBy, negateOrderBy) {
2678
2808
  if (!orderBy) {
2679
2809
  orderBy = makeDefaultOrderBy(this.schema, model);
@@ -2696,9 +2826,12 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
2696
2826
  result = result.where((eb2) => eb2.or(filters));
2697
2827
  return result;
2698
2828
  }
2699
- async create(kysely, model, data, fromRelation) {
2829
+ async create(kysely, model, data, fromRelation, creatingForDelegate = false) {
2700
2830
  const modelDef = this.requireModel(model);
2701
- const createFields = {};
2831
+ if (modelDef.isDelegate && !creatingForDelegate) {
2832
+ throw new QueryError(`Model "${this.model}" is a delegate and cannot be created directly.`);
2833
+ }
2834
+ let createFields = {};
2702
2835
  let parentUpdateTask = void 0;
2703
2836
  let m2m = void 0;
2704
2837
  if (fromRelation) {
@@ -2717,7 +2850,7 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
2717
2850
  model: fromRelation.model,
2718
2851
  operation: "update"
2719
2852
  }));
2720
- return query2.execute();
2853
+ return this.executeQuery(kysely, query2, "update");
2721
2854
  }, "parentUpdateTask");
2722
2855
  }
2723
2856
  }
@@ -2746,13 +2879,17 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
2746
2879
  }
2747
2880
  }
2748
2881
  }
2882
+ if (modelDef.baseModel) {
2883
+ const baseCreateResult = await this.processBaseModelCreate(kysely, modelDef.baseModel, createFields, model);
2884
+ createFields = baseCreateResult.remainingFields;
2885
+ }
2749
2886
  const updatedData = this.fillGeneratedValues(modelDef, createFields);
2750
2887
  const idFields = getIdFields(this.schema, model);
2751
- const query = kysely.insertInto(model).values(updatedData).returning(idFields).modifyEnd(this.makeContextComment({
2888
+ const query = kysely.insertInto(model).$if(Object.keys(updatedData).length === 0, (qb) => qb.defaultValues()).$if(Object.keys(updatedData).length > 0, (qb) => qb.values(updatedData)).returning(idFields).modifyEnd(this.makeContextComment({
2752
2889
  model,
2753
2890
  operation: "create"
2754
2891
  }));
2755
- const createdEntity = await query.executeTakeFirst();
2892
+ const createdEntity = await this.executeQueryTakeFirst(kysely, query, "create");
2756
2893
  if (Object.keys(postCreateRelations).length > 0) {
2757
2894
  const relationPromises = Object.entries(postCreateRelations).map(([field, subPayload]) => {
2758
2895
  return this.processNoneOwnedRelationForCreate(kysely, model, field, subPayload, createdEntity);
@@ -2767,6 +2904,28 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
2767
2904
  }
2768
2905
  return createdEntity;
2769
2906
  }
2907
+ async processBaseModelCreate(kysely, model, createFields, forModel) {
2908
+ const thisCreateFields = {};
2909
+ const remainingFields = {};
2910
+ Object.entries(createFields).forEach(([field, value]) => {
2911
+ const fieldDef = this.getField(model, field);
2912
+ if (fieldDef) {
2913
+ thisCreateFields[field] = value;
2914
+ } else {
2915
+ remainingFields[field] = value;
2916
+ }
2917
+ });
2918
+ const discriminatorField = getDiscriminatorField(this.schema, model);
2919
+ (0, import_common_helpers8.invariant)(discriminatorField, `Base model "${model}" must have a discriminator field`);
2920
+ thisCreateFields[discriminatorField] = forModel;
2921
+ const baseEntity = await this.create(kysely, model, thisCreateFields, void 0, true);
2922
+ const idValues = extractIdFields(baseEntity, this.schema, model);
2923
+ Object.assign(remainingFields, idValues);
2924
+ return {
2925
+ baseEntity,
2926
+ remainingFields
2927
+ };
2928
+ }
2770
2929
  buildFkAssignments(model, relationField, entity) {
2771
2930
  const parentFkFields = {};
2772
2931
  (0, import_common_helpers8.invariant)(relationField, "parentField must be defined if parentModel is defined");
@@ -2841,7 +3000,7 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
2841
3000
  case "connect": {
2842
3001
  const referencedPkFields = relationField.relation.references;
2843
3002
  (0, import_common_helpers8.invariant)(referencedPkFields, "relation must have fields info");
2844
- const extractedFks = extractFields(subPayload, referencedPkFields);
3003
+ const extractedFks = extractFields2(subPayload, referencedPkFields);
2845
3004
  if (Object.keys(extractedFks).length === referencedPkFields.length) {
2846
3005
  result = extractedFks;
2847
3006
  } else {
@@ -2936,7 +3095,7 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
2936
3095
  }
2937
3096
  relationKeyPairs = keyPairs;
2938
3097
  }
2939
- const createData = enumerate(input.data).map((item) => {
3098
+ let createData = enumerate(input.data).map((item) => {
2940
3099
  const newItem = {};
2941
3100
  for (const [name, value] of Object.entries(item)) {
2942
3101
  const fieldDef = this.requireField(model, name);
@@ -2950,14 +3109,21 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
2950
3109
  }
2951
3110
  return this.fillGeneratedValues(modelDef, newItem);
2952
3111
  });
3112
+ if (modelDef.baseModel) {
3113
+ if (input.skipDuplicates) {
3114
+ throw new QueryError('"skipDuplicates" options is not supported for polymorphic models');
3115
+ }
3116
+ const baseCreateResult = await this.processBaseModelCreateMany(kysely, modelDef.baseModel, createData, !!input.skipDuplicates, model);
3117
+ createData = baseCreateResult.remainingFieldRows;
3118
+ }
2953
3119
  const query = kysely.insertInto(model).values(createData).$if(!!input.skipDuplicates, (qb) => qb.onConflict((oc) => oc.doNothing())).modifyEnd(this.makeContextComment({
2954
3120
  model,
2955
3121
  operation: "create"
2956
3122
  }));
2957
3123
  if (!returnData) {
2958
- const result = await query.executeTakeFirstOrThrow();
3124
+ const result = await this.executeQuery(kysely, query, "createMany");
2959
3125
  return {
2960
- count: Number(result.numInsertedOrUpdatedRows)
3126
+ count: Number(result.numAffectedRows)
2961
3127
  };
2962
3128
  } else {
2963
3129
  const idFields = getIdFields(this.schema, model);
@@ -2965,10 +3131,46 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
2965
3131
  return result;
2966
3132
  }
2967
3133
  }
3134
+ async processBaseModelCreateMany(kysely, model, createRows, skipDuplicates, forModel) {
3135
+ const thisCreateRows = [];
3136
+ const remainingFieldRows = [];
3137
+ const discriminatorField = getDiscriminatorField(this.schema, model);
3138
+ (0, import_common_helpers8.invariant)(discriminatorField, `Base model "${model}" must have a discriminator field`);
3139
+ for (const createFields of createRows) {
3140
+ const thisCreateFields = {};
3141
+ const remainingFields = {};
3142
+ Object.entries(createFields).forEach(([field, value]) => {
3143
+ const fieldDef = this.getField(model, field);
3144
+ if (fieldDef) {
3145
+ thisCreateFields[field] = value;
3146
+ } else {
3147
+ remainingFields[field] = value;
3148
+ }
3149
+ });
3150
+ thisCreateFields[discriminatorField] = forModel;
3151
+ thisCreateRows.push(thisCreateFields);
3152
+ remainingFieldRows.push(remainingFields);
3153
+ }
3154
+ const baseEntities = await this.createMany(kysely, model, {
3155
+ data: thisCreateRows,
3156
+ skipDuplicates
3157
+ }, true);
3158
+ for (let i = 0; i < baseEntities.length; i++) {
3159
+ const idValues = extractIdFields(baseEntities[i], this.schema, model);
3160
+ Object.assign(remainingFieldRows[i], idValues);
3161
+ }
3162
+ return {
3163
+ baseEntities,
3164
+ remainingFieldRows
3165
+ };
3166
+ }
2968
3167
  fillGeneratedValues(modelDef, data) {
2969
3168
  const fields = modelDef.fields;
2970
3169
  const values = clone(data);
2971
- for (const field in fields) {
3170
+ for (const [field, fieldDef] of Object.entries(fields)) {
3171
+ if (fieldDef.originModel) {
3172
+ continue;
3173
+ }
2972
3174
  if (!(field in data)) {
2973
3175
  if (typeof fields[field]?.default === "object" && "kind" in fields[field].default) {
2974
3176
  const generated = this.evalGenerator(fields[field].default);
@@ -3045,28 +3247,33 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3045
3247
  }
3046
3248
  }
3047
3249
  if (Object.keys(finalData).length === 0) {
3048
- const r = await this.readUnique(kysely, model, {
3049
- where: combinedWhere
3250
+ return combinedWhere;
3251
+ }
3252
+ let needIdRead = false;
3253
+ if (modelDef.baseModel && !this.isIdFilter(model, combinedWhere)) {
3254
+ needIdRead = true;
3255
+ }
3256
+ if (needIdRead) {
3257
+ const readResult = await this.readUnique(kysely, model, {
3258
+ where: combinedWhere,
3259
+ select: this.makeIdSelect(model)
3050
3260
  });
3051
- if (!r && throwIfNotFound) {
3261
+ if (!readResult && throwIfNotFound) {
3052
3262
  throw new NotFoundError(model);
3053
3263
  }
3054
- return r;
3264
+ combinedWhere = readResult;
3265
+ }
3266
+ if (modelDef.baseModel) {
3267
+ const baseUpdateResult = await this.processBaseModelUpdate(kysely, modelDef.baseModel, combinedWhere, finalData, throwIfNotFound);
3268
+ finalData = baseUpdateResult.remainingFields;
3269
+ combinedWhere = baseUpdateResult.baseEntity;
3055
3270
  }
3056
3271
  const updateFields = {};
3057
3272
  let thisEntity = void 0;
3058
3273
  for (const field in finalData) {
3059
3274
  const fieldDef = this.requireField(model, field);
3060
3275
  if (isScalarField(this.schema, model, field) || isForeignKeyField(this.schema, model, field)) {
3061
- if (this.isNumericField(fieldDef) && typeof finalData[field] === "object" && finalData[field]) {
3062
- updateFields[field] = this.transformIncrementalUpdate(model, field, fieldDef, finalData[field]);
3063
- continue;
3064
- }
3065
- if (fieldDef.array && typeof finalData[field] === "object" && !Array.isArray(finalData[field]) && finalData[field]) {
3066
- updateFields[field] = this.transformScalarListUpdate(model, field, fieldDef, finalData[field]);
3067
- continue;
3068
- }
3069
- updateFields[field] = this.dialect.transformPrimitive(finalData[field], fieldDef.type, !!fieldDef.array);
3276
+ updateFields[field] = this.processScalarFieldUpdateData(model, field, finalData);
3070
3277
  } else {
3071
3278
  if (!allowRelationUpdate) {
3072
3279
  throw new QueryError(`Relation update not allowed for field "${field}"`);
@@ -3088,16 +3295,14 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3088
3295
  }
3089
3296
  }
3090
3297
  if (Object.keys(updateFields).length === 0) {
3091
- return thisEntity ?? await this.readUnique(kysely, model, {
3092
- where: combinedWhere
3093
- });
3298
+ return combinedWhere;
3094
3299
  } else {
3095
3300
  const idFields = getIdFields(this.schema, model);
3096
3301
  const query = kysely.updateTable(model).where((eb) => this.dialect.buildFilter(eb, model, model, combinedWhere)).set(updateFields).returning(idFields).modifyEnd(this.makeContextComment({
3097
3302
  model,
3098
3303
  operation: "update"
3099
3304
  }));
3100
- const updatedEntity = await query.executeTakeFirst();
3305
+ const updatedEntity = await this.executeQueryTakeFirst(kysely, query, "update");
3101
3306
  if (!updatedEntity) {
3102
3307
  if (throwIfNotFound) {
3103
3308
  throw new NotFoundError(model);
@@ -3108,6 +3313,55 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3108
3313
  return updatedEntity;
3109
3314
  }
3110
3315
  }
3316
+ processScalarFieldUpdateData(model, field, data) {
3317
+ const fieldDef = this.requireField(model, field);
3318
+ if (this.isNumericIncrementalUpdate(fieldDef, data[field])) {
3319
+ return this.transformIncrementalUpdate(model, field, fieldDef, data[field]);
3320
+ }
3321
+ if (fieldDef.array && typeof data[field] === "object" && !Array.isArray(data[field]) && data[field]) {
3322
+ return this.transformScalarListUpdate(model, field, fieldDef, data[field]);
3323
+ }
3324
+ return this.dialect.transformPrimitive(data[field], fieldDef.type, !!fieldDef.array);
3325
+ }
3326
+ isNumericIncrementalUpdate(fieldDef, value) {
3327
+ if (!this.isNumericField(fieldDef)) {
3328
+ return false;
3329
+ }
3330
+ if (typeof value !== "object" || !value) {
3331
+ return false;
3332
+ }
3333
+ return [
3334
+ "increment",
3335
+ "decrement",
3336
+ "multiply",
3337
+ "divide",
3338
+ "set"
3339
+ ].some((key) => key in value);
3340
+ }
3341
+ isIdFilter(model, filter) {
3342
+ if (!filter || typeof filter !== "object") {
3343
+ return false;
3344
+ }
3345
+ const idFields = getIdFields(this.schema, model);
3346
+ return idFields.length === Object.keys(filter).length && idFields.every((field) => field in filter);
3347
+ }
3348
+ async processBaseModelUpdate(kysely, model, where, updateFields, throwIfNotFound) {
3349
+ const thisUpdateFields = {};
3350
+ const remainingFields = {};
3351
+ Object.entries(updateFields).forEach(([field, value]) => {
3352
+ const fieldDef = this.getField(model, field);
3353
+ if (fieldDef) {
3354
+ thisUpdateFields[field] = value;
3355
+ } else {
3356
+ remainingFields[field] = value;
3357
+ }
3358
+ });
3359
+ const baseEntity = await this.update(kysely, model, where, thisUpdateFields, void 0, void 0, throwIfNotFound);
3360
+ return {
3361
+ baseEntity,
3362
+ remainingFields
3363
+ };
3364
+ }
3111
3365
  transformIncrementalUpdate(model, field, fieldDef, payload) {
3112
3366
  (0, import_common_helpers8.invariant)(Object.keys(payload).length === 1, 'Only one of "set", "increment", "decrement", "multiply", or "divide" can be provided');
3113
3367
  const key = Object.keys(payload)[0];
@@ -3136,7 +3390,7 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3136
3390
  makeContextComment(context) {
3137
3391
  return import_kysely8.sql.raw(`${CONTEXT_COMMENT_PREFIX}${JSON.stringify(context)}`);
3138
3392
  }
3139
- async updateMany(kysely, model, where, data, limit, returnData) {
3393
+ async updateMany(kysely, model, where, data, limit, returnData, filterModel) {
3140
3394
  if (typeof data !== "object") {
3141
3395
  throw new InternalError("data must be an object");
3142
3396
  }
@@ -3145,34 +3399,52 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3145
3399
  count: 0
3146
3400
  };
3147
3401
  }
3148
- const updateFields = {};
3402
+ const modelDef = this.requireModel(model);
3403
+ if (modelDef.baseModel && limit !== void 0) {
3404
+ throw new QueryError("Updating with a limit is not supported for polymorphic models");
3405
+ }
3406
+ filterModel ??= model;
3407
+ let updateFields = {};
3149
3408
  for (const field in data) {
3150
- const fieldDef = this.requireField(model, field);
3151
3409
  if (isRelationField(this.schema, model, field)) {
3152
3410
  continue;
3153
3411
  }
3154
- updateFields[field] = this.dialect.transformPrimitive(data[field], fieldDef.type, !!fieldDef.array);
3412
+ updateFields[field] = this.processScalarFieldUpdateData(model, field, data);
3413
+ }
3414
+ let shouldFallbackToIdFilter = false;
3415
+ if (limit !== void 0 && !this.dialect.supportsUpdateWithLimit) {
3416
+ shouldFallbackToIdFilter = true;
3417
+ }
3418
+ if (modelDef.isDelegate || modelDef.baseModel) {
3419
+ shouldFallbackToIdFilter = true;
3420
+ }
3421
+ let resultFromBaseModel = void 0;
3422
+ if (modelDef.baseModel) {
3423
+ const baseResult = await this.processBaseModelUpdateMany(kysely, modelDef.baseModel, where, updateFields, filterModel);
3424
+ updateFields = baseResult.remainingFields;
3425
+ resultFromBaseModel = baseResult.baseResult;
3426
+ }
3427
+ if (Object.keys(updateFields).length === 0) {
3428
+ return resultFromBaseModel ?? (returnData ? [] : {
3429
+ count: 0
3430
+ });
3155
3431
  }
3156
3432
  let query = kysely.updateTable(model).set(updateFields);
3157
- if (limit === void 0) {
3158
- query = query.where((eb) => this.dialect.buildFilter(eb, model, model, where));
3433
+ if (!shouldFallbackToIdFilter) {
3434
+ query = query.where((eb) => this.dialect.buildFilter(eb, model, model, where)).$if(limit !== void 0, (qb) => qb.limit(limit));
3159
3435
  } else {
3160
- if (this.dialect.supportsUpdateWithLimit) {
3161
- query = query.where((eb) => this.dialect.buildFilter(eb, model, model, where)).limit(limit);
3162
- } else {
3163
- query = query.where((eb) => eb(eb.refTuple(
3164
- ...this.buildIdFieldRefs(kysely, model)
3165
- ), "in", kysely.selectFrom(model).where((eb2) => this.dialect.buildFilter(eb2, model, model, where)).select(this.buildIdFieldRefs(kysely, model)).limit(limit)));
3166
- }
3436
+ query = query.where((eb) => eb(eb.refTuple(
3437
+ ...this.buildIdFieldRefs(kysely, model)
3438
+ ), "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))));
3167
3439
  }
3168
3440
  query = query.modifyEnd(this.makeContextComment({
3169
3441
  model,
3170
3442
  operation: "update"
3171
3443
  }));
3172
3444
  if (!returnData) {
3173
- const result = await query.executeTakeFirstOrThrow();
3445
+ const result = await this.executeQuery(kysely, query, "update");
3174
3446
  return {
3175
- count: Number(result.numUpdatedRows)
3447
+ count: Number(result.numAffectedRows)
3176
3448
  };
3177
3449
  } else {
3178
3450
  const idFields = getIdFields(this.schema, model);
@@ -3180,9 +3452,26 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3180
3452
  return result;
3181
3453
  }
3182
3454
  }
3455
+ async processBaseModelUpdateMany(kysely, model, where, updateFields, filterModel) {
3456
+ const thisUpdateFields = {};
3457
+ const remainingFields = {};
3458
+ Object.entries(updateFields).forEach(([field, value]) => {
3459
+ const fieldDef = this.getField(model, field);
3460
+ if (fieldDef) {
3461
+ thisUpdateFields[field] = value;
3462
+ } else {
3463
+ remainingFields[field] = value;
3464
+ }
3465
+ });
3466
+ const baseResult = await this.updateMany(kysely, model, where, thisUpdateFields, void 0, false, filterModel);
3467
+ return {
3468
+ baseResult,
3469
+ remainingFields
3470
+ };
3471
+ }
3183
3472
  buildIdFieldRefs(kysely, model) {
3184
3473
  const idFields = getIdFields(this.schema, model);
3185
- return idFields.map((f) => kysely.dynamic.ref(f));
3474
+ return idFields.map((f) => kysely.dynamic.ref(`${model}.${f}`));
3186
3475
  }
3187
3476
  async processRelationUpdates(kysely, model, field, fieldDef, parentIds, args, throwIfNotFound) {
3188
3477
  const tasks = [];
@@ -3300,7 +3589,7 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3300
3589
  model: fromRelation.model,
3301
3590
  operation: "update"
3302
3591
  }));
3303
- updateResult = await query.executeTakeFirstOrThrow();
3592
+ updateResult = await this.executeQuery(kysely, query, "connect");
3304
3593
  } else {
3305
3594
  const relationFieldDef = this.requireField(fromRelation.model, fromRelation.field);
3306
3595
  if (!relationFieldDef.array) {
@@ -3311,7 +3600,7 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3311
3600
  model: fromRelation.model,
3312
3601
  operation: "update"
3313
3602
  }));
3314
- await query2.execute();
3603
+ await this.executeQuery(kysely, query2, "disconnect");
3315
3604
  }
3316
3605
  const query = kysely.updateTable(model).where((eb) => eb.or(_data.map((d) => eb.and(d)))).set(keyPairs.reduce((acc, { fk, pk }) => ({
3317
3606
  ...acc,
@@ -3320,9 +3609,9 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3320
3609
  model,
3321
3610
  operation: "update"
3322
3611
  }));
3323
- updateResult = await query.executeTakeFirstOrThrow();
3612
+ updateResult = await this.executeQuery(kysely, query, "connect");
3324
3613
  }
3325
- if (_data.length > updateResult.numUpdatedRows) {
3614
+ if (_data.length > updateResult.numAffectedRows) {
3326
3615
  throw new NotFoundError(model);
3327
3616
  }
3328
3617
  }
@@ -3390,7 +3679,7 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3390
3679
  model: fromRelation.model,
3391
3680
  operation: "update"
3392
3681
  }));
3393
- await query.executeTakeFirstOrThrow();
3682
+ await this.executeQuery(kysely, query, "disconnect");
3394
3683
  } else {
3395
3684
  const query = kysely.updateTable(model).where(eb.and([
3396
3685
  // fk filter
@@ -3407,7 +3696,7 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3407
3696
  model,
3408
3697
  operation: "update"
3409
3698
  }));
3410
- await query.executeTakeFirstOrThrow();
3699
+ await this.executeQuery(kysely, query, "disconnect");
3411
3700
  }
3412
3701
  }
3413
3702
  }
@@ -3445,7 +3734,7 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3445
3734
  model,
3446
3735
  operation: "update"
3447
3736
  }));
3448
- await query.execute();
3737
+ await this.executeQuery(kysely, query, "disconnect");
3449
3738
  if (_data.length > 0) {
3450
3739
  const query2 = kysely.updateTable(model).where((eb) => eb.or(_data.map((d) => eb.and(d)))).set(keyPairs.reduce((acc, { fk, pk }) => ({
3451
3740
  ...acc,
@@ -3454,8 +3743,8 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3454
3743
  model,
3455
3744
  operation: "update"
3456
3745
  }));
3457
- const r = await query2.executeTakeFirstOrThrow();
3458
- if (_data.length > r.numUpdatedRows) {
3746
+ const r = await this.executeQuery(kysely, query2, "connect");
3747
+ if (_data.length > r.numAffectedRows) {
3459
3748
  throw new NotFoundError(model);
3460
3749
  }
3461
3750
  }
@@ -3496,7 +3785,7 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3496
3785
  OR: deleteConditions
3497
3786
  }
3498
3787
  ]
3499
- }, void 0, false);
3788
+ });
3500
3789
  } else {
3501
3790
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
3502
3791
  if (ownedByModel) {
@@ -3519,7 +3808,7 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3519
3808
  OR: deleteConditions
3520
3809
  }
3521
3810
  ]
3522
- }, void 0, false);
3811
+ });
3523
3812
  } else {
3524
3813
  deleteResult = await this.delete(kysely, model, {
3525
3814
  AND: [
@@ -3531,7 +3820,7 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3531
3820
  OR: deleteConditions
3532
3821
  }
3533
3822
  ]
3534
- }, void 0, false);
3823
+ });
3535
3824
  }
3536
3825
  }
3537
3826
  if (throwForNotFound && expectedDeleteCount > deleteResult.count) {
@@ -3542,33 +3831,59 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3542
3831
  return enumerate(data).map((item) => flattenCompoundUniqueFilters(this.schema, model, item));
3543
3832
  }
3544
3833
  // #endregion
3545
- async delete(kysely, model, where, limit, returnData) {
3834
+ async delete(kysely, model, where, limit, filterModel) {
3835
+ filterModel ??= model;
3836
+ const modelDef = this.requireModel(model);
3837
+ if (modelDef.baseModel) {
3838
+ if (limit !== void 0) {
3839
+ throw new QueryError("Deleting with a limit is not supported for polymorphic models");
3840
+ }
3841
+ return this.processBaseModelDelete(kysely, modelDef.baseModel, where, limit, filterModel);
3842
+ }
3546
3843
  let query = kysely.deleteFrom(model);
3547
- if (limit === void 0) {
3844
+ let needIdFilter = false;
3845
+ if (limit !== void 0 && !this.dialect.supportsDeleteWithLimit) {
3846
+ needIdFilter = true;
3847
+ }
3848
+ if (modelDef.isDelegate || modelDef.baseModel) {
3849
+ needIdFilter = true;
3850
+ }
3851
+ if (!needIdFilter) {
3548
3852
  query = query.where((eb) => this.dialect.buildFilter(eb, model, model, where));
3549
3853
  } else {
3550
- if (this.dialect.supportsDeleteWithLimit) {
3551
- query = query.where((eb) => this.dialect.buildFilter(eb, model, model, where)).limit(limit);
3552
- } else {
3553
- query = query.where((eb) => eb(eb.refTuple(
3554
- ...this.buildIdFieldRefs(kysely, model)
3555
- ), "in", kysely.selectFrom(model).where((eb2) => this.dialect.buildFilter(eb2, model, model, where)).select(this.buildIdFieldRefs(kysely, model)).limit(limit)));
3556
- }
3854
+ query = query.where((eb) => eb(eb.refTuple(
3855
+ ...this.buildIdFieldRefs(kysely, model)
3856
+ ), "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))));
3557
3857
  }
3858
+ await this.processDelegateRelationDelete(kysely, modelDef, where, limit);
3558
3859
  query = query.modifyEnd(this.makeContextComment({
3559
3860
  model,
3560
3861
  operation: "delete"
3561
3862
  }));
3562
- if (returnData) {
3563
- const result = await query.execute();
3564
- return result;
3565
- } else {
3566
- const result = await query.executeTakeFirstOrThrow();
3567
- return {
3568
- count: Number(result.numDeletedRows)
3569
- };
3863
+ const result = await this.executeQuery(kysely, query, "delete");
3864
+ return {
3865
+ count: Number(result.numAffectedRows)
3866
+ };
3867
+ }
3868
+ async processDelegateRelationDelete(kysely, modelDef, where, limit) {
3869
+ for (const fieldDef of Object.values(modelDef.fields)) {
3870
+ if (fieldDef.relation && fieldDef.relation.opposite) {
3871
+ const oppositeModelDef = this.requireModel(fieldDef.type);
3872
+ const oppositeRelation = this.requireField(fieldDef.type, fieldDef.relation.opposite);
3873
+ if (oppositeModelDef.baseModel && oppositeRelation.relation?.onDelete === "Cascade") {
3874
+ if (limit !== void 0) {
3875
+ throw new QueryError("Deleting with a limit is not supported for polymorphic models");
3876
+ }
3877
+ await this.delete(kysely, fieldDef.type, {
3878
+ [fieldDef.relation.opposite]: where
3879
+ }, void 0);
3880
+ }
3881
+ }
3570
3882
  }
3571
3883
  }
3884
+ async processBaseModelDelete(kysely, model, where, limit, filterModel) {
3885
+ return this.delete(kysely, model, where, limit, filterModel);
3886
+ }
3572
3887
  makeIdSelect(model) {
3573
3888
  const modelDef = this.requireModel(model);
3574
3889
  return modelDef.idFields.reduce((acc, f) => {
@@ -3602,9 +3917,7 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3602
3917
  return callback(this.kysely);
3603
3918
  } else {
3604
3919
  let txBuilder = this.kysely.transaction();
3605
- if (isolationLevel) {
3606
- txBuilder = txBuilder.setIsolationLevel(isolationLevel);
3607
- }
3920
+ txBuilder = txBuilder.setIsolationLevel(isolationLevel ?? "repeatable read");
3608
3921
  return txBuilder.execute(callback);
3609
3922
  }
3610
3923
  }
@@ -3646,6 +3959,25 @@ ${parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3646
3959
  }
3647
3960
  }
3648
3961
  }
3962
+ makeQueryId(operation) {
3963
+ return {
3964
+ queryId: `${operation}-${(0, import_cuid2.createId)()}`
3965
+ };
3966
+ }
3967
+ executeQuery(kysely, query, operation) {
3968
+ return kysely.executeQuery(query.compile(), this.makeQueryId(operation));
3969
+ }
3970
+ async executeQueryTakeFirst(kysely, query, operation) {
3971
+ const result = await kysely.executeQuery(query.compile(), this.makeQueryId(operation));
3972
+ return result.rows[0];
3973
+ }
3974
+ async executeQueryTakeFirstOrThrow(kysely, query, operation) {
3975
+ const result = await kysely.executeQuery(query.compile(), this.makeQueryId(operation));
3976
+ if (result.rows.length === 0) {
3977
+ throw new QueryError("No rows found");
3978
+ }
3979
+ return result.rows[0];
3980
+ }
3649
3981
  };
3650
3982
 
3651
3983
  // src/client/crud/operations/aggregate.ts
@@ -3657,7 +3989,22 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
3657
3989
  const normalizedArgs = this.normalizeArgs(args);
3658
3990
  const parsedArgs = this.inputValidator.validateAggregateArgs(this.model, normalizedArgs);
3659
3991
  let query = this.kysely.selectFrom((eb) => {
3660
- let subQuery = eb.selectFrom(this.model).selectAll(this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
3992
+ let subQuery = this.dialect.buildSelectModel(eb, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
3993
+ const selectedFields = [];
3994
+ for (const [key, value] of Object.entries(parsedArgs)) {
3995
+ if (key.startsWith("_") && value && typeof value === "object") {
3996
+ Object.entries(value).filter(([field]) => field !== "_all").filter(([, val]) => val === true).forEach(([field]) => {
3997
+ if (!selectedFields.includes(field)) selectedFields.push(field);
3998
+ });
3999
+ }
4000
+ }
4001
+ if (selectedFields.length > 0) {
4002
+ for (const field of selectedFields) {
4003
+ subQuery = this.dialect.buildSelectField(subQuery, this.model, this.model, field);
4004
+ }
4005
+ } else {
4006
+ subQuery = subQuery.select(() => eb.lit(1).as("_all"));
4007
+ }
3661
4008
  const skip = parsedArgs?.skip;
3662
4009
  let take = parsedArgs?.take;
3663
4010
  let negateOrderBy = false;
@@ -3703,9 +4050,9 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
3703
4050
  }
3704
4051
  }
3705
4052
  }
3706
- const result = await query.executeTakeFirstOrThrow();
4053
+ const result = await this.executeQuery(this.kysely, query, "aggregate");
3707
4054
  const ret = {};
3708
- for (const [key, value] of Object.entries(result)) {
4055
+ for (const [key, value] of Object.entries(result.rows[0])) {
3709
4056
  if (key === "_count") {
3710
4057
  ret[key] = value;
3711
4058
  continue;
@@ -3750,18 +4097,29 @@ var CountOperationHandler = class extends BaseOperationHandler {
3750
4097
  async handle(_operation, args) {
3751
4098
  const normalizedArgs = this.normalizeArgs(args);
3752
4099
  const parsedArgs = this.inputValidator.validateCountArgs(this.model, normalizedArgs);
4100
+ const subQueryName = "$sub";
3753
4101
  let query = this.kysely.selectFrom((eb) => {
3754
- let subQuery = eb.selectFrom(this.model).selectAll().where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
4102
+ let subQuery = this.dialect.buildSelectModel(eb, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
4103
+ if (parsedArgs?.select && typeof parsedArgs.select === "object") {
4104
+ for (const [key, value] of Object.entries(parsedArgs.select)) {
4105
+ if (key !== "_all" && value === true) {
4106
+ subQuery = this.dialect.buildSelectField(subQuery, this.model, this.model, key);
4107
+ }
4108
+ }
4109
+ } else {
4110
+ subQuery = subQuery.select(() => eb.lit(1).as("_all"));
4111
+ }
3755
4112
  subQuery = this.dialect.buildSkipTake(subQuery, parsedArgs?.skip, parsedArgs?.take);
3756
- return subQuery.as("$sub");
4113
+ return subQuery.as(subQueryName);
3757
4114
  });
3758
4115
  if (parsedArgs?.select && typeof parsedArgs.select === "object") {
3759
- query = query.select((eb) => Object.keys(parsedArgs.select).map((key) => key === "_all" ? eb.cast(eb.fn.countAll(), "integer").as("_all") : eb.cast(eb.fn.count(import_kysely10.sql.ref(`$sub.${key}`)), "integer").as(key)));
3760
- return query.executeTakeFirstOrThrow();
4116
+ query = query.select((eb) => Object.keys(parsedArgs.select).map((key) => key === "_all" ? eb.cast(eb.fn.countAll(), "integer").as("_all") : eb.cast(eb.fn.count(import_kysely10.sql.ref(`${subQueryName}.${key}`)), "integer").as(key)));
4117
+ const result = await this.executeQuery(this.kysely, query, "count");
4118
+ return result.rows[0];
3761
4119
  } else {
3762
4120
  query = query.select((eb) => eb.cast(eb.fn.countAll(), "integer").as("count"));
3763
- const result = await query.executeTakeFirstOrThrow();
3764
- return result.count;
4121
+ const result = await this.executeQuery(this.kysely, query, "count");
4122
+ return result.rows[0].count;
3765
4123
  }
3766
4124
  }
3767
4125
  };
@@ -3840,15 +4198,19 @@ var DeleteOperationHandler = class extends BaseOperationHandler {
3840
4198
  if (!existing) {
3841
4199
  throw new NotFoundError(this.model);
3842
4200
  }
3843
- const result = await this.delete(this.kysely, this.model, args.where, void 0, false);
3844
- if (result.count === 0) {
3845
- throw new NotFoundError(this.model);
3846
- }
4201
+ await this.safeTransaction(async (tx) => {
4202
+ const result = await this.delete(tx, this.model, args.where);
4203
+ if (result.count === 0) {
4204
+ throw new NotFoundError(this.model);
4205
+ }
4206
+ });
3847
4207
  return existing;
3848
4208
  }
3849
4209
  async runDeleteMany(args) {
3850
- const result = await this.delete(this.kysely, this.model, args?.where, args?.limit, false);
3851
- return result;
4210
+ return await this.safeTransaction(async (tx) => {
4211
+ const result = await this.delete(tx, this.model, args?.where, args?.limit);
4212
+ return result;
4213
+ });
3852
4214
  }
3853
4215
  };
3854
4216
 
@@ -3936,8 +4298,8 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
3936
4298
  }
3937
4299
  }
3938
4300
  }
3939
- const result = await query.execute();
3940
- return result.map((row) => this.postProcessRow(row));
4301
+ const result = await this.executeQuery(this.kysely, query, "groupBy");
4302
+ return result.rows.map((row) => this.postProcessRow(row));
3941
4303
  }
3942
4304
  postProcessRow(row) {
3943
4305
  const ret = {};
@@ -3989,22 +4351,35 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
3989
4351
  return (0, import_ts_pattern13.match)(operation).with("update", () => this.runUpdate(this.inputValidator.validateUpdateArgs(this.model, normalizedArgs))).with("updateMany", () => this.runUpdateMany(this.inputValidator.validateUpdateManyArgs(this.model, normalizedArgs))).with("updateManyAndReturn", () => this.runUpdateManyAndReturn(this.inputValidator.validateUpdateManyAndReturnArgs(this.model, normalizedArgs))).with("upsert", () => this.runUpsert(this.inputValidator.validateUpsertArgs(this.model, normalizedArgs))).exhaustive();
3990
4352
  }
3991
4353
  async runUpdate(args) {
3992
- const result = await this.safeTransaction(async (tx) => {
3993
- const updated = await this.update(tx, this.model, args.where, args.data);
3994
- return this.readUnique(tx, this.model, {
3995
- select: args.select,
3996
- include: args.include,
3997
- omit: args.omit,
3998
- where: getIdValues(this.schema, this.model, updated)
3999
- });
4354
+ const readBackResult = await this.safeTransaction(async (tx) => {
4355
+ const updateResult = await this.update(tx, this.model, args.where, args.data);
4356
+ const readFilter = updateResult ?? args.where;
4357
+ let readBackResult2 = void 0;
4358
+ try {
4359
+ readBackResult2 = await this.readUnique(tx, this.model, {
4360
+ select: args.select,
4361
+ include: args.include,
4362
+ omit: args.omit,
4363
+ where: readFilter
4364
+ });
4365
+ } catch {
4366
+ }
4367
+ return readBackResult2;
4000
4368
  });
4001
- if (!result && this.hasPolicyEnabled) {
4002
- throw new RejectedByPolicyError(this.model, "result is not allowed to be read back");
4369
+ if (!readBackResult) {
4370
+ if (this.hasPolicyEnabled) {
4371
+ throw new RejectedByPolicyError(this.model, "result is not allowed to be read back");
4372
+ } else {
4373
+ return null;
4374
+ }
4375
+ } else {
4376
+ return readBackResult;
4003
4377
  }
4004
- return result;
4005
4378
  }
4006
4379
  async runUpdateMany(args) {
4007
- return this.updateMany(this.kysely, this.model, args.where, args.data, args.limit, false);
4380
+ return this.safeTransaction(async (tx) => {
4381
+ return this.updateMany(tx, this.model, args.where, args.data, args.limit, false);
4382
+ });
4008
4383
  }
4009
4384
  async runUpdateManyAndReturn(args) {
4010
4385
  if (!args) {
@@ -4143,17 +4518,45 @@ var InputValidator = class {
4143
4518
  return result;
4144
4519
  }
4145
4520
  makePrimitiveSchema(type) {
4146
- return (0, import_ts_pattern14.match)(type).with("String", () => import_zod.z.string()).with("Int", () => import_zod.z.number()).with("Float", () => import_zod.z.number()).with("Boolean", () => import_zod.z.boolean()).with("BigInt", () => import_zod.z.union([
4147
- import_zod.z.number(),
4148
- import_zod.z.bigint()
4149
- ])).with("Decimal", () => import_zod.z.union([
4150
- import_zod.z.number(),
4151
- import_zod.z.instanceof(import_decimal.default),
4152
- import_zod.z.string()
4153
- ])).with("DateTime", () => import_zod.z.union([
4154
- import_zod.z.date(),
4155
- import_zod.z.string().datetime()
4156
- ])).with("Bytes", () => import_zod.z.instanceof(Uint8Array)).otherwise(() => import_zod.z.unknown());
4521
+ if (this.schema.typeDefs && type in this.schema.typeDefs) {
4522
+ return this.makeTypeDefSchema(type);
4523
+ } else {
4524
+ return (0, import_ts_pattern14.match)(type).with("String", () => import_zod.z.string()).with("Int", () => import_zod.z.number()).with("Float", () => import_zod.z.number()).with("Boolean", () => import_zod.z.boolean()).with("BigInt", () => import_zod.z.union([
4525
+ import_zod.z.number(),
4526
+ import_zod.z.bigint()
4527
+ ])).with("Decimal", () => import_zod.z.union([
4528
+ import_zod.z.number(),
4529
+ import_zod.z.instanceof(import_decimal.default),
4530
+ import_zod.z.string()
4531
+ ])).with("DateTime", () => import_zod.z.union([
4532
+ import_zod.z.date(),
4533
+ import_zod.z.string().datetime()
4534
+ ])).with("Bytes", () => import_zod.z.instanceof(Uint8Array)).otherwise(() => import_zod.z.unknown());
4535
+ }
4536
+ }
4537
+ makeTypeDefSchema(type) {
4538
+ const key = `$typedef-${type}`;
4539
+ let schema = this.schemaCache.get(key);
4540
+ if (schema) {
4541
+ return schema;
4542
+ }
4543
+ const typeDef = this.schema.typeDefs?.[type];
4544
+ (0, import_common_helpers9.invariant)(typeDef, `Type definition "${type}" not found in schema`);
4545
+ schema = import_zod.z.looseObject(Object.fromEntries(Object.entries(typeDef.fields).map(([field, def]) => {
4546
+ let fieldSchema = this.makePrimitiveSchema(def.type);
4547
+ if (def.array) {
4548
+ fieldSchema = fieldSchema.array();
4549
+ }
4550
+ if (def.optional) {
4551
+ fieldSchema = fieldSchema.optional();
4552
+ }
4553
+ return [
4554
+ field,
4555
+ fieldSchema
4556
+ ];
4557
+ })));
4558
+ this.schemaCache.set(key, schema);
4559
+ return schema;
4157
4560
  }
4158
4561
  makeWhereSchema(model, unique, withoutRelationFields = false) {
4159
4562
  const modelDef = getModel(this.schema, model);
@@ -4275,8 +4678,14 @@ var InputValidator = class {
4275
4678
  });
4276
4679
  }
4277
4680
  makePrimitiveFilterSchema(type, optional) {
4681
+ if (this.schema.typeDefs && type in this.schema.typeDefs) {
4682
+ return this.makeTypeDefFilterSchema(type, optional);
4683
+ }
4278
4684
  return (0, import_ts_pattern14.match)(type).with("String", () => this.makeStringFilterSchema(optional)).with(import_ts_pattern14.P.union("Int", "Float", "Decimal", "BigInt"), (type2) => this.makeNumberFilterSchema(this.makePrimitiveSchema(type2), optional)).with("Boolean", () => this.makeBooleanFilterSchema(optional)).with("DateTime", () => this.makeDateTimeFilterSchema(optional)).with("Bytes", () => this.makeBytesFilterSchema(optional)).with("Json", () => import_zod.z.any()).with("Unsupported", () => import_zod.z.never()).exhaustive();
4279
4685
  }
4686
+ makeTypeDefFilterSchema(_type, _optional) {
4687
+ return import_zod.z.never();
4688
+ }
4280
4689
  makeDateTimeFilterSchema(optional) {
4281
4690
  return this.makeCommonPrimitiveFilterSchema(import_zod.z.union([
4282
4691
  import_zod.z.string().datetime(),
@@ -4481,6 +4890,9 @@ var InputValidator = class {
4481
4890
  if (fieldDef.computed) {
4482
4891
  return;
4483
4892
  }
4893
+ if (this.isDelegateDiscriminator(fieldDef)) {
4894
+ return;
4895
+ }
4484
4896
  if (fieldDef.relation) {
4485
4897
  if (withoutRelationFields) {
4486
4898
  return;
@@ -4553,6 +4965,13 @@ var InputValidator = class {
4553
4965
  ]);
4554
4966
  }
4555
4967
  }
4968
+ isDelegateDiscriminator(fieldDef) {
4969
+ if (!fieldDef.originModel) {
4970
+ return false;
4971
+ }
4972
+ const discriminatorField = getDiscriminatorField(this.schema, fieldDef.originModel);
4973
+ return discriminatorField === fieldDef.name;
4974
+ }
4556
4975
  makeRelationManipulationSchema(fieldDef, withoutFields, mode) {
4557
4976
  const fieldType = fieldDef.type;
4558
4977
  const array = !!fieldDef.array;
@@ -4883,11 +5302,11 @@ var ZenStackDriver = class {
4883
5302
  }
4884
5303
  #driver;
4885
5304
  #log;
4886
- txConnection;
4887
5305
  #initPromise;
4888
5306
  #initDone;
4889
5307
  #destroyPromise;
4890
5308
  #connections = /* @__PURE__ */ new WeakSet();
5309
+ #txConnections = /* @__PURE__ */ new WeakMap();
4891
5310
  constructor(driver, log) {
4892
5311
  this.#initDone = false;
4893
5312
  this.#driver = driver;
@@ -4928,21 +5347,30 @@ var ZenStackDriver = class {
4928
5347
  }
4929
5348
  async beginTransaction(connection, settings) {
4930
5349
  const result = await this.#driver.beginTransaction(connection, settings);
4931
- this.txConnection = connection;
5350
+ this.#txConnections.set(connection, []);
4932
5351
  return result;
4933
5352
  }
4934
- commitTransaction(connection) {
5353
+ async commitTransaction(connection) {
4935
5354
  try {
4936
- return this.#driver.commitTransaction(connection);
4937
- } finally {
4938
- this.txConnection = void 0;
5355
+ const result = await this.#driver.commitTransaction(connection);
5356
+ const callbacks = this.#txConnections.get(connection);
5357
+ this.#txConnections.delete(connection);
5358
+ if (callbacks) {
5359
+ for (const callback of callbacks) {
5360
+ await callback();
5361
+ }
5362
+ }
5363
+ return result;
5364
+ } catch (err) {
5365
+ this.#txConnections.delete(connection);
5366
+ throw err;
4939
5367
  }
4940
5368
  }
4941
- rollbackTransaction(connection) {
5369
+ async rollbackTransaction(connection) {
4942
5370
  try {
4943
- return this.#driver.rollbackTransaction(connection);
5371
+ return await this.#driver.rollbackTransaction(connection);
4944
5372
  } finally {
4945
- this.txConnection = void 0;
5373
+ this.#txConnections.delete(connection);
4946
5374
  }
4947
5375
  }
4948
5376
  async destroy() {
@@ -5020,6 +5448,22 @@ var ZenStackDriver = class {
5020
5448
  #calculateDurationMillis(startTime) {
5021
5449
  return performanceNow() - startTime;
5022
5450
  }
5451
+ isTransactionConnection(connection) {
5452
+ return this.#txConnections.has(connection);
5453
+ }
5454
+ registerTransactionCommitCallback(connection, callback) {
5455
+ if (!this.#txConnections.has(connection)) {
5456
+ return;
5457
+ }
5458
+ const callbacks = this.#txConnections.get(connection);
5459
+ if (callbacks) {
5460
+ callbacks.push(callback);
5461
+ } else {
5462
+ this.#txConnections.set(connection, [
5463
+ callback
5464
+ ]);
5465
+ }
5466
+ }
5023
5467
  };
5024
5468
  function performanceNow() {
5025
5469
  if (typeof performance !== "undefined" && typeof performance.now === "function") {
@@ -5236,7 +5680,7 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
5236
5680
  this.requireCurrentModel(contextNode);
5237
5681
  model = model ?? this.currentModel;
5238
5682
  const modelDef = requireModel(this.schema, model);
5239
- const scalarFields = Object.entries(modelDef.fields).filter(([, fieldDef]) => !fieldDef.relation && !fieldDef.computed).map(([fieldName]) => fieldName);
5683
+ const scalarFields = Object.entries(modelDef.fields).filter(([, fieldDef]) => !fieldDef.relation && !fieldDef.computed && !fieldDef.originModel).map(([fieldName]) => fieldName);
5240
5684
  return scalarFields;
5241
5685
  }
5242
5686
  };
@@ -5261,7 +5705,7 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5261
5705
  get options() {
5262
5706
  return this.client.$options;
5263
5707
  }
5264
- async executeQuery(compiledQuery, queryId) {
5708
+ async executeQuery(compiledQuery, _queryId) {
5265
5709
  let queryNode = compiledQuery.query;
5266
5710
  let mutationInterceptionInfo;
5267
5711
  if (this.isMutationNode(queryNode) && this.hasMutationHooks) {
@@ -5272,7 +5716,7 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5272
5716
  await this.callBeforeMutationHooks(queryNode, mutationInterceptionInfo);
5273
5717
  }
5274
5718
  const oldQueryNode = queryNode;
5275
- if ((import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.DeleteQueryNode.is(queryNode)) && mutationInterceptionInfo?.loadAfterMutationEntity) {
5719
+ if ((import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.UpdateQueryNode.is(queryNode)) && mutationInterceptionInfo?.loadAfterMutationEntity) {
5276
5720
  queryNode = {
5277
5721
  ...queryNode,
5278
5722
  returning: import_kysely13.ReturningNode.create([
@@ -5281,34 +5725,49 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5281
5725
  };
5282
5726
  }
5283
5727
  const queryParams = compiledQuery.$raw ? compiledQuery.parameters : void 0;
5284
- const result = await this.proceedQueryWithKyselyInterceptors(queryNode, queryParams, queryId);
5728
+ const result = await this.proceedQueryWithKyselyInterceptors(queryNode, queryParams);
5285
5729
  if (this.isMutationNode(queryNode)) {
5286
- await this.callAfterQueryInterceptionFilters(result, queryNode, mutationInterceptionInfo);
5730
+ await this.callAfterMutationHooks(result.result, queryNode, mutationInterceptionInfo, result.connection);
5287
5731
  }
5288
5732
  if (oldQueryNode !== queryNode) {
5289
5733
  }
5290
- return result;
5734
+ return result.result;
5291
5735
  }, "task");
5292
5736
  return task();
5293
5737
  }
5294
- proceedQueryWithKyselyInterceptors(queryNode, parameters, queryId) {
5295
- let proceed = /* @__PURE__ */ __name((q) => this.proceedQuery(q, parameters, queryId), "proceed");
5296
- const hooks = this.options.plugins?.filter((plugin) => typeof plugin.onKyselyQuery === "function").map((plugin) => plugin.onKyselyQuery.bind(plugin)) ?? [];
5738
+ proceedQueryWithKyselyInterceptors(queryNode, parameters) {
5739
+ let proceed = /* @__PURE__ */ __name((q) => this.proceedQuery(q, parameters), "proceed");
5740
+ const hooks = [];
5741
+ for (const plugin of this.client.$options.plugins ?? []) {
5742
+ if (plugin.onKyselyQuery) {
5743
+ hooks.push(plugin.onKyselyQuery.bind(plugin));
5744
+ }
5745
+ }
5297
5746
  for (const hook of hooks) {
5298
5747
  const _proceed = proceed;
5299
- proceed = /* @__PURE__ */ __name((query) => {
5300
- return hook({
5748
+ proceed = /* @__PURE__ */ __name(async (query) => {
5749
+ let connection;
5750
+ const _p = /* @__PURE__ */ __name(async (q) => {
5751
+ const r = await _proceed(q);
5752
+ connection = r.connection;
5753
+ return r.result;
5754
+ }, "_p");
5755
+ const hookResult = await hook({
5301
5756
  client: this.client,
5302
5757
  schema: this.client.$schema,
5303
5758
  kysely: this.kysely,
5304
5759
  query,
5305
- proceed: _proceed
5760
+ proceed: _p
5306
5761
  });
5762
+ return {
5763
+ result: hookResult,
5764
+ connection
5765
+ };
5307
5766
  }, "proceed");
5308
5767
  }
5309
5768
  return proceed(queryNode);
5310
5769
  }
5311
- async proceedQuery(query, parameters, queryId) {
5770
+ async proceedQuery(query, parameters) {
5312
5771
  const finalQuery = this.nameMapper.transformNode(query);
5313
5772
  let compiled = this.compileQuery(finalQuery);
5314
5773
  if (parameters) {
@@ -5318,7 +5777,13 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5318
5777
  };
5319
5778
  }
5320
5779
  try {
5321
- return await super.executeQuery(compiled, queryId);
5780
+ return await this.provideConnection(async (connection) => {
5781
+ const result = await connection.executeQuery(compiled);
5782
+ return {
5783
+ result,
5784
+ connection
5785
+ };
5786
+ });
5322
5787
  } catch (err) {
5323
5788
  let message = `Failed to execute query: ${err}, sql: ${compiled.sql}`;
5324
5789
  if (this.options.debug) {
@@ -5421,10 +5886,11 @@ ${compiled.parameters.map((p) => (0, import_node_util2.inspect)(p)).join("\n")}`
5421
5886
  return;
5422
5887
  }
5423
5888
  if (this.options.plugins) {
5889
+ const mutationModel = this.getMutationModel(queryNode);
5424
5890
  for (const plugin of this.options.plugins) {
5425
5891
  if (plugin.beforeEntityMutation) {
5426
5892
  await plugin.beforeEntityMutation({
5427
- model: this.getMutationModel(queryNode),
5893
+ model: mutationModel,
5428
5894
  action: mutationInterceptionInfo.action,
5429
5895
  queryNode,
5430
5896
  entities: mutationInterceptionInfo.beforeMutationEntities
@@ -5433,30 +5899,45 @@ ${compiled.parameters.map((p) => (0, import_node_util2.inspect)(p)).join("\n")}`
5433
5899
  }
5434
5900
  }
5435
5901
  }
5436
- async callAfterQueryInterceptionFilters(queryResult, queryNode, mutationInterceptionInfo) {
5902
+ async callAfterMutationHooks(queryResult, queryNode, mutationInterceptionInfo, connection) {
5437
5903
  if (!mutationInterceptionInfo?.intercept) {
5438
5904
  return;
5439
5905
  }
5440
- if (this.options.plugins) {
5441
- const mutationModel = this.getMutationModel(queryNode);
5442
- for (const plugin of this.options.plugins) {
5443
- if (plugin.afterEntityMutation) {
5444
- let afterMutationEntities = void 0;
5445
- if (mutationInterceptionInfo.loadAfterMutationEntity) {
5446
- if (import_kysely13.UpdateQueryNode.is(queryNode)) {
5447
- afterMutationEntities = await this.loadEntities(mutationModel, mutationInterceptionInfo.where);
5448
- } else {
5449
- afterMutationEntities = queryResult.rows;
5450
- }
5451
- }
5452
- await plugin.afterEntityMutation({
5453
- model: this.getMutationModel(queryNode),
5906
+ const hooks = [];
5907
+ for (const plugin of this.options.plugins ?? []) {
5908
+ if (plugin.afterEntityMutation) {
5909
+ hooks.push(plugin.afterEntityMutation.bind(plugin));
5910
+ }
5911
+ }
5912
+ if (hooks.length === 0) {
5913
+ return;
5914
+ }
5915
+ const mutationModel = this.getMutationModel(queryNode);
5916
+ const inTransaction = this.driver.isTransactionConnection(connection);
5917
+ for (const hook of hooks) {
5918
+ let afterMutationEntities = void 0;
5919
+ if (mutationInterceptionInfo.loadAfterMutationEntity) {
5920
+ if (import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.UpdateQueryNode.is(queryNode)) {
5921
+ afterMutationEntities = queryResult.rows;
5922
+ }
5923
+ }
5924
+ const action = /* @__PURE__ */ __name(async () => {
5925
+ try {
5926
+ await hook({
5927
+ model: mutationModel,
5454
5928
  action: mutationInterceptionInfo.action,
5455
5929
  queryNode,
5456
5930
  beforeMutationEntities: mutationInterceptionInfo.beforeMutationEntities,
5457
5931
  afterMutationEntities
5458
5932
  });
5933
+ } catch (err) {
5934
+ console.error(`Error in afterEntityMutation hook for model "${mutationModel}": ${err}`);
5459
5935
  }
5936
+ }, "action");
5937
+ if (inTransaction) {
5938
+ this.driver.registerTransactionCommitCallback(connection, action);
5939
+ } else {
5940
+ await action();
5460
5941
  }
5461
5942
  }
5462
5943
  }
@@ -5653,7 +6134,7 @@ var SchemaDbPusher = class {
5653
6134
  }
5654
6135
  }
5655
6136
  table = this.addPrimaryKeyConstraint(table, model, modelDef);
5656
- table = this.addUniqueConstraint(table, modelDef);
6137
+ table = this.addUniqueConstraint(table, model, modelDef);
5657
6138
  return table;
5658
6139
  }
5659
6140
  isComputedField(fieldDef) {
@@ -5670,7 +6151,7 @@ var SchemaDbPusher = class {
5670
6151
  }
5671
6152
  return table;
5672
6153
  }
5673
- addUniqueConstraint(table, modelDef) {
6154
+ addUniqueConstraint(table, model, modelDef) {
5674
6155
  for (const [key, value] of Object.entries(modelDef.uniqueFields)) {
5675
6156
  (0, import_common_helpers11.invariant)(typeof value === "object", "expecting an object");
5676
6157
  if ("type" in value) {
@@ -5678,8 +6159,11 @@ var SchemaDbPusher = class {
5678
6159
  if (fieldDef.unique) {
5679
6160
  continue;
5680
6161
  }
6162
+ table = table.addUniqueConstraint(`unique_${model}_${key}`, [
6163
+ key
6164
+ ]);
5681
6165
  } else {
5682
- table = table.addUniqueConstraint(`unique_${key}`, Object.keys(value));
6166
+ table = table.addUniqueConstraint(`unique_${model}_${key}`, Object.keys(value));
5683
6167
  }
5684
6168
  }
5685
6169
  return table;
@@ -5822,6 +6306,21 @@ var ResultProcessor = class {
5822
6306
  data[key] = typeof value === "string" ? JSON.parse(value) : value;
5823
6307
  continue;
5824
6308
  }
6309
+ if (key.startsWith(DELEGATE_JOINED_FIELD_PREFIX)) {
6310
+ if (value) {
6311
+ const subRow = this.transformJson(value);
6312
+ const subModel = key.slice(DELEGATE_JOINED_FIELD_PREFIX.length);
6313
+ const idValues = getIdValues(this.schema, subModel, subRow);
6314
+ if (Object.values(idValues).some((v) => v === null || v === void 0)) {
6315
+ delete data[key];
6316
+ continue;
6317
+ }
6318
+ const processedSubRow = this.processRow(subRow, subModel);
6319
+ Object.assign(data, processedSubRow);
6320
+ }
6321
+ delete data[key];
6322
+ continue;
6323
+ }
5825
6324
  const fieldDef = getField(this.schema, model, key);
5826
6325
  if (!fieldDef) {
5827
6326
  continue;
@@ -5861,7 +6360,11 @@ var ResultProcessor = class {
5861
6360
  return this.doProcessResult(relationData, fieldDef.type);
5862
6361
  }
5863
6362
  transformScalar(value, type) {
5864
- return (0, import_ts_pattern18.match)(type).with("Boolean", () => this.transformBoolean(value)).with("DateTime", () => this.transformDate(value)).with("Bytes", () => this.transformBytes(value)).with("Decimal", () => this.transformDecimal(value)).with("BigInt", () => this.transformBigInt(value)).with("Json", () => this.transformJson(value)).otherwise(() => value);
6363
+ if (this.schema.typeDefs && type in this.schema.typeDefs) {
6364
+ return this.transformJson(value);
6365
+ } else {
6366
+ return (0, import_ts_pattern18.match)(type).with("Boolean", () => this.transformBoolean(value)).with("DateTime", () => this.transformDate(value)).with("Bytes", () => this.transformBytes(value)).with("Decimal", () => this.transformDecimal(value)).with("BigInt", () => this.transformBigInt(value)).with("Json", () => this.transformJson(value)).otherwise(() => value);
6367
+ }
5865
6368
  }
5866
6369
  transformDecimal(value) {
5867
6370
  if (value instanceof import_decimal2.default) {
@@ -6073,19 +6576,26 @@ var ClientImpl = class _ClientImpl {
6073
6576
  await new SchemaDbPusher(this.schema, this.kysely).push();
6074
6577
  }
6075
6578
  $use(plugin) {
6579
+ const newPlugins = [
6580
+ ...this.$options.plugins ?? [],
6581
+ plugin
6582
+ ];
6076
6583
  const newOptions = {
6077
6584
  ...this.options,
6078
- plugins: [
6079
- ...this.options.plugins ?? [],
6080
- plugin
6081
- ]
6585
+ plugins: newPlugins
6082
6586
  };
6083
6587
  return new _ClientImpl(this.schema, newOptions, this);
6084
6588
  }
6085
6589
  $unuse(pluginId) {
6590
+ const newPlugins = [];
6591
+ for (const plugin of this.options.plugins ?? []) {
6592
+ if (plugin.id !== pluginId) {
6593
+ newPlugins.push(plugin);
6594
+ }
6595
+ }
6086
6596
  const newOptions = {
6087
6597
  ...this.options,
6088
- plugins: this.options.plugins?.filter((p) => p.id !== pluginId)
6598
+ plugins: newPlugins
6089
6599
  };
6090
6600
  return new _ClientImpl(this.schema, newOptions, this);
6091
6601
  }