@zenstackhq/runtime 3.0.0-alpha.11 → 3.0.0-alpha.13

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 {
@@ -2542,7 +2676,7 @@ var BaseOperationHandler = class {
2542
2676
  return query.executeTakeFirst();
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) {
@@ -2746,9 +2879,13 @@ ${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
  }));
@@ -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,6 +3109,13 @@ ${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"
@@ -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,9 +3295,7 @@ ${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({
@@ -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,25 +3399,43 @@ ${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,
@@ -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 = [];
@@ -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 query.executeTakeFirstOrThrow();
3864
+ return {
3865
+ count: Number(result.numDeletedRows)
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
  }
@@ -3657,7 +3970,22 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
3657
3970
  const normalizedArgs = this.normalizeArgs(args);
3658
3971
  const parsedArgs = this.inputValidator.validateAggregateArgs(this.model, normalizedArgs);
3659
3972
  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));
3973
+ let subQuery = this.dialect.buildSelectModel(eb, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
3974
+ const selectedFields = [];
3975
+ for (const [key, value] of Object.entries(parsedArgs)) {
3976
+ if (key.startsWith("_") && value && typeof value === "object") {
3977
+ Object.entries(value).filter(([field]) => field !== "_all").filter(([, val]) => val === true).forEach(([field]) => {
3978
+ if (!selectedFields.includes(field)) selectedFields.push(field);
3979
+ });
3980
+ }
3981
+ }
3982
+ if (selectedFields.length > 0) {
3983
+ for (const field of selectedFields) {
3984
+ subQuery = this.dialect.buildSelectField(subQuery, this.model, this.model, field);
3985
+ }
3986
+ } else {
3987
+ subQuery = subQuery.select(() => eb.lit(1).as("_all"));
3988
+ }
3661
3989
  const skip = parsedArgs?.skip;
3662
3990
  let take = parsedArgs?.take;
3663
3991
  let negateOrderBy = false;
@@ -3750,13 +4078,23 @@ var CountOperationHandler = class extends BaseOperationHandler {
3750
4078
  async handle(_operation, args) {
3751
4079
  const normalizedArgs = this.normalizeArgs(args);
3752
4080
  const parsedArgs = this.inputValidator.validateCountArgs(this.model, normalizedArgs);
4081
+ const subQueryName = "$sub";
3753
4082
  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));
4083
+ let subQuery = this.dialect.buildSelectModel(eb, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
4084
+ if (parsedArgs?.select && typeof parsedArgs.select === "object") {
4085
+ for (const [key, value] of Object.entries(parsedArgs.select)) {
4086
+ if (key !== "_all" && value === true) {
4087
+ subQuery = this.dialect.buildSelectField(subQuery, this.model, this.model, key);
4088
+ }
4089
+ }
4090
+ } else {
4091
+ subQuery = subQuery.select(() => eb.lit(1).as("_all"));
4092
+ }
3755
4093
  subQuery = this.dialect.buildSkipTake(subQuery, parsedArgs?.skip, parsedArgs?.take);
3756
- return subQuery.as("$sub");
4094
+ return subQuery.as(subQueryName);
3757
4095
  });
3758
4096
  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)));
4097
+ 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)));
3760
4098
  return query.executeTakeFirstOrThrow();
3761
4099
  } else {
3762
4100
  query = query.select((eb) => eb.cast(eb.fn.countAll(), "integer").as("count"));
@@ -3840,15 +4178,19 @@ var DeleteOperationHandler = class extends BaseOperationHandler {
3840
4178
  if (!existing) {
3841
4179
  throw new NotFoundError(this.model);
3842
4180
  }
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
- }
4181
+ await this.safeTransaction(async (tx) => {
4182
+ const result = await this.delete(tx, this.model, args.where, void 0);
4183
+ if (result.count === 0) {
4184
+ throw new NotFoundError(this.model);
4185
+ }
4186
+ });
3847
4187
  return existing;
3848
4188
  }
3849
4189
  async runDeleteMany(args) {
3850
- const result = await this.delete(this.kysely, this.model, args?.where, args?.limit, false);
3851
- return result;
4190
+ return await this.safeTransaction(async (tx) => {
4191
+ const result = await this.delete(tx, this.model, args?.where, args?.limit);
4192
+ return result;
4193
+ });
3852
4194
  }
3853
4195
  };
3854
4196
 
@@ -3989,22 +4331,35 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
3989
4331
  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
4332
  }
3991
4333
  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
- });
4334
+ const readBackResult = await this.safeTransaction(async (tx) => {
4335
+ const updateResult = await this.update(tx, this.model, args.where, args.data);
4336
+ const readFilter = updateResult ?? args.where;
4337
+ let readBackResult2 = void 0;
4338
+ try {
4339
+ readBackResult2 = await this.readUnique(tx, this.model, {
4340
+ select: args.select,
4341
+ include: args.include,
4342
+ omit: args.omit,
4343
+ where: readFilter
4344
+ });
4345
+ } catch {
4346
+ }
4347
+ return readBackResult2;
4000
4348
  });
4001
- if (!result && this.hasPolicyEnabled) {
4002
- throw new RejectedByPolicyError(this.model, "result is not allowed to be read back");
4349
+ if (!readBackResult) {
4350
+ if (this.hasPolicyEnabled) {
4351
+ throw new RejectedByPolicyError(this.model, "result is not allowed to be read back");
4352
+ } else {
4353
+ return null;
4354
+ }
4355
+ } else {
4356
+ return readBackResult;
4003
4357
  }
4004
- return result;
4005
4358
  }
4006
4359
  async runUpdateMany(args) {
4007
- return this.updateMany(this.kysely, this.model, args.where, args.data, args.limit, false);
4360
+ return this.safeTransaction(async (tx) => {
4361
+ return this.updateMany(tx, this.model, args.where, args.data, args.limit, false);
4362
+ });
4008
4363
  }
4009
4364
  async runUpdateManyAndReturn(args) {
4010
4365
  if (!args) {
@@ -4143,17 +4498,45 @@ var InputValidator = class {
4143
4498
  return result;
4144
4499
  }
4145
4500
  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());
4501
+ if (this.schema.typeDefs && type in this.schema.typeDefs) {
4502
+ return this.makeTypeDefSchema(type);
4503
+ } else {
4504
+ 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([
4505
+ import_zod.z.number(),
4506
+ import_zod.z.bigint()
4507
+ ])).with("Decimal", () => import_zod.z.union([
4508
+ import_zod.z.number(),
4509
+ import_zod.z.instanceof(import_decimal.default),
4510
+ import_zod.z.string()
4511
+ ])).with("DateTime", () => import_zod.z.union([
4512
+ import_zod.z.date(),
4513
+ import_zod.z.string().datetime()
4514
+ ])).with("Bytes", () => import_zod.z.instanceof(Uint8Array)).otherwise(() => import_zod.z.unknown());
4515
+ }
4516
+ }
4517
+ makeTypeDefSchema(type) {
4518
+ const key = `$typedef-${type}`;
4519
+ let schema = this.schemaCache.get(key);
4520
+ if (schema) {
4521
+ return schema;
4522
+ }
4523
+ const typeDef = this.schema.typeDefs?.[type];
4524
+ (0, import_common_helpers9.invariant)(typeDef, `Type definition "${type}" not found in schema`);
4525
+ schema = import_zod.z.looseObject(Object.fromEntries(Object.entries(typeDef.fields).map(([field, def]) => {
4526
+ let fieldSchema = this.makePrimitiveSchema(def.type);
4527
+ if (def.array) {
4528
+ fieldSchema = fieldSchema.array();
4529
+ }
4530
+ if (def.optional) {
4531
+ fieldSchema = fieldSchema.optional();
4532
+ }
4533
+ return [
4534
+ field,
4535
+ fieldSchema
4536
+ ];
4537
+ })));
4538
+ this.schemaCache.set(key, schema);
4539
+ return schema;
4157
4540
  }
4158
4541
  makeWhereSchema(model, unique, withoutRelationFields = false) {
4159
4542
  const modelDef = getModel(this.schema, model);
@@ -4275,8 +4658,14 @@ var InputValidator = class {
4275
4658
  });
4276
4659
  }
4277
4660
  makePrimitiveFilterSchema(type, optional) {
4661
+ if (this.schema.typeDefs && type in this.schema.typeDefs) {
4662
+ return this.makeTypeDefFilterSchema(type, optional);
4663
+ }
4278
4664
  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
4665
  }
4666
+ makeTypeDefFilterSchema(_type, _optional) {
4667
+ return import_zod.z.never();
4668
+ }
4280
4669
  makeDateTimeFilterSchema(optional) {
4281
4670
  return this.makeCommonPrimitiveFilterSchema(import_zod.z.union([
4282
4671
  import_zod.z.string().datetime(),
@@ -4481,6 +4870,9 @@ var InputValidator = class {
4481
4870
  if (fieldDef.computed) {
4482
4871
  return;
4483
4872
  }
4873
+ if (this.isDelegateDiscriminator(fieldDef)) {
4874
+ return;
4875
+ }
4484
4876
  if (fieldDef.relation) {
4485
4877
  if (withoutRelationFields) {
4486
4878
  return;
@@ -4553,6 +4945,13 @@ var InputValidator = class {
4553
4945
  ]);
4554
4946
  }
4555
4947
  }
4948
+ isDelegateDiscriminator(fieldDef) {
4949
+ if (!fieldDef.originModel) {
4950
+ return false;
4951
+ }
4952
+ const discriminatorField = getDiscriminatorField(this.schema, fieldDef.originModel);
4953
+ return discriminatorField === fieldDef.name;
4954
+ }
4556
4955
  makeRelationManipulationSchema(fieldDef, withoutFields, mode) {
4557
4956
  const fieldType = fieldDef.type;
4558
4957
  const array = !!fieldDef.array;
@@ -5236,7 +5635,7 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
5236
5635
  this.requireCurrentModel(contextNode);
5237
5636
  model = model ?? this.currentModel;
5238
5637
  const modelDef = requireModel(this.schema, model);
5239
- const scalarFields = Object.entries(modelDef.fields).filter(([, fieldDef]) => !fieldDef.relation && !fieldDef.computed).map(([fieldName]) => fieldName);
5638
+ const scalarFields = Object.entries(modelDef.fields).filter(([, fieldDef]) => !fieldDef.relation && !fieldDef.computed && !fieldDef.originModel).map(([fieldName]) => fieldName);
5240
5639
  return scalarFields;
5241
5640
  }
5242
5641
  };
@@ -5653,7 +6052,7 @@ var SchemaDbPusher = class {
5653
6052
  }
5654
6053
  }
5655
6054
  table = this.addPrimaryKeyConstraint(table, model, modelDef);
5656
- table = this.addUniqueConstraint(table, modelDef);
6055
+ table = this.addUniqueConstraint(table, model, modelDef);
5657
6056
  return table;
5658
6057
  }
5659
6058
  isComputedField(fieldDef) {
@@ -5670,7 +6069,7 @@ var SchemaDbPusher = class {
5670
6069
  }
5671
6070
  return table;
5672
6071
  }
5673
- addUniqueConstraint(table, modelDef) {
6072
+ addUniqueConstraint(table, model, modelDef) {
5674
6073
  for (const [key, value] of Object.entries(modelDef.uniqueFields)) {
5675
6074
  (0, import_common_helpers11.invariant)(typeof value === "object", "expecting an object");
5676
6075
  if ("type" in value) {
@@ -5678,8 +6077,11 @@ var SchemaDbPusher = class {
5678
6077
  if (fieldDef.unique) {
5679
6078
  continue;
5680
6079
  }
6080
+ table = table.addUniqueConstraint(`unique_${model}_${key}`, [
6081
+ key
6082
+ ]);
5681
6083
  } else {
5682
- table = table.addUniqueConstraint(`unique_${key}`, Object.keys(value));
6084
+ table = table.addUniqueConstraint(`unique_${model}_${key}`, Object.keys(value));
5683
6085
  }
5684
6086
  }
5685
6087
  return table;
@@ -5822,6 +6224,21 @@ var ResultProcessor = class {
5822
6224
  data[key] = typeof value === "string" ? JSON.parse(value) : value;
5823
6225
  continue;
5824
6226
  }
6227
+ if (key.startsWith(DELEGATE_JOINED_FIELD_PREFIX)) {
6228
+ if (value) {
6229
+ const subRow = this.transformJson(value);
6230
+ const subModel = key.slice(DELEGATE_JOINED_FIELD_PREFIX.length);
6231
+ const idValues = getIdValues(this.schema, subModel, subRow);
6232
+ if (Object.values(idValues).some((v) => v === null || v === void 0)) {
6233
+ delete data[key];
6234
+ continue;
6235
+ }
6236
+ const processedSubRow = this.processRow(subRow, subModel);
6237
+ Object.assign(data, processedSubRow);
6238
+ }
6239
+ delete data[key];
6240
+ continue;
6241
+ }
5825
6242
  const fieldDef = getField(this.schema, model, key);
5826
6243
  if (!fieldDef) {
5827
6244
  continue;
@@ -5861,7 +6278,11 @@ var ResultProcessor = class {
5861
6278
  return this.doProcessResult(relationData, fieldDef.type);
5862
6279
  }
5863
6280
  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);
6281
+ if (this.schema.typeDefs && type in this.schema.typeDefs) {
6282
+ return this.transformJson(value);
6283
+ } else {
6284
+ 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);
6285
+ }
5865
6286
  }
5866
6287
  transformDecimal(value) {
5867
6288
  if (value instanceof import_decimal2.default) {