@zenstackhq/runtime 3.0.0-beta.3 → 3.0.0-beta.5

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
@@ -37,19 +37,20 @@ __export(src_exports, {
37
37
  QueryError: () => QueryError,
38
38
  ZenStackClient: () => ZenStackClient,
39
39
  definePlugin: () => definePlugin,
40
- sql: () => import_kysely18.sql
40
+ sql: () => import_kysely19.sql
41
41
  });
42
42
  module.exports = __toCommonJS(src_exports);
43
43
 
44
44
  // src/client/client-impl.ts
45
45
  var import_common_helpers16 = require("@zenstackhq/common-helpers");
46
- var import_kysely17 = require("kysely");
46
+ var import_kysely18 = require("kysely");
47
47
 
48
48
  // src/client/crud/operations/aggregate.ts
49
- var import_kysely9 = require("kysely");
49
+ var import_kysely11 = require("kysely");
50
50
  var import_ts_pattern10 = require("ts-pattern");
51
51
 
52
52
  // src/client/query-utils.ts
53
+ var import_common_helpers = require("@zenstackhq/common-helpers");
53
54
  var import_ts_pattern = require("ts-pattern");
54
55
 
55
56
  // src/schema/expression.ts
@@ -117,6 +118,9 @@ var ExpressionUtils = {
117
118
  or: /* @__PURE__ */ __name((expr2, ...expressions) => {
118
119
  return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
119
120
  }, "or"),
121
+ not: /* @__PURE__ */ __name((expr2) => {
122
+ return ExpressionUtils.unary("!", expr2);
123
+ }, "not"),
120
124
  is: /* @__PURE__ */ __name((value, kind) => {
121
125
  return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
122
126
  }, "is"),
@@ -177,22 +181,26 @@ var NotFoundError = class extends Error {
177
181
  static {
178
182
  __name(this, "NotFoundError");
179
183
  }
180
- constructor(model) {
181
- super(`Entity not found for model "${model}"`);
184
+ constructor(model, details) {
185
+ super(`Entity not found for model "${model}"${details ? `: ${details}` : ""}`);
182
186
  }
183
187
  };
184
188
 
185
189
  // src/client/query-utils.ts
186
190
  function getModel(schema, model) {
187
- return schema.models[model];
191
+ return Object.values(schema.models).find((m) => m.name.toLowerCase() === model.toLowerCase());
188
192
  }
189
193
  __name(getModel, "getModel");
194
+ function getTypeDef(schema, type) {
195
+ return schema.typeDefs?.[type];
196
+ }
197
+ __name(getTypeDef, "getTypeDef");
190
198
  function requireModel(schema, model) {
191
- const matchedName = Object.keys(schema.models).find((k) => k.toLowerCase() === model.toLowerCase());
192
- if (!matchedName) {
199
+ const modelDef = getModel(schema, model);
200
+ if (!modelDef) {
193
201
  throw new QueryError(`Model "${model}" not found in schema`);
194
202
  }
195
- return schema.models[matchedName];
203
+ return modelDef;
196
204
  }
197
205
  __name(requireModel, "requireModel");
198
206
  function getField(schema, model, field) {
@@ -200,19 +208,40 @@ function getField(schema, model, field) {
200
208
  return modelDef?.fields[field];
201
209
  }
202
210
  __name(getField, "getField");
203
- function requireField(schema, model, field) {
204
- const modelDef = requireModel(schema, model);
205
- if (!modelDef.fields[field]) {
206
- throw new QueryError(`Field "${field}" not found in model "${model}"`);
211
+ function requireField(schema, modelOrType, field) {
212
+ const modelDef = getModel(schema, modelOrType);
213
+ if (modelDef) {
214
+ if (!modelDef.fields[field]) {
215
+ throw new QueryError(`Field "${field}" not found in model "${modelOrType}"`);
216
+ } else {
217
+ return modelDef.fields[field];
218
+ }
219
+ }
220
+ const typeDef = getTypeDef(schema, modelOrType);
221
+ if (typeDef) {
222
+ if (!typeDef.fields[field]) {
223
+ throw new QueryError(`Field "${field}" not found in type "${modelOrType}"`);
224
+ } else {
225
+ return typeDef.fields[field];
226
+ }
207
227
  }
208
- return modelDef.fields[field];
228
+ throw new QueryError(`Model or type "${modelOrType}" not found in schema`);
209
229
  }
210
230
  __name(requireField, "requireField");
211
231
  function getIdFields(schema, model) {
212
- const modelDef = requireModel(schema, model);
232
+ const modelDef = getModel(schema, model);
213
233
  return modelDef?.idFields;
214
234
  }
215
235
  __name(getIdFields, "getIdFields");
236
+ function requireIdFields(schema, model) {
237
+ const modelDef = requireModel(schema, model);
238
+ const result = modelDef?.idFields;
239
+ if (!result) {
240
+ throw new InternalError(`Model "${model}" does not have ID field(s)`);
241
+ }
242
+ return result;
243
+ }
244
+ __name(requireIdFields, "requireIdFields");
216
245
  function getRelationForeignKeyFieldPairs(schema, model, relationField) {
217
246
  const fieldDef = requireField(schema, model, relationField);
218
247
  if (!fieldDef?.relation) {
@@ -326,7 +355,7 @@ function buildFieldRef(schema, model, field, options, eb, modelAlias, inlineComp
326
355
  throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
327
356
  }
328
357
  return computer(eb, {
329
- currentModel: modelAlias
358
+ modelAlias
330
359
  });
331
360
  }
332
361
  }
@@ -361,7 +390,7 @@ function buildJoinPairs(schema, model, modelAlias, relationField, relationModelA
361
390
  }
362
391
  __name(buildJoinPairs, "buildJoinPairs");
363
392
  function makeDefaultOrderBy(schema, model) {
364
- const idFields = getIdFields(schema, model);
393
+ const idFields = requireIdFields(schema, model);
365
394
  return idFields.map((f) => ({
366
395
  [f]: "asc"
367
396
  }));
@@ -400,11 +429,17 @@ function getManyToManyRelation(schema, model, field) {
400
429
  "A"
401
430
  ];
402
431
  }
432
+ const modelIdFields = requireIdFields(schema, model);
433
+ (0, import_common_helpers.invariant)(modelIdFields.length === 1, "Only single-field ID is supported for many-to-many relation");
434
+ const otherIdFields = requireIdFields(schema, fieldDef.type);
435
+ (0, import_common_helpers.invariant)(otherIdFields.length === 1, "Only single-field ID is supported for many-to-many relation");
403
436
  return {
404
437
  parentFkName: orderedFK[0],
438
+ parentPKName: modelIdFields[0],
405
439
  otherModel: fieldDef.type,
406
440
  otherField: fieldDef.relation.opposite,
407
441
  otherFkName: orderedFK[1],
442
+ otherPKName: otherIdFields[0],
408
443
  joinTable: fieldDef.relation.name ? `_${fieldDef.relation.name}` : `_${sortedModelNames[0]}To${sortedModelNames[1]}`
409
444
  };
410
445
  } else {
@@ -443,7 +478,7 @@ function ensureArray(value) {
443
478
  }
444
479
  __name(ensureArray, "ensureArray");
445
480
  function extractIdFields(entity, schema, model) {
446
- const idFields = getIdFields(schema, model);
481
+ const idFields = requireIdFields(schema, model);
447
482
  return extractFields(entity, idFields);
448
483
  }
449
484
  __name(extractIdFields, "extractIdFields");
@@ -480,36 +515,95 @@ __name(aggregate, "aggregate");
480
515
 
481
516
  // src/client/crud/operations/base.ts
482
517
  var import_cuid2 = require("@paralleldrive/cuid2");
483
- var import_common_helpers8 = require("@zenstackhq/common-helpers");
484
- var import_kysely8 = require("kysely");
518
+ var import_common_helpers10 = require("@zenstackhq/common-helpers");
519
+ var import_kysely10 = require("kysely");
485
520
  var import_nanoid = require("nanoid");
486
521
  var import_ts_pattern9 = require("ts-pattern");
487
522
  var import_ulid = require("ulid");
488
523
  var uuid = __toESM(require("uuid"), 1);
489
524
 
490
525
  // src/plugins/policy/errors.ts
526
+ var RejectedByPolicyReason = /* @__PURE__ */ function(RejectedByPolicyReason2) {
527
+ RejectedByPolicyReason2["NO_ACCESS"] = "no-access";
528
+ RejectedByPolicyReason2["CANNOT_READ_BACK"] = "cannot-read-back";
529
+ RejectedByPolicyReason2["OTHER"] = "other";
530
+ return RejectedByPolicyReason2;
531
+ }({});
491
532
  var RejectedByPolicyError = class extends Error {
492
533
  static {
493
534
  __name(this, "RejectedByPolicyError");
494
535
  }
495
536
  model;
496
537
  reason;
497
- constructor(model, reason) {
498
- super(reason ?? `Operation rejected by policy${model ? ": " + model : ""}`), this.model = model, this.reason = reason;
538
+ constructor(model, reason = "no-access", message) {
539
+ super(message ?? `Operation rejected by policy${model ? ": " + model : ""}`), this.model = model, this.reason = reason;
499
540
  }
500
541
  };
501
542
 
543
+ // src/plugins/policy/functions.ts
544
+ var import_common_helpers8 = require("@zenstackhq/common-helpers");
545
+ var import_kysely9 = require("kysely");
546
+
547
+ // src/client/contract.ts
548
+ var TransactionIsolationLevel = /* @__PURE__ */ function(TransactionIsolationLevel2) {
549
+ TransactionIsolationLevel2["ReadUncommitted"] = "read uncommitted";
550
+ TransactionIsolationLevel2["ReadCommitted"] = "read committed";
551
+ TransactionIsolationLevel2["RepeatableRead"] = "repeatable read";
552
+ TransactionIsolationLevel2["Serializable"] = "serializable";
553
+ TransactionIsolationLevel2["Snapshot"] = "snapshot";
554
+ return TransactionIsolationLevel2;
555
+ }({});
556
+ var CRUD = [
557
+ "create",
558
+ "read",
559
+ "update",
560
+ "delete"
561
+ ];
562
+
563
+ // src/client/kysely-utils.ts
564
+ var import_kysely = require("kysely");
565
+ function stripAlias(node) {
566
+ if (import_kysely.AliasNode.is(node)) {
567
+ return {
568
+ alias: node.alias,
569
+ node: node.node
570
+ };
571
+ } else {
572
+ return {
573
+ alias: void 0,
574
+ node
575
+ };
576
+ }
577
+ }
578
+ __name(stripAlias, "stripAlias");
579
+ function extractModelName(node) {
580
+ const { node: innerNode } = stripAlias(node);
581
+ return import_kysely.TableNode.is(innerNode) ? innerNode.table.identifier.name : void 0;
582
+ }
583
+ __name(extractModelName, "extractModelName");
584
+ function extractFieldName(node) {
585
+ if (import_kysely.ReferenceNode.is(node) && import_kysely.ColumnNode.is(node.column)) {
586
+ return node.column.column.name;
587
+ } else if (import_kysely.ColumnNode.is(node)) {
588
+ return node.column.name;
589
+ } else {
590
+ return void 0;
591
+ }
592
+ }
593
+ __name(extractFieldName, "extractFieldName");
594
+
502
595
  // src/plugins/policy/policy-handler.ts
503
- var import_common_helpers6 = require("@zenstackhq/common-helpers");
504
- var import_kysely7 = require("kysely");
596
+ var import_common_helpers7 = require("@zenstackhq/common-helpers");
597
+ var import_kysely8 = require("kysely");
505
598
  var import_ts_pattern8 = require("ts-pattern");
506
599
 
507
600
  // src/client/crud/dialects/index.ts
508
601
  var import_ts_pattern5 = require("ts-pattern");
509
602
 
510
603
  // src/client/crud/dialects/postgresql.ts
511
- var import_common_helpers2 = require("@zenstackhq/common-helpers");
512
- var import_kysely2 = require("kysely");
604
+ var import_common_helpers3 = require("@zenstackhq/common-helpers");
605
+ var import_decimal = __toESM(require("decimal.js"), 1);
606
+ var import_kysely3 = require("kysely");
513
607
  var import_ts_pattern3 = require("ts-pattern");
514
608
 
515
609
  // src/client/constants.ts
@@ -533,9 +627,9 @@ var AGGREGATE_OPERATORS = [
533
627
  "_max"
534
628
  ];
535
629
 
536
- // src/client/crud/dialects/base.ts
537
- var import_common_helpers = require("@zenstackhq/common-helpers");
538
- var import_kysely = require("kysely");
630
+ // src/client/crud/dialects/base-dialect.ts
631
+ var import_common_helpers2 = require("@zenstackhq/common-helpers");
632
+ var import_kysely2 = require("kysely");
539
633
  var import_ts_pattern2 = require("ts-pattern");
540
634
 
541
635
  // src/utils/enumerate.ts
@@ -552,7 +646,7 @@ function enumerate(x) {
552
646
  }
553
647
  __name(enumerate, "enumerate");
554
648
 
555
- // src/client/crud/dialects/base.ts
649
+ // src/client/crud/dialects/base-dialect.ts
556
650
  var BaseCrudDialect = class {
557
651
  static {
558
652
  __name(this, "BaseCrudDialect");
@@ -566,6 +660,9 @@ var BaseCrudDialect = class {
566
660
  transformPrimitive(value, _type, _forArrayField) {
567
661
  return value;
568
662
  }
663
+ transformOutput(value, _type) {
664
+ return value;
665
+ }
569
666
  // #region common query builders
570
667
  buildSelectModel(eb, model, modelAlias) {
571
668
  const modelDef = requireModel(this.schema, model);
@@ -594,7 +691,7 @@ var BaseCrudDialect = class {
594
691
  if ("distinct" in args && args.distinct) {
595
692
  const distinct = ensureArray(args.distinct);
596
693
  if (this.supportsDistinctOn) {
597
- result = result.distinctOn(distinct.map((f) => import_kysely.sql.ref(`${modelAlias}.${f}`)));
694
+ result = result.distinctOn(distinct.map((f) => import_kysely2.sql.ref(`${modelAlias}.${f}`)));
598
695
  } else {
599
696
  throw new QueryError(`"distinct" is not supported by "${this.schema.provider.type}" provider`);
600
697
  }
@@ -644,7 +741,7 @@ var BaseCrudDialect = class {
644
741
  buildCursorFilter(model, query, cursor, orderBy, negateOrderBy, modelAlias) {
645
742
  const _orderBy = orderBy ?? makeDefaultOrderBy(this.schema, model);
646
743
  const orderByItems = ensureArray(_orderBy).flatMap((obj) => Object.entries(obj));
647
- const eb = (0, import_kysely.expressionBuilder)();
744
+ const eb = (0, import_kysely2.expressionBuilder)();
648
745
  const subQueryAlias = `${model}$cursor$sub`;
649
746
  const cursorFilter = this.buildFilter(eb, model, subQueryAlias, cursor);
650
747
  let result = query;
@@ -679,7 +776,7 @@ var BaseCrudDialect = class {
679
776
  if (payload === null) {
680
777
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, model, field);
681
778
  if (ownedByModel && !fieldDef.originModel) {
682
- return this.and(eb, ...keyPairs.map(({ fk }) => eb(import_kysely.sql.ref(`${modelAlias}.${fk}`), "is", null)));
779
+ return this.and(eb, ...keyPairs.map(({ fk }) => eb(import_kysely2.sql.ref(`${modelAlias}.${fk}`), "is", null)));
683
780
  } else {
684
781
  return this.buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, {
685
782
  is: null
@@ -696,7 +793,7 @@ var BaseCrudDialect = class {
696
793
  joinAlias
697
794
  );
698
795
  const filterResultField = `${field}$filter`;
699
- 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));
796
+ const joinSelect = eb.selectFrom(`${fieldDef.type} as ${joinAlias}`).where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right))))).select(() => eb.fn.count(eb.lit(1)).as(filterResultField));
700
797
  const conditions = [];
701
798
  if ("is" in payload || "isNot" in payload) {
702
799
  if ("is" in payload) {
@@ -726,24 +823,26 @@ var BaseCrudDialect = class {
726
823
  }
727
824
  buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
728
825
  if (payload === null) {
729
- return eb(import_kysely.sql.ref(`${modelAlias}.${field}`), "is", null);
826
+ return eb(import_kysely2.sql.ref(`${modelAlias}.${field}`), "is", null);
730
827
  }
731
828
  const relationModel = fieldDef.type;
732
829
  const relationFilterSelectAlias = `${modelAlias}$${field}$filter`;
733
830
  const buildPkFkWhereRefs = /* @__PURE__ */ __name((eb2) => {
734
831
  const m2m = getManyToManyRelation(this.schema, model, field);
735
832
  if (m2m) {
736
- const modelIdField = getIdFields(this.schema, model)[0];
737
- const relationIdField = getIdFields(this.schema, relationModel)[0];
738
- return eb2(import_kysely.sql.ref(`${relationFilterSelectAlias}.${relationIdField}`), "in", eb2.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(import_kysely.sql.ref(`${m2m.joinTable}.${m2m.parentFkName}`), "=", import_kysely.sql.ref(`${modelAlias}.${modelIdField}`)));
833
+ const modelIdFields = requireIdFields(this.schema, model);
834
+ (0, import_common_helpers2.invariant)(modelIdFields.length === 1, "many-to-many relation must have exactly one id field");
835
+ const relationIdFields = requireIdFields(this.schema, relationModel);
836
+ (0, import_common_helpers2.invariant)(relationIdFields.length === 1, "many-to-many relation must have exactly one id field");
837
+ return eb2(import_kysely2.sql.ref(`${relationFilterSelectAlias}.${relationIdFields[0]}`), "in", eb2.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(import_kysely2.sql.ref(`${m2m.joinTable}.${m2m.parentFkName}`), "=", import_kysely2.sql.ref(`${modelAlias}.${modelIdFields[0]}`)));
739
838
  } else {
740
839
  const relationKeyPairs = getRelationForeignKeyFieldPairs(this.schema, model, field);
741
840
  let result2 = this.true(eb2);
742
841
  for (const { fk, pk } of relationKeyPairs.keyPairs) {
743
842
  if (relationKeyPairs.ownedByModel) {
744
- result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${modelAlias}.${fk}`), "=", import_kysely.sql.ref(`${relationFilterSelectAlias}.${pk}`)));
843
+ result2 = this.and(eb2, result2, eb2(import_kysely2.sql.ref(`${modelAlias}.${fk}`), "=", import_kysely2.sql.ref(`${relationFilterSelectAlias}.${pk}`)));
745
844
  } else {
746
- result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${modelAlias}.${pk}`), "=", import_kysely.sql.ref(`${relationFilterSelectAlias}.${fk}`)));
845
+ result2 = this.and(eb2, result2, eb2(import_kysely2.sql.ref(`${modelAlias}.${pk}`), "=", import_kysely2.sql.ref(`${relationFilterSelectAlias}.${fk}`)));
747
846
  }
748
847
  }
749
848
  return result2;
@@ -826,7 +925,7 @@ var BaseCrudDialect = class {
826
925
  return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type, false) : rhs);
827
926
  }
828
927
  buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0, excludeKeys = []) {
829
- if (payload === null || !(0, import_common_helpers.isPlainObject)(payload)) {
928
+ if (payload === null || !(0, import_common_helpers2.isPlainObject)(payload)) {
830
929
  return {
831
930
  conditions: [
832
931
  this.buildLiteralFilter(eb, lhs, type, payload)
@@ -845,14 +944,14 @@ var BaseCrudDialect = class {
845
944
  }
846
945
  const rhs = Array.isArray(value) ? value.map(getRhs) : getRhs(value);
847
946
  const condition = (0, import_ts_pattern2.match)(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
848
- (0, import_common_helpers.invariant)(Array.isArray(rhs), "right hand side must be an array");
947
+ (0, import_common_helpers2.invariant)(Array.isArray(rhs), "right hand side must be an array");
849
948
  if (rhs.length === 0) {
850
949
  return this.false(eb);
851
950
  } else {
852
951
  return eb(lhs, "in", rhs);
853
952
  }
854
953
  }).with("notIn", () => {
855
- (0, import_common_helpers.invariant)(Array.isArray(rhs), "right hand side must be an array");
954
+ (0, import_common_helpers2.invariant)(Array.isArray(rhs), "right hand side must be an array");
856
955
  if (rhs.length === 0) {
857
956
  return this.true(eb);
858
957
  } else {
@@ -892,7 +991,7 @@ var BaseCrudDialect = class {
892
991
  if (key === "mode" || consumedKeys.includes(key)) {
893
992
  continue;
894
993
  }
895
- const condition = (0, import_ts_pattern2.match)(key).with("contains", () => mode === "insensitive" ? eb(fieldRef, "ilike", import_kysely.sql.val(`%${value}%`)) : eb(fieldRef, "like", import_kysely.sql.val(`%${value}%`))).with("startsWith", () => mode === "insensitive" ? eb(fieldRef, "ilike", import_kysely.sql.val(`${value}%`)) : eb(fieldRef, "like", import_kysely.sql.val(`${value}%`))).with("endsWith", () => mode === "insensitive" ? eb(fieldRef, "ilike", import_kysely.sql.val(`%${value}`)) : eb(fieldRef, "like", import_kysely.sql.val(`%${value}`))).otherwise(() => {
994
+ const condition = (0, import_ts_pattern2.match)(key).with("contains", () => mode === "insensitive" ? eb(fieldRef, "ilike", import_kysely2.sql.val(`%${value}%`)) : eb(fieldRef, "like", import_kysely2.sql.val(`%${value}%`))).with("startsWith", () => mode === "insensitive" ? eb(fieldRef, "ilike", import_kysely2.sql.val(`${value}%`)) : eb(fieldRef, "like", import_kysely2.sql.val(`${value}%`))).with("endsWith", () => mode === "insensitive" ? eb(fieldRef, "ilike", import_kysely2.sql.val(`%${value}`)) : eb(fieldRef, "like", import_kysely2.sql.val(`%${value}`))).otherwise(() => {
896
995
  throw new QueryError(`Invalid string filter key: ${key}`);
897
996
  });
898
997
  if (condition) {
@@ -904,16 +1003,16 @@ var BaseCrudDialect = class {
904
1003
  }
905
1004
  prepStringCasing(eb, value, mode) {
906
1005
  if (!mode || mode === "default") {
907
- return value === null ? value : import_kysely.sql.val(value);
1006
+ return value === null ? value : import_kysely2.sql.val(value);
908
1007
  }
909
1008
  if (typeof value === "string") {
910
1009
  return eb.fn("lower", [
911
- import_kysely.sql.val(value)
1010
+ import_kysely2.sql.val(value)
912
1011
  ]);
913
1012
  } else if (Array.isArray(value)) {
914
1013
  return value.map((v) => this.prepStringCasing(eb, v, mode));
915
1014
  } else {
916
- return value === null ? null : import_kysely.sql.val(value);
1015
+ return value === null ? null : import_kysely2.sql.val(value);
917
1016
  }
918
1017
  }
919
1018
  buildNumberFilter(eb, fieldRef, type, payload) {
@@ -970,19 +1069,19 @@ var BaseCrudDialect = class {
970
1069
  "_min",
971
1070
  "_max"
972
1071
  ].includes(field)) {
973
- (0, import_common_helpers.invariant)(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
1072
+ (0, import_common_helpers2.invariant)(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
974
1073
  for (const [k, v] of Object.entries(value)) {
975
- (0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
976
- result = result.orderBy((eb) => aggregate(eb, this.fieldRef(model, k, eb, modelAlias), field), import_kysely.sql.raw(this.negateSort(v, negated)));
1074
+ (0, import_common_helpers2.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
1075
+ result = result.orderBy((eb) => aggregate(eb, this.fieldRef(model, k, eb, modelAlias), field), import_kysely2.sql.raw(this.negateSort(v, negated)));
977
1076
  }
978
1077
  continue;
979
1078
  }
980
1079
  switch (field) {
981
1080
  case "_count": {
982
- (0, import_common_helpers.invariant)(value && typeof value === "object", 'invalid orderBy value for field "_count"');
1081
+ (0, import_common_helpers2.invariant)(value && typeof value === "object", 'invalid orderBy value for field "_count"');
983
1082
  for (const [k, v] of Object.entries(value)) {
984
- (0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
985
- result = result.orderBy((eb) => eb.fn.count(this.fieldRef(model, k, eb, modelAlias)), import_kysely.sql.raw(this.negateSort(v, negated)));
1083
+ (0, import_common_helpers2.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
1084
+ result = result.orderBy((eb) => eb.fn.count(this.fieldRef(model, k, eb, modelAlias)), import_kysely2.sql.raw(this.negateSort(v, negated)));
986
1085
  }
987
1086
  continue;
988
1087
  }
@@ -991,11 +1090,11 @@ var BaseCrudDialect = class {
991
1090
  }
992
1091
  const fieldDef = requireField(this.schema, model, field);
993
1092
  if (!fieldDef.relation) {
994
- const fieldRef = this.fieldRef(model, field, (0, import_kysely.expressionBuilder)(), modelAlias);
1093
+ const fieldRef = this.fieldRef(model, field, (0, import_kysely2.expressionBuilder)(), modelAlias);
995
1094
  if (value === "asc" || value === "desc") {
996
1095
  result = result.orderBy(fieldRef, this.negateSort(value, negated));
997
1096
  } else if (value && typeof value === "object" && "nulls" in value && "sort" in value && (value.sort === "asc" || value.sort === "desc") && (value.nulls === "first" || value.nulls === "last")) {
998
- result = result.orderBy(fieldRef, import_kysely.sql.raw(`${this.negateSort(value.sort, negated)} nulls ${value.nulls}`));
1097
+ result = result.orderBy(fieldRef, import_kysely2.sql.raw(`${this.negateSort(value.sort, negated)} nulls ${value.nulls}`));
999
1098
  }
1000
1099
  } else {
1001
1100
  const relationModel = fieldDef.type;
@@ -1004,13 +1103,13 @@ var BaseCrudDialect = class {
1004
1103
  throw new QueryError(`invalid orderBy value for field "${field}"`);
1005
1104
  }
1006
1105
  if ("_count" in value) {
1007
- (0, import_common_helpers.invariant)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
1106
+ (0, import_common_helpers2.invariant)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
1008
1107
  const sort = this.negateSort(value._count, negated);
1009
1108
  result = result.orderBy((eb) => {
1010
1109
  const subQueryAlias = `${modelAlias}$orderBy$${field}$count`;
1011
1110
  let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
1012
1111
  const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, subQueryAlias);
1013
- subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely.sql.ref(left), "=", import_kysely.sql.ref(right)))));
1112
+ subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right)))));
1014
1113
  subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
1015
1114
  return subQuery;
1016
1115
  }, sort);
@@ -1018,7 +1117,7 @@ var BaseCrudDialect = class {
1018
1117
  } else {
1019
1118
  result = result.leftJoin(relationModel, (join) => {
1020
1119
  const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, relationModel);
1021
- return join.on((eb) => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely.sql.ref(left), "=", import_kysely.sql.ref(right)))));
1120
+ return join.on((eb) => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right)))));
1022
1121
  });
1023
1122
  result = this.buildOrderBy(result, fieldDef.type, relationModel, value, false, negated);
1024
1123
  }
@@ -1070,13 +1169,13 @@ var BaseCrudDialect = class {
1070
1169
  if (fieldDef.computed) {
1071
1170
  return query.select((eb) => this.fieldRef(model, field, eb, modelAlias).as(field));
1072
1171
  } else if (!fieldDef.originModel) {
1073
- return query.select(import_kysely.sql.ref(`${modelAlias}.${field}`).as(field));
1172
+ return query.select(import_kysely2.sql.ref(`${modelAlias}.${field}`).as(field));
1074
1173
  } else {
1075
1174
  return this.buildSelectField(query, fieldDef.originModel, fieldDef.originModel, field);
1076
1175
  }
1077
1176
  }
1078
1177
  buildDelegateJoin(thisModel, thisModelAlias, otherModelAlias, query) {
1079
- const idFields = getIdFields(this.schema, thisModel);
1178
+ const idFields = requireIdFields(this.schema, thisModel);
1080
1179
  query = query.leftJoin(otherModelAlias, (qb) => {
1081
1180
  for (const idField of idFields) {
1082
1181
  qb = qb.onRef(`${thisModelAlias}.${idField}`, "=", `${otherModelAlias}.${idField}`);
@@ -1098,10 +1197,16 @@ var BaseCrudDialect = class {
1098
1197
  for (const [field, value] of Object.entries(selections.select)) {
1099
1198
  const fieldDef = requireField(this.schema, model, field);
1100
1199
  const fieldModel = fieldDef.type;
1101
- const joinPairs = buildJoinPairs(this.schema, model, parentAlias, field, fieldModel);
1102
- let fieldCountQuery = eb.selectFrom(fieldModel).select(eb.fn.countAll().as(`_count$${field}`));
1103
- for (const [left, right] of joinPairs) {
1104
- fieldCountQuery = fieldCountQuery.whereRef(left, "=", right);
1200
+ let fieldCountQuery;
1201
+ const m2m = getManyToManyRelation(this.schema, model, field);
1202
+ if (m2m) {
1203
+ fieldCountQuery = eb.selectFrom(fieldModel).innerJoin(m2m.joinTable, (join) => join.onRef(`${m2m.joinTable}.${m2m.otherFkName}`, "=", `${fieldModel}.${m2m.otherPKName}`).onRef(`${m2m.joinTable}.${m2m.parentFkName}`, "=", `${parentAlias}.${m2m.parentPKName}`)).select(eb.fn.countAll().as(`_count$${field}`));
1204
+ } else {
1205
+ fieldCountQuery = eb.selectFrom(fieldModel).select(eb.fn.countAll().as(`_count$${field}`));
1206
+ const joinPairs = buildJoinPairs(this.schema, model, parentAlias, field, fieldModel);
1207
+ for (const [left, right] of joinPairs) {
1208
+ fieldCountQuery = fieldCountQuery.whereRef(left, "=", right);
1209
+ }
1105
1210
  }
1106
1211
  if (value && typeof value === "object" && "where" in value && value.where && typeof value.where === "object") {
1107
1212
  const filter = this.buildFilter(eb, fieldModel, fieldModel, value.where);
@@ -1181,6 +1286,9 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1181
1286
  static {
1182
1287
  __name(this, "PostgresCrudDialect");
1183
1288
  }
1289
+ constructor(schema, options) {
1290
+ super(schema, options);
1291
+ }
1184
1292
  get provider() {
1185
1293
  return "postgresql";
1186
1294
  }
@@ -1195,9 +1303,41 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1195
1303
  return value.map((v) => this.transformPrimitive(v, type, false));
1196
1304
  }
1197
1305
  } else {
1198
- return (0, import_ts_pattern3.match)(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).with("Decimal", () => value !== null ? value.toString() : value).otherwise(() => value);
1306
+ return (0, import_ts_pattern3.match)(type).with("DateTime", () => value instanceof Date ? value.toISOString() : typeof value === "string" ? new Date(value).toISOString() : value).with("Decimal", () => value !== null ? value.toString() : value).otherwise(() => value);
1199
1307
  }
1200
1308
  }
1309
+ transformOutput(value, type) {
1310
+ if (value === null || value === void 0) {
1311
+ return value;
1312
+ }
1313
+ return (0, import_ts_pattern3.match)(type).with("DateTime", () => this.transformOutputDate(value)).with("Bytes", () => this.transformOutputBytes(value)).with("BigInt", () => this.transformOutputBigInt(value)).with("Decimal", () => this.transformDecimal(value)).otherwise(() => super.transformOutput(value, type));
1314
+ }
1315
+ transformOutputBigInt(value) {
1316
+ if (typeof value === "bigint") {
1317
+ return value;
1318
+ }
1319
+ (0, import_common_helpers3.invariant)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
1320
+ return BigInt(value);
1321
+ }
1322
+ transformDecimal(value) {
1323
+ if (value instanceof import_decimal.default) {
1324
+ return value;
1325
+ }
1326
+ (0, import_common_helpers3.invariant)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal.default, `Expected string, number or Decimal, got ${typeof value}`);
1327
+ return new import_decimal.default(value);
1328
+ }
1329
+ transformOutputDate(value) {
1330
+ if (typeof value === "string") {
1331
+ return new Date(value);
1332
+ } else if (value instanceof Date && this.options.fixPostgresTimezone !== false) {
1333
+ return new Date(value.getTime() - value.getTimezoneOffset() * 60 * 1e3);
1334
+ } else {
1335
+ return value;
1336
+ }
1337
+ }
1338
+ transformOutputBytes(value) {
1339
+ return Buffer.isBuffer(value) ? Uint8Array.from(value) : value;
1340
+ }
1201
1341
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
1202
1342
  const relationResultName = `${parentAlias}$${relationField}`;
1203
1343
  const joinedQuery = this.buildRelationJSON(model, query, relationField, parentAlias, payload, relationResultName);
@@ -1228,14 +1368,14 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1228
1368
  buildRelationJoinFilter(query, model, relationField, relationModel, relationModelAlias, parentAlias) {
1229
1369
  const m2m = getManyToManyRelation(this.schema, model, relationField);
1230
1370
  if (m2m) {
1231
- const parentIds = getIdFields(this.schema, model);
1232
- const relationIds = getIdFields(this.schema, relationModel);
1233
- (0, import_common_helpers2.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1234
- (0, import_common_helpers2.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1371
+ const parentIds = requireIdFields(this.schema, model);
1372
+ const relationIds = requireIdFields(this.schema, relationModel);
1373
+ (0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1374
+ (0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1235
1375
  query = query.where((eb) => eb(eb.ref(`${relationModelAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
1236
1376
  } else {
1237
1377
  const joinPairs = buildJoinPairs(this.schema, model, parentAlias, relationField, relationModelAlias);
1238
- query = query.where((eb) => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right)))));
1378
+ query = query.where((eb) => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely3.sql.ref(left), "=", import_kysely3.sql.ref(right)))));
1239
1379
  }
1240
1380
  return query;
1241
1381
  }
@@ -1243,9 +1383,9 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1243
1383
  qb = qb.select((eb) => {
1244
1384
  const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias, eb, payload, parentResultName);
1245
1385
  if (relationFieldDef.array) {
1246
- return eb.fn.coalesce(import_kysely2.sql`jsonb_agg(jsonb_build_object(${import_kysely2.sql.join(objArgs)}))`, import_kysely2.sql`'[]'::jsonb`).as("$data");
1386
+ return eb.fn.coalesce(import_kysely3.sql`jsonb_agg(jsonb_build_object(${import_kysely3.sql.join(objArgs)}))`, import_kysely3.sql`'[]'::jsonb`).as("$data");
1247
1387
  } else {
1248
- return import_kysely2.sql`jsonb_build_object(${import_kysely2.sql.join(objArgs)})`.as("$data");
1388
+ return import_kysely3.sql`jsonb_build_object(${import_kysely3.sql.join(objArgs)})`.as("$data");
1249
1389
  }
1250
1390
  });
1251
1391
  return qb;
@@ -1256,13 +1396,13 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1256
1396
  const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
1257
1397
  if (descendantModels.length > 0) {
1258
1398
  objArgs.push(...descendantModels.map((subModel) => [
1259
- import_kysely2.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1399
+ import_kysely3.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1260
1400
  eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
1261
1401
  ]).flatMap((v) => v));
1262
1402
  }
1263
1403
  if (payload === true || !payload.select) {
1264
1404
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
1265
- import_kysely2.sql.lit(field),
1405
+ import_kysely3.sql.lit(field),
1266
1406
  this.fieldRef(relationModel, field, eb, relationModelAlias, false)
1267
1407
  ]).flatMap((v) => v));
1268
1408
  } else if (payload.select) {
@@ -1270,14 +1410,14 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1270
1410
  if (field === "_count") {
1271
1411
  const subJson = this.buildCountJson(relationModel, eb, relationModelAlias, value);
1272
1412
  return [
1273
- import_kysely2.sql.lit(field),
1413
+ import_kysely3.sql.lit(field),
1274
1414
  subJson
1275
1415
  ];
1276
1416
  } else {
1277
1417
  const fieldDef = requireField(this.schema, relationModel, field);
1278
1418
  const fieldValue = fieldDef.relation ? eb.ref(`${parentResultName}$${field}.$data`) : this.fieldRef(relationModel, field, eb, relationModelAlias, false);
1279
1419
  return [
1280
- import_kysely2.sql.lit(field),
1420
+ import_kysely3.sql.lit(field),
1281
1421
  fieldValue
1282
1422
  ];
1283
1423
  }
@@ -1285,7 +1425,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1285
1425
  }
1286
1426
  if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
1287
1427
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field]) => [
1288
- import_kysely2.sql.lit(field),
1428
+ import_kysely3.sql.lit(field),
1289
1429
  // reference the synthesized JSON field
1290
1430
  eb.ref(`${parentResultName}$${field}.$data`)
1291
1431
  ]).flatMap((v) => v));
@@ -1315,7 +1455,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1315
1455
  }
1316
1456
  buildJsonObject(eb, value) {
1317
1457
  return eb.fn("jsonb_build_object", Object.entries(value).flatMap(([key, value2]) => [
1318
- import_kysely2.sql.lit(key),
1458
+ import_kysely3.sql.lit(key),
1319
1459
  value2
1320
1460
  ]));
1321
1461
  }
@@ -1343,11 +1483,33 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1343
1483
  get supportInsertWithDefault() {
1344
1484
  return true;
1345
1485
  }
1486
+ getFieldSqlType(fieldDef) {
1487
+ if (fieldDef.relation) {
1488
+ throw new QueryError("Cannot get SQL type of a relation field");
1489
+ }
1490
+ let result;
1491
+ if (this.schema.enums?.[fieldDef.type]) {
1492
+ result = "text";
1493
+ } else {
1494
+ result = (0, import_ts_pattern3.match)(fieldDef.type).with("String", () => "text").with("Boolean", () => "boolean").with("Int", () => "integer").with("BigInt", () => "bigint").with("Float", () => "double precision").with("Decimal", () => "decimal").with("DateTime", () => "timestamp").with("Bytes", () => "bytea").with("Json", () => "jsonb").otherwise(() => "text");
1495
+ }
1496
+ if (fieldDef.array) {
1497
+ result += "[]";
1498
+ }
1499
+ return result;
1500
+ }
1501
+ getStringCasingBehavior() {
1502
+ return {
1503
+ supportsILike: true,
1504
+ likeCaseSensitive: true
1505
+ };
1506
+ }
1346
1507
  };
1347
1508
 
1348
1509
  // src/client/crud/dialects/sqlite.ts
1349
- var import_common_helpers3 = require("@zenstackhq/common-helpers");
1350
- var import_kysely3 = require("kysely");
1510
+ var import_common_helpers4 = require("@zenstackhq/common-helpers");
1511
+ var import_decimal2 = __toESM(require("decimal.js"), 1);
1512
+ var import_kysely4 = require("kysely");
1351
1513
  var import_ts_pattern4 = require("ts-pattern");
1352
1514
  var SqliteCrudDialect = class extends BaseCrudDialect {
1353
1515
  static {
@@ -1366,9 +1528,57 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1366
1528
  if (this.schema.typeDefs && type in this.schema.typeDefs) {
1367
1529
  return JSON.stringify(value);
1368
1530
  } else {
1369
- return (0, import_ts_pattern4.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);
1531
+ return (0, import_ts_pattern4.match)(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => value instanceof Date ? value.toISOString() : typeof value === "string" ? new Date(value).toISOString() : value).with("Decimal", () => value.toString()).with("Bytes", () => Buffer.from(value)).with("Json", () => JSON.stringify(value)).otherwise(() => value);
1532
+ }
1533
+ }
1534
+ }
1535
+ transformOutput(value, type) {
1536
+ if (value === null || value === void 0) {
1537
+ return value;
1538
+ } else if (this.schema.typeDefs && type in this.schema.typeDefs) {
1539
+ return this.transformOutputJson(value);
1540
+ } else {
1541
+ return (0, import_ts_pattern4.match)(type).with("Boolean", () => this.transformOutputBoolean(value)).with("DateTime", () => this.transformOutputDate(value)).with("Bytes", () => this.transformOutputBytes(value)).with("Decimal", () => this.transformOutputDecimal(value)).with("BigInt", () => this.transformOutputBigInt(value)).with("Json", () => this.transformOutputJson(value)).otherwise(() => super.transformOutput(value, type));
1542
+ }
1543
+ }
1544
+ transformOutputDecimal(value) {
1545
+ if (value instanceof import_decimal2.default) {
1546
+ return value;
1547
+ }
1548
+ (0, import_common_helpers4.invariant)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal2.default, `Expected string, number or Decimal, got ${typeof value}`);
1549
+ return new import_decimal2.default(value);
1550
+ }
1551
+ transformOutputBigInt(value) {
1552
+ if (typeof value === "bigint") {
1553
+ return value;
1554
+ }
1555
+ (0, import_common_helpers4.invariant)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
1556
+ return BigInt(value);
1557
+ }
1558
+ transformOutputBoolean(value) {
1559
+ return !!value;
1560
+ }
1561
+ transformOutputDate(value) {
1562
+ if (typeof value === "number") {
1563
+ return new Date(value);
1564
+ } else if (typeof value === "string") {
1565
+ return new Date(value);
1566
+ } else {
1567
+ return value;
1568
+ }
1569
+ }
1570
+ transformOutputBytes(value) {
1571
+ return Buffer.isBuffer(value) ? Uint8Array.from(value) : value;
1572
+ }
1573
+ transformOutputJson(value) {
1574
+ if (typeof value === "string") {
1575
+ try {
1576
+ return JSON.parse(value);
1577
+ } catch (e) {
1578
+ throw new QueryError("Invalid JSON returned", e);
1370
1579
  }
1371
1580
  }
1581
+ return value;
1372
1582
  }
1373
1583
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
1374
1584
  return query.select((eb) => this.buildRelationJSON(model, eb, relationField, parentAlias, payload).as(relationField));
@@ -1395,13 +1605,13 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1395
1605
  const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
1396
1606
  if (descendantModels.length > 0) {
1397
1607
  objArgs.push(...descendantModels.map((subModel) => [
1398
- import_kysely3.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1608
+ import_kysely4.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1399
1609
  eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
1400
1610
  ]).flatMap((v) => v));
1401
1611
  }
1402
1612
  if (payload === true || !payload.select) {
1403
1613
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
1404
- import_kysely3.sql.lit(field),
1614
+ import_kysely4.sql.lit(field),
1405
1615
  this.fieldRef(relationModel, field, eb, subQueryName, false)
1406
1616
  ]).flatMap((v) => v));
1407
1617
  } else if (payload.select) {
@@ -1409,7 +1619,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1409
1619
  if (field === "_count") {
1410
1620
  const subJson = this.buildCountJson(relationModel, eb, `${parentAlias}$${relationField}`, value);
1411
1621
  return [
1412
- import_kysely3.sql.lit(field),
1622
+ import_kysely4.sql.lit(field),
1413
1623
  subJson
1414
1624
  ];
1415
1625
  } else {
@@ -1417,12 +1627,12 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1417
1627
  if (fieldDef.relation) {
1418
1628
  const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
1419
1629
  return [
1420
- import_kysely3.sql.lit(field),
1630
+ import_kysely4.sql.lit(field),
1421
1631
  subJson
1422
1632
  ];
1423
1633
  } else {
1424
1634
  return [
1425
- import_kysely3.sql.lit(field),
1635
+ import_kysely4.sql.lit(field),
1426
1636
  this.fieldRef(relationModel, field, eb, subQueryName, false)
1427
1637
  ];
1428
1638
  }
@@ -1433,15 +1643,15 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1433
1643
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field, value]) => {
1434
1644
  const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
1435
1645
  return [
1436
- import_kysely3.sql.lit(field),
1646
+ import_kysely4.sql.lit(field),
1437
1647
  subJson
1438
1648
  ];
1439
1649
  }).flatMap((v) => v));
1440
1650
  }
1441
1651
  if (relationFieldDef.array) {
1442
- return eb.fn.coalesce(import_kysely3.sql`json_group_array(json_object(${import_kysely3.sql.join(objArgs)}))`, import_kysely3.sql`json_array()`).as("$data");
1652
+ return eb.fn.coalesce(import_kysely4.sql`json_group_array(json_object(${import_kysely4.sql.join(objArgs)}))`, import_kysely4.sql`json_array()`).as("$data");
1443
1653
  } else {
1444
- return import_kysely3.sql`json_object(${import_kysely3.sql.join(objArgs)})`.as("$data");
1654
+ return import_kysely4.sql`json_object(${import_kysely4.sql.join(objArgs)})`.as("$data");
1445
1655
  }
1446
1656
  });
1447
1657
  return tbl;
@@ -1451,10 +1661,10 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1451
1661
  const relationModel = fieldDef.type;
1452
1662
  const m2m = getManyToManyRelation(this.schema, model, relationField);
1453
1663
  if (m2m) {
1454
- const parentIds = getIdFields(this.schema, model);
1455
- const relationIds = getIdFields(this.schema, relationModel);
1456
- (0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1457
- (0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1664
+ const parentIds = requireIdFields(this.schema, model);
1665
+ const relationIds = requireIdFields(this.schema, relationModel);
1666
+ (0, import_common_helpers4.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1667
+ (0, import_common_helpers4.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1458
1668
  selectModelQuery = selectModelQuery.where((eb) => eb(eb.ref(`${relationModelAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
1459
1669
  } else {
1460
1670
  const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
@@ -1482,7 +1692,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1482
1692
  }
1483
1693
  buildJsonObject(eb, value) {
1484
1694
  return eb.fn("json_object", Object.entries(value).flatMap(([key, value2]) => [
1485
- import_kysely3.sql.lit(key),
1695
+ import_kysely4.sql.lit(key),
1486
1696
  value2
1487
1697
  ]));
1488
1698
  }
@@ -1506,6 +1716,24 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1506
1716
  get supportInsertWithDefault() {
1507
1717
  return false;
1508
1718
  }
1719
+ getFieldSqlType(fieldDef) {
1720
+ if (fieldDef.relation) {
1721
+ throw new QueryError("Cannot get SQL type of a relation field");
1722
+ }
1723
+ if (fieldDef.array) {
1724
+ throw new QueryError("SQLite does not support scalar list type");
1725
+ }
1726
+ if (this.schema.enums?.[fieldDef.type]) {
1727
+ return "text";
1728
+ }
1729
+ return (0, import_ts_pattern4.match)(fieldDef.type).with("String", () => "text").with("Boolean", () => "integer").with("Int", () => "integer").with("BigInt", () => "integer").with("Float", () => "real").with("Decimal", () => "decimal").with("DateTime", () => "numeric").with("Bytes", () => "blob").with("Json", () => "jsonb").otherwise(() => "text");
1730
+ }
1731
+ getStringCasingBehavior() {
1732
+ return {
1733
+ supportsILike: false,
1734
+ likeCaseSensitive: false
1735
+ };
1736
+ }
1509
1737
  };
1510
1738
 
1511
1739
  // src/client/crud/dialects/index.ts
@@ -1515,8 +1743,8 @@ function getCrudDialect(schema, options) {
1515
1743
  __name(getCrudDialect, "getCrudDialect");
1516
1744
 
1517
1745
  // src/utils/default-operation-node-visitor.ts
1518
- var import_kysely4 = require("kysely");
1519
- var DefaultOperationNodeVisitor = class extends import_kysely4.OperationNodeVisitor {
1746
+ var import_kysely5 = require("kysely");
1747
+ var DefaultOperationNodeVisitor = class extends import_kysely5.OperationNodeVisitor {
1520
1748
  static {
1521
1749
  __name(this, "DefaultOperationNodeVisitor");
1522
1750
  }
@@ -1833,12 +2061,12 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
1833
2061
  };
1834
2062
 
1835
2063
  // src/plugins/policy/expression-transformer.ts
1836
- var import_common_helpers5 = require("@zenstackhq/common-helpers");
1837
- var import_kysely6 = require("kysely");
2064
+ var import_common_helpers6 = require("@zenstackhq/common-helpers");
2065
+ var import_kysely7 = require("kysely");
1838
2066
  var import_ts_pattern7 = require("ts-pattern");
1839
2067
 
1840
2068
  // src/plugins/policy/expression-evaluator.ts
1841
- var import_common_helpers4 = require("@zenstackhq/common-helpers");
2069
+ var import_common_helpers5 = require("@zenstackhq/common-helpers");
1842
2070
  var import_ts_pattern6 = require("ts-pattern");
1843
2071
  var ExpressionEvaluator = class {
1844
2072
  static {
@@ -1882,18 +2110,18 @@ var ExpressionEvaluator = class {
1882
2110
  const right = this.evaluate(expr2.right, context);
1883
2111
  return (0, import_ts_pattern6.match)(expr2.op).with("==", () => left === right).with("!=", () => left !== right).with(">", () => left > right).with(">=", () => left >= right).with("<", () => left < right).with("<=", () => left <= right).with("&&", () => left && right).with("||", () => left || right).with("in", () => {
1884
2112
  const _right = right ?? [];
1885
- (0, import_common_helpers4.invariant)(Array.isArray(_right), 'expected array for "in" operator');
2113
+ (0, import_common_helpers5.invariant)(Array.isArray(_right), 'expected array for "in" operator');
1886
2114
  return _right.includes(left);
1887
2115
  }).exhaustive();
1888
2116
  }
1889
2117
  evaluateCollectionPredicate(expr2, context) {
1890
2118
  const op = expr2.op;
1891
- (0, import_common_helpers4.invariant)(op === "?" || op === "!" || op === "^", 'expected "?" or "!" or "^" operator');
2119
+ (0, import_common_helpers5.invariant)(op === "?" || op === "!" || op === "^", 'expected "?" or "!" or "^" operator');
1892
2120
  const left = this.evaluate(expr2.left, context);
1893
2121
  if (!left) {
1894
2122
  return false;
1895
2123
  }
1896
- (0, import_common_helpers4.invariant)(Array.isArray(left), "expected array");
2124
+ (0, import_common_helpers5.invariant)(Array.isArray(left), "expected array");
1897
2125
  return (0, import_ts_pattern6.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1898
2126
  ...context,
1899
2127
  thisValue: item
@@ -1908,24 +2136,30 @@ var ExpressionEvaluator = class {
1908
2136
  };
1909
2137
 
1910
2138
  // src/plugins/policy/utils.ts
1911
- var import_kysely5 = require("kysely");
2139
+ var import_kysely6 = require("kysely");
1912
2140
  function trueNode(dialect) {
1913
- return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean", false));
2141
+ return import_kysely6.ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean", false));
1914
2142
  }
1915
2143
  __name(trueNode, "trueNode");
1916
2144
  function falseNode(dialect) {
1917
- return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean", false));
2145
+ return import_kysely6.ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean", false));
1918
2146
  }
1919
2147
  __name(falseNode, "falseNode");
1920
2148
  function isTrueNode(node) {
1921
- return import_kysely5.ValueNode.is(node) && (node.value === true || node.value === 1);
2149
+ return import_kysely6.ValueNode.is(node) && (node.value === true || node.value === 1);
1922
2150
  }
1923
2151
  __name(isTrueNode, "isTrueNode");
1924
2152
  function isFalseNode(node) {
1925
- return import_kysely5.ValueNode.is(node) && (node.value === false || node.value === 0);
2153
+ return import_kysely6.ValueNode.is(node) && (node.value === false || node.value === 0);
1926
2154
  }
1927
2155
  __name(isFalseNode, "isFalseNode");
1928
2156
  function conjunction(dialect, nodes) {
2157
+ if (nodes.length === 0) {
2158
+ return trueNode(dialect);
2159
+ }
2160
+ if (nodes.length === 1) {
2161
+ return nodes[0];
2162
+ }
1929
2163
  if (nodes.some(isFalseNode)) {
1930
2164
  return falseNode(dialect);
1931
2165
  }
@@ -1933,10 +2167,16 @@ function conjunction(dialect, nodes) {
1933
2167
  if (items.length === 0) {
1934
2168
  return trueNode(dialect);
1935
2169
  }
1936
- return items.reduce((acc, node) => import_kysely5.OrNode.is(node) ? import_kysely5.AndNode.create(acc, import_kysely5.ParensNode.create(node)) : import_kysely5.AndNode.create(acc, node));
2170
+ return items.reduce((acc, node) => import_kysely6.AndNode.create(wrapParensIf(acc, import_kysely6.OrNode.is), wrapParensIf(node, import_kysely6.OrNode.is)));
1937
2171
  }
1938
2172
  __name(conjunction, "conjunction");
1939
2173
  function disjunction(dialect, nodes) {
2174
+ if (nodes.length === 0) {
2175
+ return falseNode(dialect);
2176
+ }
2177
+ if (nodes.length === 1) {
2178
+ return nodes[0];
2179
+ }
1940
2180
  if (nodes.some(isTrueNode)) {
1941
2181
  return trueNode(dialect);
1942
2182
  }
@@ -1944,26 +2184,36 @@ function disjunction(dialect, nodes) {
1944
2184
  if (items.length === 0) {
1945
2185
  return falseNode(dialect);
1946
2186
  }
1947
- return items.reduce((acc, node) => import_kysely5.AndNode.is(node) ? import_kysely5.OrNode.create(acc, import_kysely5.ParensNode.create(node)) : import_kysely5.OrNode.create(acc, node));
2187
+ return items.reduce((acc, node) => import_kysely6.OrNode.create(wrapParensIf(acc, import_kysely6.AndNode.is), wrapParensIf(node, import_kysely6.AndNode.is)));
1948
2188
  }
1949
2189
  __name(disjunction, "disjunction");
1950
- function logicalNot(node) {
1951
- return import_kysely5.UnaryOperationNode.create(import_kysely5.OperatorNode.create("not"), import_kysely5.AndNode.is(node) || import_kysely5.OrNode.is(node) ? import_kysely5.ParensNode.create(node) : node);
2190
+ function logicalNot(dialect, node) {
2191
+ if (isTrueNode(node)) {
2192
+ return falseNode(dialect);
2193
+ }
2194
+ if (isFalseNode(node)) {
2195
+ return trueNode(dialect);
2196
+ }
2197
+ return import_kysely6.UnaryOperationNode.create(import_kysely6.OperatorNode.create("not"), wrapParensIf(node, (n) => import_kysely6.AndNode.is(n) || import_kysely6.OrNode.is(n)));
1952
2198
  }
1953
2199
  __name(logicalNot, "logicalNot");
2200
+ function wrapParensIf(node, predicate) {
2201
+ return predicate(node) ? import_kysely6.ParensNode.create(node) : node;
2202
+ }
2203
+ __name(wrapParensIf, "wrapParensIf");
1954
2204
  function buildIsFalse(node, dialect) {
1955
2205
  if (isFalseNode(node)) {
1956
2206
  return trueNode(dialect);
1957
2207
  } else if (isTrueNode(node)) {
1958
2208
  return falseNode(dialect);
1959
2209
  }
1960
- return import_kysely5.BinaryOperationNode.create(
2210
+ return import_kysely6.BinaryOperationNode.create(
1961
2211
  // coalesce so null is treated as false
1962
- import_kysely5.FunctionNode.create("coalesce", [
2212
+ import_kysely6.FunctionNode.create("coalesce", [
1963
2213
  node,
1964
2214
  falseNode(dialect)
1965
2215
  ]),
1966
- import_kysely5.OperatorNode.create("="),
2216
+ import_kysely6.OperatorNode.create("="),
1967
2217
  falseNode(dialect)
1968
2218
  );
1969
2219
  }
@@ -1972,11 +2222,11 @@ function getTableName(node) {
1972
2222
  if (!node) {
1973
2223
  return node;
1974
2224
  }
1975
- if (import_kysely5.TableNode.is(node)) {
2225
+ if (import_kysely6.TableNode.is(node)) {
1976
2226
  return node.table.identifier.name;
1977
- } else if (import_kysely5.AliasNode.is(node)) {
2227
+ } else if (import_kysely6.AliasNode.is(node)) {
1978
2228
  return getTableName(node.node);
1979
- } else if (import_kysely5.ReferenceNode.is(node) && node.table) {
2229
+ } else if (import_kysely6.ReferenceNode.is(node) && node.table) {
1980
2230
  return getTableName(node.table);
1981
2231
  }
1982
2232
  return void 0;
@@ -2009,16 +2259,21 @@ var ExpressionTransformer = class {
2009
2259
  static {
2010
2260
  __name(this, "ExpressionTransformer");
2011
2261
  }
2012
- schema;
2013
- clientOptions;
2014
- auth;
2262
+ client;
2015
2263
  dialect;
2016
- constructor(schema, clientOptions, auth) {
2017
- this.schema = schema;
2018
- this.clientOptions = clientOptions;
2019
- this.auth = auth;
2264
+ constructor(client) {
2265
+ this.client = client;
2020
2266
  this.dialect = getCrudDialect(this.schema, this.clientOptions);
2021
2267
  }
2268
+ get schema() {
2269
+ return this.client.$schema;
2270
+ }
2271
+ get clientOptions() {
2272
+ return this.client.$options;
2273
+ }
2274
+ get auth() {
2275
+ return this.client.$auth;
2276
+ }
2022
2277
  get authType() {
2023
2278
  if (!this.schema.authType) {
2024
2279
  throw new InternalError('Schema does not have an "authType" specified');
@@ -2036,16 +2291,12 @@ var ExpressionTransformer = class {
2036
2291
  return this.transformValue(expr2.value, typeof expr2.value === "string" ? "String" : typeof expr2.value === "boolean" ? "Boolean" : "Int");
2037
2292
  }
2038
2293
  _array(expr2, context) {
2039
- return import_kysely6.ValueListNode.create(expr2.items.map((item) => this.transform(item, context)));
2294
+ return import_kysely7.ValueListNode.create(expr2.items.map((item) => this.transform(item, context)));
2040
2295
  }
2041
2296
  _field(expr2, context) {
2042
2297
  const fieldDef = requireField(this.schema, context.model, expr2.field);
2043
2298
  if (!fieldDef.relation) {
2044
- if (context.thisEntity) {
2045
- return context.thisEntity[expr2.field];
2046
- } else {
2047
- return this.createColumnRef(expr2.field, context);
2048
- }
2299
+ return this.createColumnRef(expr2.field, context);
2049
2300
  } else {
2050
2301
  const { memberFilter, memberSelect, ...restContext } = context;
2051
2302
  const relation = this.transformRelationAccess(expr2.field, fieldDef.type, restContext);
@@ -2060,18 +2311,18 @@ var ExpressionTransformer = class {
2060
2311
  }
2061
2312
  mergeWhere(where, memberFilter) {
2062
2313
  if (!where) {
2063
- return import_kysely6.WhereNode.create(memberFilter ?? trueNode(this.dialect));
2314
+ return import_kysely7.WhereNode.create(memberFilter ?? trueNode(this.dialect));
2064
2315
  }
2065
2316
  if (!memberFilter) {
2066
2317
  return where;
2067
2318
  }
2068
- return import_kysely6.WhereNode.create(conjunction(this.dialect, [
2319
+ return import_kysely7.WhereNode.create(conjunction(this.dialect, [
2069
2320
  where.where,
2070
2321
  memberFilter
2071
2322
  ]));
2072
2323
  }
2073
2324
  _null() {
2074
- return import_kysely6.ValueNode.createImmediate(null);
2325
+ return import_kysely7.ValueNode.createImmediate(null);
2075
2326
  }
2076
2327
  _binary(expr2, context) {
2077
2328
  if (expr2.op === "&&") {
@@ -2086,51 +2337,88 @@ var ExpressionTransformer = class {
2086
2337
  ]);
2087
2338
  }
2088
2339
  if (this.isAuthCall(expr2.left) || this.isAuthCall(expr2.right)) {
2089
- return this.transformAuthBinary(expr2);
2340
+ return this.transformAuthBinary(expr2, context);
2090
2341
  }
2091
2342
  const op = expr2.op;
2092
2343
  if (op === "?" || op === "!" || op === "^") {
2093
2344
  return this.transformCollectionPredicate(expr2, context);
2094
2345
  }
2095
- const left = this.transform(expr2.left, context);
2096
- const right = this.transform(expr2.right, context);
2346
+ const { normalizedLeft, normalizedRight } = this.normalizeBinaryOperationOperands(expr2, context);
2347
+ const left = this.transform(normalizedLeft, context);
2348
+ const right = this.transform(normalizedRight, context);
2097
2349
  if (op === "in") {
2098
2350
  if (this.isNullNode(left)) {
2099
2351
  return this.transformValue(false, "Boolean");
2100
2352
  } else {
2101
- if (import_kysely6.ValueListNode.is(right)) {
2102
- return import_kysely6.BinaryOperationNode.create(left, import_kysely6.OperatorNode.create("in"), right);
2353
+ if (import_kysely7.ValueListNode.is(right)) {
2354
+ return import_kysely7.BinaryOperationNode.create(left, import_kysely7.OperatorNode.create("in"), right);
2103
2355
  } else {
2104
- return import_kysely6.BinaryOperationNode.create(left, import_kysely6.OperatorNode.create("="), import_kysely6.FunctionNode.create("any", [
2356
+ return import_kysely7.BinaryOperationNode.create(left, import_kysely7.OperatorNode.create("="), import_kysely7.FunctionNode.create("any", [
2105
2357
  right
2106
2358
  ]));
2107
2359
  }
2108
2360
  }
2109
2361
  }
2110
2362
  if (this.isNullNode(right)) {
2111
- return expr2.op === "==" ? import_kysely6.BinaryOperationNode.create(left, import_kysely6.OperatorNode.create("is"), right) : import_kysely6.BinaryOperationNode.create(left, import_kysely6.OperatorNode.create("is not"), right);
2363
+ return this.transformNullCheck(left, expr2.op);
2112
2364
  } else if (this.isNullNode(left)) {
2113
- return expr2.op === "==" ? import_kysely6.BinaryOperationNode.create(right, import_kysely6.OperatorNode.create("is"), import_kysely6.ValueNode.createImmediate(null)) : import_kysely6.BinaryOperationNode.create(right, import_kysely6.OperatorNode.create("is not"), import_kysely6.ValueNode.createImmediate(null));
2365
+ return this.transformNullCheck(right, expr2.op);
2366
+ } else {
2367
+ return import_kysely7.BinaryOperationNode.create(left, this.transformOperator(op), right);
2114
2368
  }
2115
- return import_kysely6.BinaryOperationNode.create(left, this.transformOperator(op), right);
2369
+ }
2370
+ transformNullCheck(expr2, operator) {
2371
+ (0, import_common_helpers6.invariant)(operator === "==" || operator === "!=", 'operator must be "==" or "!=" for null comparison');
2372
+ if (import_kysely7.ValueNode.is(expr2)) {
2373
+ if (expr2.value === null) {
2374
+ return operator === "==" ? trueNode(this.dialect) : falseNode(this.dialect);
2375
+ } else {
2376
+ return operator === "==" ? falseNode(this.dialect) : trueNode(this.dialect);
2377
+ }
2378
+ } else {
2379
+ return operator === "==" ? import_kysely7.BinaryOperationNode.create(expr2, import_kysely7.OperatorNode.create("is"), import_kysely7.ValueNode.createImmediate(null)) : import_kysely7.BinaryOperationNode.create(expr2, import_kysely7.OperatorNode.create("is not"), import_kysely7.ValueNode.createImmediate(null));
2380
+ }
2381
+ }
2382
+ normalizeBinaryOperationOperands(expr2, context) {
2383
+ let normalizedLeft = expr2.left;
2384
+ if (this.isRelationField(expr2.left, context.model)) {
2385
+ (0, import_common_helpers6.invariant)(ExpressionUtils.isNull(expr2.right), "only null comparison is supported for relation field");
2386
+ const leftRelDef = this.getFieldDefFromFieldRef(expr2.left, context.model);
2387
+ (0, import_common_helpers6.invariant)(leftRelDef, "failed to get relation field definition");
2388
+ const idFields = requireIdFields(this.schema, leftRelDef.type);
2389
+ normalizedLeft = this.makeOrAppendMember(normalizedLeft, idFields[0]);
2390
+ }
2391
+ let normalizedRight = expr2.right;
2392
+ if (this.isRelationField(expr2.right, context.model)) {
2393
+ (0, import_common_helpers6.invariant)(ExpressionUtils.isNull(expr2.left), "only null comparison is supported for relation field");
2394
+ const rightRelDef = this.getFieldDefFromFieldRef(expr2.right, context.model);
2395
+ (0, import_common_helpers6.invariant)(rightRelDef, "failed to get relation field definition");
2396
+ const idFields = requireIdFields(this.schema, rightRelDef.type);
2397
+ normalizedRight = this.makeOrAppendMember(normalizedRight, idFields[0]);
2398
+ }
2399
+ return {
2400
+ normalizedLeft,
2401
+ normalizedRight
2402
+ };
2116
2403
  }
2117
2404
  transformCollectionPredicate(expr2, context) {
2118
- (0, import_common_helpers5.invariant)(expr2.op === "?" || expr2.op === "!" || expr2.op === "^", 'expected "?" or "!" or "^" operator');
2405
+ (0, import_common_helpers6.invariant)(expr2.op === "?" || expr2.op === "!" || expr2.op === "^", 'expected "?" or "!" or "^" operator');
2119
2406
  if (this.isAuthCall(expr2.left) || this.isAuthMember(expr2.left)) {
2120
2407
  const value = new ExpressionEvaluator().evaluate(expr2, {
2121
2408
  auth: this.auth
2122
2409
  });
2123
2410
  return this.transformValue(value, "Boolean");
2124
2411
  }
2125
- (0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.left) || ExpressionUtils.isMember(expr2.left), "left operand must be field or member access");
2412
+ (0, import_common_helpers6.invariant)(ExpressionUtils.isField(expr2.left) || ExpressionUtils.isMember(expr2.left), "left operand must be field or member access");
2126
2413
  let newContextModel;
2127
- if (ExpressionUtils.isField(expr2.left)) {
2128
- const fieldDef = requireField(this.schema, context.model, expr2.left.field);
2414
+ const fieldDef = this.getFieldDefFromFieldRef(expr2.left, context.model);
2415
+ if (fieldDef) {
2416
+ (0, import_common_helpers6.invariant)(fieldDef.relation, `field is not a relation: ${JSON.stringify(expr2.left)}`);
2129
2417
  newContextModel = fieldDef.type;
2130
2418
  } else {
2131
- (0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.left.receiver));
2132
- const fieldDef = requireField(this.schema, context.model, expr2.left.receiver.field);
2133
- newContextModel = fieldDef.type;
2419
+ (0, import_common_helpers6.invariant)(ExpressionUtils.isMember(expr2.left) && ExpressionUtils.isField(expr2.left.receiver), "left operand must be member access with field receiver");
2420
+ const fieldDef2 = requireField(this.schema, context.model, expr2.left.receiver.field);
2421
+ newContextModel = fieldDef2.type;
2134
2422
  for (const member of expr2.left.members) {
2135
2423
  const memberDef = requireField(this.schema, newContextModel, member);
2136
2424
  newContextModel = memberDef.type;
@@ -2139,71 +2427,118 @@ var ExpressionTransformer = class {
2139
2427
  let predicateFilter = this.transform(expr2.right, {
2140
2428
  ...context,
2141
2429
  model: newContextModel,
2142
- alias: void 0,
2143
- thisEntity: void 0
2430
+ alias: void 0
2144
2431
  });
2145
2432
  if (expr2.op === "!") {
2146
- predicateFilter = logicalNot(predicateFilter);
2433
+ predicateFilter = logicalNot(this.dialect, predicateFilter);
2147
2434
  }
2148
- const count = import_kysely6.FunctionNode.create("count", [
2149
- import_kysely6.ValueNode.createImmediate(1)
2435
+ const count = import_kysely7.FunctionNode.create("count", [
2436
+ import_kysely7.ValueNode.createImmediate(1)
2150
2437
  ]);
2151
- const predicateResult = (0, import_ts_pattern7.match)(expr2.op).with("?", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create(">"), import_kysely6.ValueNode.createImmediate(0))).with("!", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create("="), import_kysely6.ValueNode.createImmediate(0))).with("^", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create("="), import_kysely6.ValueNode.createImmediate(0))).exhaustive();
2438
+ const predicateResult = (0, import_ts_pattern7.match)(expr2.op).with("?", () => import_kysely7.BinaryOperationNode.create(count, import_kysely7.OperatorNode.create(">"), import_kysely7.ValueNode.createImmediate(0))).with("!", () => import_kysely7.BinaryOperationNode.create(count, import_kysely7.OperatorNode.create("="), import_kysely7.ValueNode.createImmediate(0))).with("^", () => import_kysely7.BinaryOperationNode.create(count, import_kysely7.OperatorNode.create("="), import_kysely7.ValueNode.createImmediate(0))).exhaustive();
2152
2439
  return this.transform(expr2.left, {
2153
2440
  ...context,
2154
- memberSelect: import_kysely6.SelectionNode.create(import_kysely6.AliasNode.create(predicateResult, import_kysely6.IdentifierNode.create("$t"))),
2441
+ memberSelect: import_kysely7.SelectionNode.create(import_kysely7.AliasNode.create(predicateResult, import_kysely7.IdentifierNode.create("$t"))),
2155
2442
  memberFilter: predicateFilter
2156
2443
  });
2157
2444
  }
2158
- transformAuthBinary(expr2) {
2445
+ transformAuthBinary(expr2, context) {
2159
2446
  if (expr2.op !== "==" && expr2.op !== "!=") {
2160
- throw new Error(`Unsupported operator for auth call: ${expr2.op}`);
2447
+ throw new QueryError(`Unsupported operator for \`auth()\` in policy of model "${context.model}": ${expr2.op}`);
2161
2448
  }
2449
+ let authExpr;
2162
2450
  let other;
2163
2451
  if (this.isAuthCall(expr2.left)) {
2452
+ authExpr = expr2.left;
2164
2453
  other = expr2.right;
2165
2454
  } else {
2455
+ authExpr = expr2.right;
2166
2456
  other = expr2.left;
2167
2457
  }
2168
2458
  if (ExpressionUtils.isNull(other)) {
2169
2459
  return this.transformValue(expr2.op === "==" ? !this.auth : !!this.auth, "Boolean");
2170
2460
  } else {
2171
- throw new Error("Unsupported binary expression with `auth()`");
2461
+ const authModel = getModel(this.schema, this.authType);
2462
+ if (!authModel) {
2463
+ throw new QueryError(`Unsupported use of \`auth()\` in policy of model "${context.model}", comparing with \`auth()\` is only possible when auth type is a model`);
2464
+ }
2465
+ const idFields = Object.values(authModel.fields).filter((f) => f.id).map((f) => f.name);
2466
+ (0, import_common_helpers6.invariant)(idFields.length > 0, "auth type model must have at least one id field");
2467
+ const conditions = idFields.map((fieldName) => ExpressionUtils.binary(ExpressionUtils.member(authExpr, [
2468
+ fieldName
2469
+ ]), "==", this.makeOrAppendMember(other, fieldName)));
2470
+ let result = this.buildAnd(conditions);
2471
+ if (expr2.op === "!=") {
2472
+ result = this.buildLogicalNot(result);
2473
+ }
2474
+ return this.transform(result, context);
2475
+ }
2476
+ }
2477
+ makeOrAppendMember(other, fieldName) {
2478
+ if (ExpressionUtils.isMember(other)) {
2479
+ return ExpressionUtils.member(other.receiver, [
2480
+ ...other.members,
2481
+ fieldName
2482
+ ]);
2483
+ } else {
2484
+ return ExpressionUtils.member(other, [
2485
+ fieldName
2486
+ ]);
2172
2487
  }
2173
2488
  }
2174
2489
  transformValue(value, type) {
2175
- return import_kysely6.ValueNode.create(this.dialect.transformPrimitive(value, type, false) ?? null);
2490
+ if (value === true) {
2491
+ return trueNode(this.dialect);
2492
+ } else if (value === false) {
2493
+ return falseNode(this.dialect);
2494
+ } else {
2495
+ return import_kysely7.ValueNode.create(this.dialect.transformPrimitive(value, type, false) ?? null);
2496
+ }
2176
2497
  }
2177
2498
  _unary(expr2, context) {
2178
- (0, import_common_helpers5.invariant)(expr2.op === "!", 'only "!" operator is supported');
2179
- return import_kysely6.BinaryOperationNode.create(this.transform(expr2.operand, context), this.transformOperator("!="), trueNode(this.dialect));
2499
+ (0, import_common_helpers6.invariant)(expr2.op === "!", 'only "!" operator is supported');
2500
+ return logicalNot(this.dialect, this.transform(expr2.operand, context));
2180
2501
  }
2181
2502
  transformOperator(op) {
2182
2503
  const mappedOp = (0, import_ts_pattern7.match)(op).with("==", () => "=").otherwise(() => op);
2183
- return import_kysely6.OperatorNode.create(mappedOp);
2504
+ return import_kysely7.OperatorNode.create(mappedOp);
2184
2505
  }
2185
2506
  _call(expr2, context) {
2186
2507
  const result = this.transformCall(expr2, context);
2187
2508
  return result.toOperationNode();
2188
2509
  }
2189
2510
  transformCall(expr2, context) {
2190
- const func = this.clientOptions.functions?.[expr2.function];
2511
+ const func = this.getFunctionImpl(expr2.function);
2191
2512
  if (!func) {
2192
2513
  throw new QueryError(`Function not implemented: ${expr2.function}`);
2193
2514
  }
2194
- const eb = (0, import_kysely6.expressionBuilder)();
2515
+ const eb = (0, import_kysely7.expressionBuilder)();
2195
2516
  return func(eb, (expr2.args ?? []).map((arg) => this.transformCallArg(eb, arg, context)), {
2517
+ client: this.client,
2196
2518
  dialect: this.dialect,
2197
2519
  model: context.model,
2520
+ modelAlias: context.alias ?? context.model,
2198
2521
  operation: context.operation
2199
2522
  });
2200
2523
  }
2524
+ getFunctionImpl(functionName) {
2525
+ let func = this.clientOptions.functions?.[functionName];
2526
+ if (!func) {
2527
+ for (const plugin of this.clientOptions.plugins ?? []) {
2528
+ if (plugin.functions?.[functionName]) {
2529
+ func = plugin.functions[functionName];
2530
+ break;
2531
+ }
2532
+ }
2533
+ }
2534
+ return func;
2535
+ }
2201
2536
  transformCallArg(eb, arg, context) {
2202
2537
  if (ExpressionUtils.isLiteral(arg)) {
2203
2538
  return eb.val(arg.value);
2204
2539
  }
2205
2540
  if (ExpressionUtils.isField(arg)) {
2206
- return context.thisEntityRaw ? eb.val(context.thisEntityRaw[arg.field]) : eb.ref(arg.field);
2541
+ return eb.ref(arg.field);
2207
2542
  }
2208
2543
  if (ExpressionUtils.isCall(arg)) {
2209
2544
  return this.transformCall(arg, context);
@@ -2218,14 +2553,32 @@ var ExpressionTransformer = class {
2218
2553
  if (this.isAuthCall(expr2.receiver)) {
2219
2554
  return this.valueMemberAccess(this.auth, expr2, this.authType);
2220
2555
  }
2221
- (0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.receiver), "expect receiver to be field expression");
2556
+ (0, import_common_helpers6.invariant)(ExpressionUtils.isField(expr2.receiver) || ExpressionUtils.isThis(expr2.receiver), 'expect receiver to be field expression or "this"');
2557
+ let members = expr2.members;
2558
+ let receiver;
2222
2559
  const { memberFilter, memberSelect, ...restContext } = context;
2223
- const receiver = this.transform(expr2.receiver, restContext);
2224
- (0, import_common_helpers5.invariant)(import_kysely6.SelectQueryNode.is(receiver), "expected receiver to be select query");
2225
- const receiverField = requireField(this.schema, context.model, expr2.receiver.field);
2560
+ if (ExpressionUtils.isThis(expr2.receiver)) {
2561
+ if (expr2.members.length === 1) {
2562
+ return this._field(ExpressionUtils.field(expr2.members[0]), context);
2563
+ } else {
2564
+ const firstMemberFieldDef = requireField(this.schema, context.model, expr2.members[0]);
2565
+ receiver = this.transformRelationAccess(expr2.members[0], firstMemberFieldDef.type, restContext);
2566
+ members = expr2.members.slice(1);
2567
+ }
2568
+ } else {
2569
+ receiver = this.transform(expr2.receiver, restContext);
2570
+ }
2571
+ (0, import_common_helpers6.invariant)(import_kysely7.SelectQueryNode.is(receiver), "expected receiver to be select query");
2572
+ let startType;
2573
+ if (ExpressionUtils.isField(expr2.receiver)) {
2574
+ const receiverField = requireField(this.schema, context.model, expr2.receiver.field);
2575
+ startType = receiverField.type;
2576
+ } else {
2577
+ startType = context.model;
2578
+ }
2226
2579
  const memberFields = [];
2227
- let currType = receiverField.type;
2228
- for (const member of expr2.members) {
2580
+ let currType = startType;
2581
+ for (const member of members) {
2229
2582
  const fieldDef = requireField(this.schema, currType, member);
2230
2583
  memberFields.push({
2231
2584
  fieldDef,
@@ -2234,22 +2587,21 @@ var ExpressionTransformer = class {
2234
2587
  currType = fieldDef.type;
2235
2588
  }
2236
2589
  let currNode = void 0;
2237
- for (let i = expr2.members.length - 1; i >= 0; i--) {
2238
- const member = expr2.members[i];
2590
+ for (let i = members.length - 1; i >= 0; i--) {
2591
+ const member = members[i];
2239
2592
  const { fieldDef, fromModel } = memberFields[i];
2240
2593
  if (fieldDef.relation) {
2241
2594
  const relation = this.transformRelationAccess(member, fieldDef.type, {
2242
2595
  ...restContext,
2243
2596
  model: fromModel,
2244
- alias: void 0,
2245
- thisEntity: void 0
2597
+ alias: void 0
2246
2598
  });
2247
2599
  if (currNode) {
2248
- (0, import_common_helpers5.invariant)(import_kysely6.SelectQueryNode.is(currNode), "expected select query node");
2600
+ (0, import_common_helpers6.invariant)(import_kysely7.SelectQueryNode.is(currNode), "expected select query node");
2249
2601
  currNode = {
2250
2602
  ...relation,
2251
2603
  selections: [
2252
- import_kysely6.SelectionNode.create(import_kysely6.AliasNode.create(currNode, import_kysely6.IdentifierNode.create(expr2.members[i + 1])))
2604
+ import_kysely7.SelectionNode.create(import_kysely7.AliasNode.create(currNode, import_kysely7.IdentifierNode.create(members[i + 1])))
2253
2605
  ]
2254
2606
  };
2255
2607
  } else {
@@ -2262,21 +2614,21 @@ var ExpressionTransformer = class {
2262
2614
  };
2263
2615
  }
2264
2616
  } else {
2265
- (0, import_common_helpers5.invariant)(i === expr2.members.length - 1, "plain field access must be the last segment");
2266
- (0, import_common_helpers5.invariant)(!currNode, "plain field access must be the last segment");
2267
- currNode = import_kysely6.ColumnNode.create(member);
2617
+ (0, import_common_helpers6.invariant)(i === members.length - 1, "plain field access must be the last segment");
2618
+ (0, import_common_helpers6.invariant)(!currNode, "plain field access must be the last segment");
2619
+ currNode = import_kysely7.ColumnNode.create(member);
2268
2620
  }
2269
2621
  }
2270
2622
  return {
2271
2623
  ...receiver,
2272
2624
  selections: [
2273
- import_kysely6.SelectionNode.create(import_kysely6.AliasNode.create(currNode, import_kysely6.IdentifierNode.create("$t")))
2625
+ import_kysely7.SelectionNode.create(import_kysely7.AliasNode.create(currNode, import_kysely7.IdentifierNode.create("$t")))
2274
2626
  ]
2275
2627
  };
2276
2628
  }
2277
2629
  valueMemberAccess(receiver, expr2, receiverType) {
2278
2630
  if (!receiver) {
2279
- return import_kysely6.ValueNode.createImmediate(null);
2631
+ return import_kysely7.ValueNode.createImmediate(null);
2280
2632
  }
2281
2633
  if (expr2.members.length !== 1) {
2282
2634
  throw new Error(`Only single member access is supported`);
@@ -2287,40 +2639,33 @@ var ExpressionTransformer = class {
2287
2639
  return this.transformValue(fieldValue, fieldDef.type);
2288
2640
  }
2289
2641
  transformRelationAccess(field, relationModel, context) {
2642
+ const m2m = getManyToManyRelation(this.schema, context.model, field);
2643
+ if (m2m) {
2644
+ return this.transformManyToManyRelationAccess(m2m, context);
2645
+ }
2290
2646
  const fromModel = context.model;
2291
2647
  const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, fromModel, field);
2292
- if (context.thisEntity) {
2293
- let condition;
2294
- if (ownedByModel) {
2295
- condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => import_kysely6.BinaryOperationNode.create(import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(pk), import_kysely6.TableNode.create(relationModel)), import_kysely6.OperatorNode.create("="), context.thisEntity[fk])));
2296
- } else {
2297
- condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => import_kysely6.BinaryOperationNode.create(import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(fk), import_kysely6.TableNode.create(relationModel)), import_kysely6.OperatorNode.create("="), context.thisEntity[pk])));
2298
- }
2299
- return {
2300
- kind: "SelectQueryNode",
2301
- from: import_kysely6.FromNode.create([
2302
- import_kysely6.TableNode.create(relationModel)
2303
- ]),
2304
- where: import_kysely6.WhereNode.create(condition)
2305
- };
2648
+ let condition;
2649
+ if (ownedByModel) {
2650
+ condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => import_kysely7.BinaryOperationNode.create(import_kysely7.ReferenceNode.create(import_kysely7.ColumnNode.create(fk), import_kysely7.TableNode.create(context.alias ?? fromModel)), import_kysely7.OperatorNode.create("="), import_kysely7.ReferenceNode.create(import_kysely7.ColumnNode.create(pk), import_kysely7.TableNode.create(relationModel)))));
2306
2651
  } else {
2307
- let condition;
2308
- if (ownedByModel) {
2309
- condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => import_kysely6.BinaryOperationNode.create(import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(fk), import_kysely6.TableNode.create(context.alias ?? fromModel)), import_kysely6.OperatorNode.create("="), import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(pk), import_kysely6.TableNode.create(relationModel)))));
2310
- } else {
2311
- condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => import_kysely6.BinaryOperationNode.create(import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(pk), import_kysely6.TableNode.create(context.alias ?? fromModel)), import_kysely6.OperatorNode.create("="), import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(fk), import_kysely6.TableNode.create(relationModel)))));
2312
- }
2313
- return {
2314
- kind: "SelectQueryNode",
2315
- from: import_kysely6.FromNode.create([
2316
- import_kysely6.TableNode.create(relationModel)
2317
- ]),
2318
- where: import_kysely6.WhereNode.create(condition)
2319
- };
2652
+ condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => import_kysely7.BinaryOperationNode.create(import_kysely7.ReferenceNode.create(import_kysely7.ColumnNode.create(pk), import_kysely7.TableNode.create(context.alias ?? fromModel)), import_kysely7.OperatorNode.create("="), import_kysely7.ReferenceNode.create(import_kysely7.ColumnNode.create(fk), import_kysely7.TableNode.create(relationModel)))));
2320
2653
  }
2654
+ return {
2655
+ kind: "SelectQueryNode",
2656
+ from: import_kysely7.FromNode.create([
2657
+ import_kysely7.TableNode.create(relationModel)
2658
+ ]),
2659
+ where: import_kysely7.WhereNode.create(condition)
2660
+ };
2661
+ }
2662
+ transformManyToManyRelationAccess(m2m, context) {
2663
+ const eb = (0, import_kysely7.expressionBuilder)();
2664
+ const relationQuery = eb.selectFrom(m2m.otherModel).innerJoin(m2m.joinTable, (join) => join.onRef(`${m2m.otherModel}.${m2m.otherPKName}`, "=", `${m2m.joinTable}.${m2m.otherFkName}`).onRef(`${m2m.joinTable}.${m2m.parentFkName}`, "=", `${context.alias ?? context.model}.${m2m.parentPKName}`));
2665
+ return relationQuery.toOperationNode();
2321
2666
  }
2322
2667
  createColumnRef(column, context) {
2323
- return import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(column), import_kysely6.TableNode.create(context.alias ?? context.model));
2668
+ return import_kysely7.ReferenceNode.create(import_kysely7.ColumnNode.create(column), import_kysely7.TableNode.create(context.alias ?? context.model));
2324
2669
  }
2325
2670
  isAuthCall(value) {
2326
2671
  return ExpressionUtils.isCall(value) && value.function === "auth";
@@ -2329,7 +2674,32 @@ var ExpressionTransformer = class {
2329
2674
  return ExpressionUtils.isMember(expr2) && this.isAuthCall(expr2.receiver);
2330
2675
  }
2331
2676
  isNullNode(node) {
2332
- return import_kysely6.ValueNode.is(node) && node.value === null;
2677
+ return import_kysely7.ValueNode.is(node) && node.value === null;
2678
+ }
2679
+ buildLogicalNot(result) {
2680
+ return ExpressionUtils.unary("!", result);
2681
+ }
2682
+ buildAnd(conditions) {
2683
+ if (conditions.length === 0) {
2684
+ return ExpressionUtils.literal(true);
2685
+ } else if (conditions.length === 1) {
2686
+ return conditions[0];
2687
+ } else {
2688
+ return conditions.reduce((acc, condition) => ExpressionUtils.binary(acc, "&&", condition));
2689
+ }
2690
+ }
2691
+ isRelationField(expr2, model) {
2692
+ const fieldDef = this.getFieldDefFromFieldRef(expr2, model);
2693
+ return !!fieldDef?.relation;
2694
+ }
2695
+ getFieldDefFromFieldRef(expr2, model) {
2696
+ if (ExpressionUtils.isField(expr2)) {
2697
+ return requireField(this.schema, model, expr2.field);
2698
+ } else if (ExpressionUtils.isMember(expr2) && expr2.members.length === 1 && ExpressionUtils.isThis(expr2.receiver)) {
2699
+ return requireField(this.schema, model, expr2.members[0]);
2700
+ } else {
2701
+ return void 0;
2702
+ }
2333
2703
  }
2334
2704
  };
2335
2705
  _ts_decorate([
@@ -2402,7 +2772,7 @@ _ts_decorate([
2402
2772
  ], ExpressionTransformer.prototype, "_member", null);
2403
2773
 
2404
2774
  // src/plugins/policy/policy-handler.ts
2405
- var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2775
+ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2406
2776
  static {
2407
2777
  __name(this, "PolicyHandler");
2408
2778
  }
@@ -2417,111 +2787,296 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2417
2787
  }
2418
2788
  async handle(node, proceed) {
2419
2789
  if (!this.isCrudQueryNode(node)) {
2420
- throw new RejectedByPolicyError(void 0, "non-CRUD queries are not allowed");
2790
+ throw new RejectedByPolicyError(void 0, RejectedByPolicyReason.OTHER, "non-CRUD queries are not allowed");
2421
2791
  }
2422
2792
  if (!this.isMutationQueryNode(node)) {
2423
2793
  return proceed(this.transformNode(node));
2424
2794
  }
2425
- let mutationRequiresTransaction = false;
2426
- const mutationModel = this.getMutationModel(node);
2427
- if (import_kysely7.InsertQueryNode.is(node)) {
2428
- const constCondition = this.tryGetConstantPolicy(mutationModel, "create");
2429
- if (constCondition === false) {
2430
- throw new RejectedByPolicyError(mutationModel);
2431
- } else if (constCondition === void 0) {
2432
- mutationRequiresTransaction = true;
2795
+ const { mutationModel } = this.getMutationModel(node);
2796
+ if (import_kysely8.InsertQueryNode.is(node)) {
2797
+ const isManyToManyJoinTable = this.isManyToManyJoinTable(mutationModel);
2798
+ let needCheckPreCreate = true;
2799
+ if (!isManyToManyJoinTable) {
2800
+ const constCondition = this.tryGetConstantPolicy(mutationModel, "create");
2801
+ if (constCondition === true) {
2802
+ needCheckPreCreate = false;
2803
+ } else if (constCondition === false) {
2804
+ throw new RejectedByPolicyError(mutationModel);
2805
+ }
2806
+ }
2807
+ if (needCheckPreCreate) {
2808
+ await this.enforcePreCreatePolicy(node, mutationModel, isManyToManyJoinTable, proceed);
2433
2809
  }
2434
2810
  }
2435
- if (!mutationRequiresTransaction && !node.returning) {
2436
- return proceed(this.transformNode(node));
2437
- }
2438
- if (import_kysely7.InsertQueryNode.is(node)) {
2439
- await this.enforcePreCreatePolicy(node, proceed);
2440
- }
2441
- const transformedNode = this.transformNode(node);
2442
- const result = await proceed(transformedNode);
2443
- if (!this.onlyReturningId(node)) {
2811
+ const result = await proceed(this.transformNode(node));
2812
+ if (!node.returning || this.onlyReturningId(node)) {
2813
+ return result;
2814
+ } else {
2444
2815
  const readBackResult = await this.processReadBack(node, result, proceed);
2445
2816
  if (readBackResult.rows.length !== result.rows.length) {
2446
- throw new RejectedByPolicyError(mutationModel, "result is not allowed to be read back");
2817
+ throw new RejectedByPolicyError(mutationModel, RejectedByPolicyReason.CANNOT_READ_BACK, "result is not allowed to be read back");
2447
2818
  }
2448
2819
  return readBackResult;
2449
- } else {
2820
+ }
2821
+ }
2822
+ // #region overrides
2823
+ transformSelectQuery(node) {
2824
+ let whereNode = this.transformNode(node.where);
2825
+ const policyFilter = this.createPolicyFilterForFrom(node.from);
2826
+ if (policyFilter) {
2827
+ whereNode = import_kysely8.WhereNode.create(whereNode?.where ? conjunction(this.dialect, [
2828
+ whereNode.where,
2829
+ policyFilter
2830
+ ]) : policyFilter);
2831
+ }
2832
+ const baseResult = super.transformSelectQuery({
2833
+ ...node,
2834
+ where: void 0
2835
+ });
2836
+ return {
2837
+ ...baseResult,
2838
+ where: whereNode
2839
+ };
2840
+ }
2841
+ transformJoin(node) {
2842
+ const table = this.extractTableName(node.table);
2843
+ if (!table) {
2844
+ return super.transformJoin(node);
2845
+ }
2846
+ const filter = this.buildPolicyFilter(table.model, table.alias, "read");
2847
+ const nestedSelect = {
2848
+ kind: "SelectQueryNode",
2849
+ from: import_kysely8.FromNode.create([
2850
+ node.table
2851
+ ]),
2852
+ selections: [
2853
+ import_kysely8.SelectionNode.createSelectAll()
2854
+ ],
2855
+ where: import_kysely8.WhereNode.create(filter)
2856
+ };
2857
+ return {
2858
+ ...node,
2859
+ table: import_kysely8.AliasNode.create(import_kysely8.ParensNode.create(nestedSelect), import_kysely8.IdentifierNode.create(table.alias ?? table.model))
2860
+ };
2861
+ }
2862
+ transformInsertQuery(node) {
2863
+ let onConflict = node.onConflict;
2864
+ if (onConflict?.updates) {
2865
+ const { mutationModel, alias } = this.getMutationModel(node);
2866
+ const filter = this.buildPolicyFilter(mutationModel, alias, "update");
2867
+ if (onConflict.updateWhere) {
2868
+ onConflict = {
2869
+ ...onConflict,
2870
+ updateWhere: import_kysely8.WhereNode.create(conjunction(this.dialect, [
2871
+ onConflict.updateWhere.where,
2872
+ filter
2873
+ ]))
2874
+ };
2875
+ } else {
2876
+ onConflict = {
2877
+ ...onConflict,
2878
+ updateWhere: import_kysely8.WhereNode.create(filter)
2879
+ };
2880
+ }
2881
+ }
2882
+ const processedNode = onConflict ? {
2883
+ ...node,
2884
+ onConflict
2885
+ } : node;
2886
+ const result = super.transformInsertQuery(processedNode);
2887
+ if (!node.returning) {
2888
+ return result;
2889
+ }
2890
+ if (this.onlyReturningId(node)) {
2450
2891
  return result;
2892
+ } else {
2893
+ const { mutationModel } = this.getMutationModel(node);
2894
+ const idFields = requireIdFields(this.client.$schema, mutationModel);
2895
+ return {
2896
+ ...result,
2897
+ returning: import_kysely8.ReturningNode.create(idFields.map((field) => import_kysely8.SelectionNode.create(import_kysely8.ColumnNode.create(field))))
2898
+ };
2451
2899
  }
2452
2900
  }
2901
+ transformUpdateQuery(node) {
2902
+ const result = super.transformUpdateQuery(node);
2903
+ const { mutationModel, alias } = this.getMutationModel(node);
2904
+ let filter = this.buildPolicyFilter(mutationModel, alias, "update");
2905
+ if (node.from) {
2906
+ const joinFilter = this.createPolicyFilterForFrom(node.from);
2907
+ if (joinFilter) {
2908
+ filter = conjunction(this.dialect, [
2909
+ filter,
2910
+ joinFilter
2911
+ ]);
2912
+ }
2913
+ }
2914
+ return {
2915
+ ...result,
2916
+ where: import_kysely8.WhereNode.create(result.where ? conjunction(this.dialect, [
2917
+ result.where.where,
2918
+ filter
2919
+ ]) : filter)
2920
+ };
2921
+ }
2922
+ transformDeleteQuery(node) {
2923
+ const result = super.transformDeleteQuery(node);
2924
+ const { mutationModel, alias } = this.getMutationModel(node);
2925
+ let filter = this.buildPolicyFilter(mutationModel, alias, "delete");
2926
+ if (node.using) {
2927
+ const joinFilter = this.createPolicyFilterForTables(node.using.tables);
2928
+ if (joinFilter) {
2929
+ filter = conjunction(this.dialect, [
2930
+ filter,
2931
+ joinFilter
2932
+ ]);
2933
+ }
2934
+ }
2935
+ return {
2936
+ ...result,
2937
+ where: import_kysely8.WhereNode.create(result.where ? conjunction(this.dialect, [
2938
+ result.where.where,
2939
+ filter
2940
+ ]) : filter)
2941
+ };
2942
+ }
2943
+ // #endregion
2944
+ // #region helpers
2453
2945
  onlyReturningId(node) {
2454
2946
  if (!node.returning) {
2455
2947
  return true;
2456
2948
  }
2457
- const idFields = getIdFields(this.client.$schema, this.getMutationModel(node));
2949
+ const { mutationModel } = this.getMutationModel(node);
2950
+ const idFields = requireIdFields(this.client.$schema, mutationModel);
2458
2951
  const collector = new ColumnCollector();
2459
2952
  const selectedColumns = collector.collect(node.returning);
2460
2953
  return selectedColumns.every((c) => idFields.includes(c));
2461
2954
  }
2462
- async enforcePreCreatePolicy(node, proceed) {
2463
- if (!node.columns || !node.values) {
2464
- return;
2465
- }
2466
- const model = this.getMutationModel(node);
2467
- const fields = node.columns.map((c) => c.column.name);
2468
- const valueRows = this.unwrapCreateValueRows(node.values, model, fields);
2955
+ async enforcePreCreatePolicy(node, mutationModel, isManyToManyJoinTable, proceed) {
2956
+ const fields = node.columns?.map((c) => c.column.name) ?? [];
2957
+ const valueRows = node.values ? this.unwrapCreateValueRows(node.values, mutationModel, fields, isManyToManyJoinTable) : [
2958
+ []
2959
+ ];
2469
2960
  for (const values of valueRows) {
2470
- await this.enforcePreCreatePolicyForOne(model, fields, values.map((v) => v.node), values.map((v) => v.raw), proceed);
2961
+ if (isManyToManyJoinTable) {
2962
+ await this.enforcePreCreatePolicyForManyToManyJoinTable(mutationModel, fields, values.map((v) => v.node), proceed);
2963
+ } else {
2964
+ await this.enforcePreCreatePolicyForOne(mutationModel, fields, values.map((v) => v.node), proceed);
2965
+ }
2966
+ }
2967
+ }
2968
+ async enforcePreCreatePolicyForManyToManyJoinTable(tableName, fields, values, proceed) {
2969
+ const m2m = this.resolveManyToManyJoinTable(tableName);
2970
+ (0, import_common_helpers7.invariant)(m2m);
2971
+ (0, import_common_helpers7.invariant)(fields.includes("A") && fields.includes("B"), "many-to-many join table must have A and B fk fields");
2972
+ const aIndex = fields.indexOf("A");
2973
+ const aNode = values[aIndex];
2974
+ const bIndex = fields.indexOf("B");
2975
+ const bNode = values[bIndex];
2976
+ (0, import_common_helpers7.invariant)(import_kysely8.ValueNode.is(aNode) && import_kysely8.ValueNode.is(bNode), "A and B values must be ValueNode");
2977
+ const aValue = aNode.value;
2978
+ const bValue = bNode.value;
2979
+ (0, import_common_helpers7.invariant)(aValue !== null && aValue !== void 0, "A value cannot be null or undefined");
2980
+ (0, import_common_helpers7.invariant)(bValue !== null && bValue !== void 0, "B value cannot be null or undefined");
2981
+ const eb = (0, import_kysely8.expressionBuilder)();
2982
+ const filterA = this.buildPolicyFilter(m2m.firstModel, void 0, "update");
2983
+ const queryA = eb.selectFrom(m2m.firstModel).where(eb(eb.ref(`${m2m.firstModel}.${m2m.firstIdField}`), "=", aValue)).select(() => new import_kysely8.ExpressionWrapper(filterA).as("$t"));
2984
+ const filterB = this.buildPolicyFilter(m2m.secondModel, void 0, "update");
2985
+ const queryB = eb.selectFrom(m2m.secondModel).where(eb(eb.ref(`${m2m.secondModel}.${m2m.secondIdField}`), "=", bValue)).select(() => new import_kysely8.ExpressionWrapper(filterB).as("$t"));
2986
+ const queryNode = {
2987
+ kind: "SelectQueryNode",
2988
+ selections: [
2989
+ import_kysely8.SelectionNode.create(import_kysely8.AliasNode.create(queryA.toOperationNode(), import_kysely8.IdentifierNode.create("$conditionA"))),
2990
+ import_kysely8.SelectionNode.create(import_kysely8.AliasNode.create(queryB.toOperationNode(), import_kysely8.IdentifierNode.create("$conditionB")))
2991
+ ]
2992
+ };
2993
+ const result = await proceed(queryNode);
2994
+ if (!result.rows[0]?.$conditionA) {
2995
+ throw new RejectedByPolicyError(m2m.firstModel, RejectedByPolicyReason.CANNOT_READ_BACK, `many-to-many relation participant model "${m2m.firstModel}" not updatable`);
2996
+ }
2997
+ if (!result.rows[0]?.$conditionB) {
2998
+ throw new RejectedByPolicyError(m2m.secondModel, RejectedByPolicyReason.NO_ACCESS, `many-to-many relation participant model "${m2m.secondModel}" not updatable`);
2471
2999
  }
2472
3000
  }
2473
- async enforcePreCreatePolicyForOne(model, fields, values, valuesRaw, proceed) {
2474
- const thisEntity = {};
2475
- const thisEntityRaw = {};
2476
- for (let i = 0; i < fields.length; i++) {
2477
- thisEntity[fields[i]] = values[i];
2478
- thisEntityRaw[fields[i]] = valuesRaw[i];
3001
+ async enforcePreCreatePolicyForOne(model, fields, values, proceed) {
3002
+ const allFields = Object.entries(requireModel(this.client.$schema, model).fields).filter(([, def]) => !def.relation);
3003
+ const allValues = [];
3004
+ for (const [name, _def] of allFields) {
3005
+ const index = fields.indexOf(name);
3006
+ if (index >= 0) {
3007
+ allValues.push(values[index]);
3008
+ } else {
3009
+ allValues.push(import_kysely8.ValueNode.createImmediate(null));
3010
+ }
2479
3011
  }
2480
- const filter = this.buildPolicyFilter(model, void 0, "create", thisEntity, thisEntityRaw);
3012
+ const eb = (0, import_kysely8.expressionBuilder)();
3013
+ const constTable = {
3014
+ kind: "SelectQueryNode",
3015
+ from: import_kysely8.FromNode.create([
3016
+ import_kysely8.AliasNode.create(import_kysely8.ParensNode.create(import_kysely8.ValuesNode.create([
3017
+ import_kysely8.ValueListNode.create(allValues)
3018
+ ])), import_kysely8.IdentifierNode.create("$t"))
3019
+ ]),
3020
+ selections: allFields.map(([name, def], index) => {
3021
+ const castedColumnRef = import_kysely8.sql`CAST(${eb.ref(`column${index + 1}`)} as ${import_kysely8.sql.raw(this.dialect.getFieldSqlType(def))})`.as(name);
3022
+ return import_kysely8.SelectionNode.create(castedColumnRef.toOperationNode());
3023
+ })
3024
+ };
3025
+ const filter = this.buildPolicyFilter(model, void 0, "create");
2481
3026
  const preCreateCheck = {
2482
3027
  kind: "SelectQueryNode",
3028
+ from: import_kysely8.FromNode.create([
3029
+ import_kysely8.AliasNode.create(constTable, import_kysely8.IdentifierNode.create(model))
3030
+ ]),
2483
3031
  selections: [
2484
- import_kysely7.SelectionNode.create(import_kysely7.AliasNode.create(filter, import_kysely7.IdentifierNode.create("$condition")))
2485
- ]
3032
+ import_kysely8.SelectionNode.create(import_kysely8.AliasNode.create(import_kysely8.BinaryOperationNode.create(import_kysely8.FunctionNode.create("COUNT", [
3033
+ import_kysely8.ValueNode.createImmediate(1)
3034
+ ]), import_kysely8.OperatorNode.create(">"), import_kysely8.ValueNode.createImmediate(0)), import_kysely8.IdentifierNode.create("$condition")))
3035
+ ],
3036
+ where: import_kysely8.WhereNode.create(filter)
2486
3037
  };
2487
3038
  const result = await proceed(preCreateCheck);
2488
3039
  if (!result.rows[0]?.$condition) {
2489
3040
  throw new RejectedByPolicyError(model);
2490
3041
  }
2491
3042
  }
2492
- unwrapCreateValueRows(node, model, fields) {
2493
- if (import_kysely7.ValuesNode.is(node)) {
2494
- return node.values.map((v) => this.unwrapCreateValueRow(v.values, model, fields));
2495
- } else if (import_kysely7.PrimitiveValueListNode.is(node)) {
3043
+ unwrapCreateValueRows(node, model, fields, isManyToManyJoinTable) {
3044
+ if (import_kysely8.ValuesNode.is(node)) {
3045
+ return node.values.map((v) => this.unwrapCreateValueRow(v.values, model, fields, isManyToManyJoinTable));
3046
+ } else if (import_kysely8.PrimitiveValueListNode.is(node)) {
2496
3047
  return [
2497
- this.unwrapCreateValueRow(node.values, model, fields)
3048
+ this.unwrapCreateValueRow(node.values, model, fields, isManyToManyJoinTable)
2498
3049
  ];
2499
3050
  } else {
2500
3051
  throw new InternalError(`Unexpected node kind: ${node.kind} for unwrapping create values`);
2501
3052
  }
2502
3053
  }
2503
- unwrapCreateValueRow(data, model, fields) {
2504
- (0, import_common_helpers6.invariant)(data.length === fields.length, "data length must match fields length");
3054
+ unwrapCreateValueRow(data, model, fields, isImplicitManyToManyJoinTable) {
3055
+ (0, import_common_helpers7.invariant)(data.length === fields.length, "data length must match fields length");
2505
3056
  const result = [];
2506
3057
  for (let i = 0; i < data.length; i++) {
2507
3058
  const item = data[i];
2508
- const fieldDef = requireField(this.client.$schema, model, fields[i]);
2509
3059
  if (typeof item === "object" && item && "kind" in item) {
2510
- (0, import_common_helpers6.invariant)(item.kind === "ValueNode", "expecting a ValueNode");
3060
+ const fieldDef = requireField(this.client.$schema, model, fields[i]);
3061
+ (0, import_common_helpers7.invariant)(item.kind === "ValueNode", "expecting a ValueNode");
2511
3062
  result.push({
2512
- node: import_kysely7.ValueNode.create(this.dialect.transformPrimitive(item.value, fieldDef.type, !!fieldDef.array)),
3063
+ node: import_kysely8.ValueNode.create(this.dialect.transformPrimitive(item.value, fieldDef.type, !!fieldDef.array)),
2513
3064
  raw: item.value
2514
3065
  });
2515
3066
  } else {
2516
- const value = this.dialect.transformPrimitive(item, fieldDef.type, !!fieldDef.array);
3067
+ let value = item;
3068
+ if (!isImplicitManyToManyJoinTable) {
3069
+ const fieldDef = requireField(this.client.$schema, model, fields[i]);
3070
+ value = this.dialect.transformPrimitive(item, fieldDef.type, !!fieldDef.array);
3071
+ }
2517
3072
  if (Array.isArray(value)) {
2518
3073
  result.push({
2519
- node: import_kysely7.RawNode.createWithSql(this.dialect.buildArrayLiteralSQL(value)),
3074
+ node: import_kysely8.RawNode.createWithSql(this.dialect.buildArrayLiteralSQL(value)),
2520
3075
  raw: value
2521
3076
  });
2522
3077
  } else {
2523
3078
  result.push({
2524
- node: import_kysely7.ValueNode.create(value),
3079
+ node: import_kysely8.ValueNode.create(value),
2525
3080
  raw: value
2526
3081
  });
2527
3082
  }
@@ -2557,18 +3112,15 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2557
3112
  if (!this.isMutationQueryNode(node) || !node.returning) {
2558
3113
  return result;
2559
3114
  }
2560
- const table = this.getMutationModel(node);
2561
- if (!table) {
2562
- throw new InternalError(`Unable to get table name for query node: ${node}`);
2563
- }
2564
- const idConditions = this.buildIdConditions(table, result.rows);
2565
- const policyFilter = this.buildPolicyFilter(table, void 0, "read");
3115
+ const { mutationModel } = this.getMutationModel(node);
3116
+ const idConditions = this.buildIdConditions(mutationModel, result.rows);
3117
+ const policyFilter = this.buildPolicyFilter(mutationModel, void 0, "read");
2566
3118
  const select = {
2567
3119
  kind: "SelectQueryNode",
2568
- from: import_kysely7.FromNode.create([
2569
- import_kysely7.TableNode.create(table)
3120
+ from: import_kysely8.FromNode.create([
3121
+ import_kysely8.TableNode.create(mutationModel)
2570
3122
  ]),
2571
- where: import_kysely7.WhereNode.create(conjunction(this.dialect, [
3123
+ where: import_kysely8.WhereNode.create(conjunction(this.dialect, [
2572
3124
  idConditions,
2573
3125
  policyFilter
2574
3126
  ])),
@@ -2578,15 +3130,31 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2578
3130
  return selectResult;
2579
3131
  }
2580
3132
  buildIdConditions(table, rows) {
2581
- const idFields = getIdFields(this.client.$schema, table);
2582
- return disjunction(this.dialect, rows.map((row) => conjunction(this.dialect, idFields.map((field) => import_kysely7.BinaryOperationNode.create(import_kysely7.ColumnNode.create(field), import_kysely7.OperatorNode.create("="), import_kysely7.ValueNode.create(row[field]))))));
3133
+ const idFields = requireIdFields(this.client.$schema, table);
3134
+ return disjunction(this.dialect, rows.map((row) => conjunction(this.dialect, idFields.map((field) => import_kysely8.BinaryOperationNode.create(import_kysely8.ColumnNode.create(field), import_kysely8.OperatorNode.create("="), import_kysely8.ValueNode.create(row[field]))))));
2583
3135
  }
2584
3136
  getMutationModel(node) {
2585
- const r = (0, import_ts_pattern8.match)(node).when(import_kysely7.InsertQueryNode.is, (node2) => getTableName(node2.into)).when(import_kysely7.UpdateQueryNode.is, (node2) => getTableName(node2.table)).when(import_kysely7.DeleteQueryNode.is, (node2) => {
3137
+ const r = (0, import_ts_pattern8.match)(node).when(import_kysely8.InsertQueryNode.is, (node2) => ({
3138
+ mutationModel: getTableName(node2.into),
3139
+ alias: void 0
3140
+ })).when(import_kysely8.UpdateQueryNode.is, (node2) => {
3141
+ if (!node2.table) {
3142
+ throw new QueryError("Update query must have a table");
3143
+ }
3144
+ const r2 = this.extractTableName(node2.table);
3145
+ return r2 ? {
3146
+ mutationModel: r2.model,
3147
+ alias: r2.alias
3148
+ } : void 0;
3149
+ }).when(import_kysely8.DeleteQueryNode.is, (node2) => {
2586
3150
  if (node2.from.froms.length !== 1) {
2587
- throw new InternalError("Only one from table is supported for delete");
3151
+ throw new QueryError("Only one from table is supported for delete");
2588
3152
  }
2589
- return getTableName(node2.from.froms[0]);
3153
+ const r2 = this.extractTableName(node2.from.froms[0]);
3154
+ return r2 ? {
3155
+ mutationModel: r2.model,
3156
+ alias: r2.alias
3157
+ } : void 0;
2590
3158
  }).exhaustive();
2591
3159
  if (!r) {
2592
3160
  throw new InternalError(`Unable to get table name for query node: ${node}`);
@@ -2594,18 +3162,22 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2594
3162
  return r;
2595
3163
  }
2596
3164
  isCrudQueryNode(node) {
2597
- return import_kysely7.SelectQueryNode.is(node) || import_kysely7.InsertQueryNode.is(node) || import_kysely7.UpdateQueryNode.is(node) || import_kysely7.DeleteQueryNode.is(node);
3165
+ return import_kysely8.SelectQueryNode.is(node) || import_kysely8.InsertQueryNode.is(node) || import_kysely8.UpdateQueryNode.is(node) || import_kysely8.DeleteQueryNode.is(node);
2598
3166
  }
2599
3167
  isMutationQueryNode(node) {
2600
- return import_kysely7.InsertQueryNode.is(node) || import_kysely7.UpdateQueryNode.is(node) || import_kysely7.DeleteQueryNode.is(node);
3168
+ return import_kysely8.InsertQueryNode.is(node) || import_kysely8.UpdateQueryNode.is(node) || import_kysely8.DeleteQueryNode.is(node);
2601
3169
  }
2602
- buildPolicyFilter(model, alias, operation, thisEntity, thisEntityRaw) {
3170
+ buildPolicyFilter(model, alias, operation) {
3171
+ const m2mFilter = this.getModelPolicyFilterForManyToManyJoinTable(model, alias, operation);
3172
+ if (m2mFilter) {
3173
+ return m2mFilter;
3174
+ }
2603
3175
  const policies = this.getModelPolicies(model, operation);
2604
3176
  if (policies.length === 0) {
2605
3177
  return falseNode(this.dialect);
2606
3178
  }
2607
- const allows = policies.filter((policy) => policy.kind === "allow").map((policy) => this.transformPolicyCondition(model, alias, operation, policy, thisEntity, thisEntityRaw));
2608
- const denies = policies.filter((policy) => policy.kind === "deny").map((policy) => this.transformPolicyCondition(model, alias, operation, policy, thisEntity, thisEntityRaw));
3179
+ const allows = policies.filter((policy) => policy.kind === "allow").map((policy) => this.compilePolicyCondition(model, alias, operation, policy));
3180
+ const denies = policies.filter((policy) => policy.kind === "deny").map((policy) => this.compilePolicyCondition(model, alias, operation, policy));
2609
3181
  let combinedPolicy;
2610
3182
  if (allows.length === 0) {
2611
3183
  combinedPolicy = falseNode(this.dialect);
@@ -2614,109 +3186,66 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2614
3186
  if (denies.length !== 0) {
2615
3187
  const combinedDenies = conjunction(this.dialect, denies.map((d) => buildIsFalse(d, this.dialect)));
2616
3188
  combinedPolicy = conjunction(this.dialect, [
2617
- combinedPolicy,
2618
- combinedDenies
2619
- ]);
2620
- }
2621
- }
2622
- return combinedPolicy;
2623
- }
2624
- transformSelectQuery(node) {
2625
- let whereNode = node.where;
2626
- node.from?.froms.forEach((from) => {
2627
- const extractResult = this.extractTableName(from);
2628
- if (extractResult) {
2629
- const { model, alias } = extractResult;
2630
- const filter = this.buildPolicyFilter(model, alias, "read");
2631
- whereNode = import_kysely7.WhereNode.create(whereNode?.where ? conjunction(this.dialect, [
2632
- whereNode.where,
2633
- filter
2634
- ]) : filter);
2635
- }
2636
- });
2637
- const baseResult = super.transformSelectQuery({
2638
- ...node,
2639
- where: void 0
2640
- });
2641
- return {
2642
- ...baseResult,
2643
- where: whereNode
2644
- };
2645
- }
2646
- transformInsertQuery(node) {
2647
- const result = super.transformInsertQuery(node);
2648
- if (!node.returning) {
2649
- return result;
2650
- }
2651
- if (this.onlyReturningId(node)) {
2652
- return result;
2653
- } else {
2654
- const idFields = getIdFields(this.client.$schema, this.getMutationModel(node));
2655
- return {
2656
- ...result,
2657
- returning: import_kysely7.ReturningNode.create(idFields.map((field) => import_kysely7.SelectionNode.create(import_kysely7.ColumnNode.create(field))))
2658
- };
2659
- }
2660
- }
2661
- transformUpdateQuery(node) {
2662
- const result = super.transformUpdateQuery(node);
2663
- const mutationModel = this.getMutationModel(node);
2664
- const filter = this.buildPolicyFilter(mutationModel, void 0, "update");
2665
- return {
2666
- ...result,
2667
- where: import_kysely7.WhereNode.create(result.where ? conjunction(this.dialect, [
2668
- result.where.where,
2669
- filter
2670
- ]) : filter)
2671
- };
2672
- }
2673
- transformDeleteQuery(node) {
2674
- const result = super.transformDeleteQuery(node);
2675
- const mutationModel = this.getMutationModel(node);
2676
- const filter = this.buildPolicyFilter(mutationModel, void 0, "delete");
2677
- return {
2678
- ...result,
2679
- where: import_kysely7.WhereNode.create(result.where ? conjunction(this.dialect, [
2680
- result.where.where,
2681
- filter
2682
- ]) : filter)
2683
- };
3189
+ combinedPolicy,
3190
+ combinedDenies
3191
+ ]);
3192
+ }
3193
+ }
3194
+ return combinedPolicy;
2684
3195
  }
2685
- extractTableName(from) {
2686
- if (import_kysely7.TableNode.is(from)) {
3196
+ extractTableName(node) {
3197
+ if (import_kysely8.TableNode.is(node)) {
2687
3198
  return {
2688
- model: from.table.identifier.name
3199
+ model: node.table.identifier.name
2689
3200
  };
2690
3201
  }
2691
- if (import_kysely7.AliasNode.is(from)) {
2692
- const inner = this.extractTableName(from.node);
3202
+ if (import_kysely8.AliasNode.is(node)) {
3203
+ const inner = this.extractTableName(node.node);
2693
3204
  if (!inner) {
2694
3205
  return void 0;
2695
3206
  }
2696
3207
  return {
2697
3208
  model: inner.model,
2698
- alias: import_kysely7.IdentifierNode.is(from.alias) ? from.alias.name : void 0
3209
+ alias: import_kysely8.IdentifierNode.is(node.alias) ? node.alias.name : void 0
2699
3210
  };
2700
3211
  } else {
2701
3212
  return void 0;
2702
3213
  }
2703
3214
  }
2704
- transformPolicyCondition(model, alias, operation, policy, thisEntity, thisEntityRaw) {
2705
- return new ExpressionTransformer(this.client.$schema, this.client.$options, this.client.$auth).transform(policy.condition, {
3215
+ createPolicyFilterForFrom(node) {
3216
+ if (!node) {
3217
+ return void 0;
3218
+ }
3219
+ return this.createPolicyFilterForTables(node.froms);
3220
+ }
3221
+ createPolicyFilterForTables(tables) {
3222
+ return tables.reduce((acc, table) => {
3223
+ const extractResult = this.extractTableName(table);
3224
+ if (extractResult) {
3225
+ const { model, alias } = extractResult;
3226
+ const filter = this.buildPolicyFilter(model, alias, "read");
3227
+ return acc ? conjunction(this.dialect, [
3228
+ acc,
3229
+ filter
3230
+ ]) : filter;
3231
+ }
3232
+ return acc;
3233
+ }, void 0);
3234
+ }
3235
+ compilePolicyCondition(model, alias, operation, policy) {
3236
+ return new ExpressionTransformer(this.client).transform(policy.condition, {
2706
3237
  model,
2707
3238
  alias,
2708
3239
  operation,
2709
- thisEntity,
2710
- thisEntityRaw,
2711
3240
  auth: this.client.$auth
2712
3241
  });
2713
3242
  }
2714
- getModelPolicies(modelName, operation) {
2715
- const modelDef = requireModel(this.client.$schema, modelName);
3243
+ getModelPolicies(model, operation) {
3244
+ const modelDef = requireModel(this.client.$schema, model);
2716
3245
  const result = [];
2717
3246
  const extractOperations = /* @__PURE__ */ __name((expr2) => {
2718
- (0, import_common_helpers6.invariant)(ExpressionUtils.isLiteral(expr2), "expecting a literal");
2719
- (0, import_common_helpers6.invariant)(typeof expr2.value === "string", "expecting a string literal");
3247
+ (0, import_common_helpers7.invariant)(ExpressionUtils.isLiteral(expr2), "expecting a literal");
3248
+ (0, import_common_helpers7.invariant)(typeof expr2.value === "string", "expecting a string literal");
2720
3249
  return expr2.value.split(",").filter((v) => !!v).map((v) => v.trim());
2721
3250
  }, "extractOperations");
2722
3251
  if (modelDef.attributes) {
@@ -2728,8 +3257,84 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2728
3257
  }
2729
3258
  return result;
2730
3259
  }
3260
+ resolveManyToManyJoinTable(tableName) {
3261
+ for (const model of Object.values(this.client.$schema.models)) {
3262
+ for (const field of Object.values(model.fields)) {
3263
+ const m2m = getManyToManyRelation(this.client.$schema, model.name, field.name);
3264
+ if (m2m?.joinTable === tableName) {
3265
+ const sortedRecord = [
3266
+ {
3267
+ model: model.name,
3268
+ field: field.name
3269
+ },
3270
+ {
3271
+ model: m2m.otherModel,
3272
+ field: m2m.otherField
3273
+ }
3274
+ ].sort(this.manyToManySorter);
3275
+ const firstIdFields = requireIdFields(this.client.$schema, sortedRecord[0].model);
3276
+ const secondIdFields = requireIdFields(this.client.$schema, sortedRecord[1].model);
3277
+ (0, import_common_helpers7.invariant)(firstIdFields.length === 1 && secondIdFields.length === 1, "only single-field id is supported for implicit many-to-many join table");
3278
+ return {
3279
+ firstModel: sortedRecord[0].model,
3280
+ firstField: sortedRecord[0].field,
3281
+ firstIdField: firstIdFields[0],
3282
+ secondModel: sortedRecord[1].model,
3283
+ secondField: sortedRecord[1].field,
3284
+ secondIdField: secondIdFields[0]
3285
+ };
3286
+ }
3287
+ }
3288
+ }
3289
+ return void 0;
3290
+ }
3291
+ manyToManySorter(a, b) {
3292
+ return a.model !== b.model ? a.model.localeCompare(b.model) : a.field.localeCompare(b.field);
3293
+ }
3294
+ isManyToManyJoinTable(tableName) {
3295
+ return !!this.resolveManyToManyJoinTable(tableName);
3296
+ }
3297
+ getModelPolicyFilterForManyToManyJoinTable(tableName, alias, operation) {
3298
+ const m2m = this.resolveManyToManyJoinTable(tableName);
3299
+ if (!m2m) {
3300
+ return void 0;
3301
+ }
3302
+ const checkForOperation = operation === "read" ? "read" : "update";
3303
+ const eb = (0, import_kysely8.expressionBuilder)();
3304
+ const joinTable = alias ?? tableName;
3305
+ const aQuery = eb.selectFrom(m2m.firstModel).whereRef(`${m2m.firstModel}.${m2m.firstIdField}`, "=", `${joinTable}.A`).select(() => new import_kysely8.ExpressionWrapper(this.buildPolicyFilter(m2m.firstModel, void 0, checkForOperation)).as("$conditionA"));
3306
+ const bQuery = eb.selectFrom(m2m.secondModel).whereRef(`${m2m.secondModel}.${m2m.secondIdField}`, "=", `${joinTable}.B`).select(() => new import_kysely8.ExpressionWrapper(this.buildPolicyFilter(m2m.secondModel, void 0, checkForOperation)).as("$conditionB"));
3307
+ return eb.and([
3308
+ aQuery,
3309
+ bQuery
3310
+ ]).toOperationNode();
3311
+ }
2731
3312
  };
2732
3313
 
3314
+ // src/plugins/policy/functions.ts
3315
+ var check = /* @__PURE__ */ __name((eb, args, { client, model, modelAlias, operation }) => {
3316
+ (0, import_common_helpers8.invariant)(args.length === 1 || args.length === 2, '"check" function requires 1 or 2 arguments');
3317
+ const arg1Node = args[0].toOperationNode();
3318
+ const arg2Node = args.length === 2 ? args[1].toOperationNode() : void 0;
3319
+ if (arg2Node) {
3320
+ (0, import_common_helpers8.invariant)(import_kysely9.ValueNode.is(arg2Node) && typeof arg2Node.value === "string", '"operation" parameter must be a string literal when provided');
3321
+ (0, import_common_helpers8.invariant)(CRUD.includes(arg2Node.value), '"operation" parameter must be one of "create", "read", "update", "delete"');
3322
+ }
3323
+ const fieldName = extractFieldName(arg1Node);
3324
+ (0, import_common_helpers8.invariant)(fieldName, 'Failed to extract field name from the first argument of "check" function');
3325
+ const fieldDef = requireField(client.$schema, model, fieldName);
3326
+ (0, import_common_helpers8.invariant)(fieldDef.relation, `Field "${fieldName}" is not a relation field in model "${model}"`);
3327
+ (0, import_common_helpers8.invariant)(!fieldDef.array, `Field "${fieldName}" is a to-many relation, which is not supported by "check"`);
3328
+ const relationModel = fieldDef.type;
3329
+ const op = arg2Node ? arg2Node.value : operation;
3330
+ const policyHandler = new PolicyHandler(client);
3331
+ const joinPairs = buildJoinPairs(client.$schema, model, modelAlias, fieldName, relationModel);
3332
+ const joinCondition = joinPairs.length === 1 ? eb(eb.ref(joinPairs[0][0]), "=", eb.ref(joinPairs[0][1])) : eb.and(joinPairs.map(([left, right]) => eb(eb.ref(left), "=", eb.ref(right))));
3333
+ const policyCondition = policyHandler.buildPolicyFilter(relationModel, void 0, op);
3334
+ const result = eb.selectFrom(relationModel).where(joinCondition).select(new import_kysely9.ExpressionWrapper(policyCondition).as("$condition"));
3335
+ return result;
3336
+ }, "check");
3337
+
2733
3338
  // src/plugins/policy/plugin.ts
2734
3339
  var PolicyPlugin = class {
2735
3340
  static {
@@ -2744,6 +3349,11 @@ var PolicyPlugin = class {
2744
3349
  get description() {
2745
3350
  return "Enforces access policies defined in the schema.";
2746
3351
  }
3352
+ get functions() {
3353
+ return {
3354
+ check
3355
+ };
3356
+ }
2747
3357
  onKyselyQuery({
2748
3358
  query,
2749
3359
  client,
@@ -2760,13 +3370,13 @@ var PolicyPlugin = class {
2760
3370
  };
2761
3371
 
2762
3372
  // src/utils/clone.ts
2763
- var import_common_helpers7 = require("@zenstackhq/common-helpers");
3373
+ var import_common_helpers9 = require("@zenstackhq/common-helpers");
2764
3374
  function clone(value) {
2765
3375
  if (Array.isArray(value)) {
2766
3376
  return value.map((v) => clone(v));
2767
3377
  }
2768
3378
  if (typeof value === "object") {
2769
- if (!value || !(0, import_common_helpers7.isPlainObject)(value)) {
3379
+ if (!value || !(0, import_common_helpers9.isPlainObject)(value)) {
2770
3380
  return value;
2771
3381
  }
2772
3382
  const result = {};
@@ -2779,16 +3389,6 @@ function clone(value) {
2779
3389
  }
2780
3390
  __name(clone, "clone");
2781
3391
 
2782
- // src/client/contract.ts
2783
- var TransactionIsolationLevel = /* @__PURE__ */ function(TransactionIsolationLevel2) {
2784
- TransactionIsolationLevel2["ReadUncommitted"] = "read uncommitted";
2785
- TransactionIsolationLevel2["ReadCommitted"] = "read committed";
2786
- TransactionIsolationLevel2["RepeatableRead"] = "repeatable read";
2787
- TransactionIsolationLevel2["Serializable"] = "serializable";
2788
- TransactionIsolationLevel2["Snapshot"] = "snapshot";
2789
- return TransactionIsolationLevel2;
2790
- }({});
2791
-
2792
3392
  // src/client/crud/operations/base.ts
2793
3393
  var BaseOperationHandler = class {
2794
3394
  static {
@@ -2833,7 +3433,7 @@ var BaseOperationHandler = class {
2833
3433
  return getField(this.schema, model, field);
2834
3434
  }
2835
3435
  async exists(kysely, model, filter) {
2836
- const idFields = getIdFields(this.schema, model);
3436
+ const idFields = requireIdFields(this.schema, model);
2837
3437
  const _filter = flattenCompoundUniqueFilters(this.schema, model, filter);
2838
3438
  const query = kysely.selectFrom(model).where((eb) => eb.and(_filter)).select(idFields.map((f) => kysely.dynamic.ref(f))).limit(1).modifyEnd(this.makeContextComment({
2839
3439
  model,
@@ -2842,7 +3442,7 @@ var BaseOperationHandler = class {
2842
3442
  return this.executeQueryTakeFirst(kysely, query, "exists");
2843
3443
  }
2844
3444
  async read(kysely, model, args) {
2845
- let query = this.dialect.buildSelectModel((0, import_kysely8.expressionBuilder)(), model, model);
3445
+ let query = this.dialect.buildSelectModel((0, import_kysely10.expressionBuilder)(), model, model);
2846
3446
  if (args) {
2847
3447
  query = this.dialect.buildFilterSortTake(model, args, query, model);
2848
3448
  }
@@ -2914,26 +3514,21 @@ var BaseOperationHandler = class {
2914
3514
  throw new QueryError(`Model "${this.model}" is a delegate and cannot be created directly.`);
2915
3515
  }
2916
3516
  let createFields = {};
2917
- let parentUpdateTask = void 0;
3517
+ let updateParent = void 0;
2918
3518
  let m2m = void 0;
2919
3519
  if (fromRelation) {
2920
3520
  m2m = getManyToManyRelation(this.schema, fromRelation.model, fromRelation.field);
2921
3521
  if (!m2m) {
2922
3522
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation?.model ?? "", fromRelation?.field ?? "");
2923
3523
  if (!ownedByModel) {
2924
- const parentFkFields = this.buildFkAssignments(fromRelation.model, fromRelation.field, fromRelation.ids);
3524
+ const parentFkFields = await this.buildFkAssignments(kysely, fromRelation.model, fromRelation.field, fromRelation.ids);
2925
3525
  Object.assign(createFields, parentFkFields);
2926
3526
  } else {
2927
- parentUpdateTask = /* @__PURE__ */ __name((entity) => {
2928
- const query2 = kysely.updateTable(fromRelation.model).set(keyPairs.reduce((acc, { fk, pk }) => ({
2929
- ...acc,
2930
- [fk]: entity[pk]
2931
- }), {})).where((eb) => eb.and(fromRelation.ids)).modifyEnd(this.makeContextComment({
2932
- model: fromRelation.model,
2933
- operation: "update"
2934
- }));
2935
- return this.executeQuery(kysely, query2, "update");
2936
- }, "parentUpdateTask");
3527
+ updateParent = /* @__PURE__ */ __name((entity) => {
3528
+ for (const { fk, pk } of keyPairs) {
3529
+ fromRelation.parentUpdates[fk] = entity[pk];
3530
+ }
3531
+ }, "updateParent");
2937
3532
  }
2938
3533
  }
2939
3534
  }
@@ -2965,24 +3560,23 @@ var BaseOperationHandler = class {
2965
3560
  const baseCreateResult = await this.processBaseModelCreate(kysely, modelDef.baseModel, createFields, model);
2966
3561
  createFields = baseCreateResult.remainingFields;
2967
3562
  }
2968
- const updatedData = this.fillGeneratedValues(modelDef, createFields);
2969
- const idFields = getIdFields(this.schema, model);
3563
+ const updatedData = this.fillGeneratedAndDefaultValues(modelDef, createFields);
3564
+ const idFields = requireIdFields(this.schema, model);
2970
3565
  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({
2971
3566
  model,
2972
3567
  operation: "create"
2973
3568
  }));
2974
3569
  const createdEntity = await this.executeQueryTakeFirst(kysely, query, "create");
2975
3570
  if (Object.keys(postCreateRelations).length > 0) {
2976
- const relationPromises = Object.entries(postCreateRelations).map(([field, subPayload]) => {
2977
- return this.processNoneOwnedRelationForCreate(kysely, model, field, subPayload, createdEntity);
2978
- });
2979
- await Promise.all(relationPromises);
3571
+ for (const [field, subPayload] of Object.entries(postCreateRelations)) {
3572
+ await this.processNoneOwnedRelationForCreate(kysely, model, field, subPayload, createdEntity);
3573
+ }
2980
3574
  }
2981
3575
  if (fromRelation && m2m) {
2982
3576
  await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, createdEntity, m2m.joinTable);
2983
3577
  }
2984
- if (parentUpdateTask) {
2985
- await parentUpdateTask(createdEntity);
3578
+ if (updateParent) {
3579
+ updateParent(createdEntity);
2986
3580
  }
2987
3581
  return createdEntity;
2988
3582
  }
@@ -2998,7 +3592,7 @@ var BaseOperationHandler = class {
2998
3592
  }
2999
3593
  });
3000
3594
  const discriminatorField = getDiscriminatorField(this.schema, model);
3001
- (0, import_common_helpers8.invariant)(discriminatorField, `Base model "${model}" must have a discriminator field`);
3595
+ (0, import_common_helpers10.invariant)(discriminatorField, `Base model "${model}" must have a discriminator field`);
3002
3596
  thisCreateFields[discriminatorField] = forModel;
3003
3597
  const baseEntity = await this.create(kysely, model, thisCreateFields, void 0, true);
3004
3598
  const idValues = extractIdFields(baseEntity, this.schema, model);
@@ -3008,14 +3602,24 @@ var BaseOperationHandler = class {
3008
3602
  remainingFields
3009
3603
  };
3010
3604
  }
3011
- buildFkAssignments(model, relationField, entity) {
3605
+ async buildFkAssignments(kysely, model, relationField, entity) {
3012
3606
  const parentFkFields = {};
3013
- (0, import_common_helpers8.invariant)(relationField, "parentField must be defined if parentModel is defined");
3014
- (0, import_common_helpers8.invariant)(entity, "parentEntity must be defined if parentModel is defined");
3607
+ (0, import_common_helpers10.invariant)(relationField, "parentField must be defined if parentModel is defined");
3608
+ (0, import_common_helpers10.invariant)(entity, "parentEntity must be defined if parentModel is defined");
3015
3609
  const { keyPairs } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
3016
3610
  for (const pair of keyPairs) {
3017
3611
  if (!(pair.pk in entity)) {
3018
- throw new QueryError(`Field "${pair.pk}" not found in parent created data`);
3612
+ const extraRead = await this.readUnique(kysely, model, {
3613
+ where: entity,
3614
+ select: {
3615
+ [pair.pk]: true
3616
+ }
3617
+ });
3618
+ if (!extraRead) {
3619
+ throw new QueryError(`Field "${pair.pk}" not found in parent created data`);
3620
+ } else {
3621
+ Object.assign(entity, extraRead);
3622
+ }
3019
3623
  }
3020
3624
  Object.assign(parentFkFields, {
3021
3625
  [pair.fk]: entity[pair.pk]
@@ -3036,15 +3640,15 @@ var BaseOperationHandler = class {
3036
3640
  entity: rightEntity
3037
3641
  }
3038
3642
  ].sort((a, b) => (
3039
- // the implement m2m join table's "A", "B" fk fields' order is determined
3643
+ // the implicit m2m join table's "A", "B" fk fields' order is determined
3040
3644
  // by model name's sort order, and when identical (for self-relations),
3041
3645
  // field name's sort order
3042
3646
  a.model !== b.model ? a.model.localeCompare(b.model) : a.field.localeCompare(b.field)
3043
3647
  ));
3044
- const firstIds = getIdFields(this.schema, sortedRecords[0].model);
3045
- const secondIds = getIdFields(this.schema, sortedRecords[1].model);
3046
- (0, import_common_helpers8.invariant)(firstIds.length === 1, "many-to-many relation must have exactly one id field");
3047
- (0, import_common_helpers8.invariant)(secondIds.length === 1, "many-to-many relation must have exactly one id field");
3648
+ const firstIds = requireIdFields(this.schema, sortedRecords[0].model);
3649
+ const secondIds = requireIdFields(this.schema, sortedRecords[1].model);
3650
+ (0, import_common_helpers10.invariant)(firstIds.length === 1, "many-to-many relation must have exactly one id field");
3651
+ (0, import_common_helpers10.invariant)(secondIds.length === 1, "many-to-many relation must have exactly one id field");
3048
3652
  if (action === "connect") {
3049
3653
  const result = await kysely.insertInto(joinTable).values({
3050
3654
  A: sortedRecords[0].entity[firstIds[0]],
@@ -3055,17 +3659,17 @@ var BaseOperationHandler = class {
3055
3659
  ]).doNothing()).execute();
3056
3660
  return result[0];
3057
3661
  } else {
3058
- const eb = (0, import_kysely8.expressionBuilder)();
3662
+ const eb = (0, import_kysely10.expressionBuilder)();
3059
3663
  const result = await kysely.deleteFrom(joinTable).where(eb(`${joinTable}.A`, "=", sortedRecords[0].entity[firstIds[0]])).where(eb(`${joinTable}.B`, "=", sortedRecords[1].entity[secondIds[0]])).execute();
3060
3664
  return result[0];
3061
3665
  }
3062
3666
  }
3063
3667
  resetManyToManyRelation(kysely, model, field, parentIds) {
3064
- (0, import_common_helpers8.invariant)(Object.keys(parentIds).length === 1, "parentIds must have exactly one field");
3668
+ (0, import_common_helpers10.invariant)(Object.keys(parentIds).length === 1, "parentIds must have exactly one field");
3065
3669
  const parentId = Object.values(parentIds)[0];
3066
3670
  const m2m = getManyToManyRelation(this.schema, model, field);
3067
- (0, import_common_helpers8.invariant)(m2m, "not a many-to-many relation");
3068
- const eb = (0, import_kysely8.expressionBuilder)();
3671
+ (0, import_common_helpers10.invariant)(m2m, "not a many-to-many relation");
3672
+ const eb = (0, import_kysely10.expressionBuilder)();
3069
3673
  return kysely.deleteFrom(m2m.joinTable).where(eb(`${m2m.joinTable}.${m2m.parentFkName}`, "=", parentId)).execute();
3070
3674
  }
3071
3675
  async processOwnedRelationForCreate(kysely, relationField, payload) {
@@ -3086,7 +3690,7 @@ var BaseOperationHandler = class {
3086
3690
  }
3087
3691
  case "connect": {
3088
3692
  const referencedPkFields = relationField.relation.references;
3089
- (0, import_common_helpers8.invariant)(referencedPkFields, "relation must have fields info");
3693
+ (0, import_common_helpers10.invariant)(referencedPkFields, "relation must have fields info");
3090
3694
  const extractedFks = extractFields(subPayload, referencedPkFields);
3091
3695
  if (Object.keys(extractedFks).length === referencedPkFields.length) {
3092
3696
  result = extractedFks;
@@ -3096,7 +3700,7 @@ var BaseOperationHandler = class {
3096
3700
  select: fieldsToSelectObject(referencedPkFields)
3097
3701
  });
3098
3702
  if (!relationEntity) {
3099
- throw new NotFoundError(`Could not find the entity for connect action`);
3703
+ throw new NotFoundError(relationModel, `Could not find the entity to connect for the relation "${relationField.name}"`);
3100
3704
  }
3101
3705
  result = relationEntity;
3102
3706
  }
@@ -3118,14 +3722,14 @@ var BaseOperationHandler = class {
3118
3722
  }
3119
3723
  return result;
3120
3724
  }
3121
- processNoneOwnedRelationForCreate(kysely, contextModel, relationFieldName, payload, parentEntity) {
3725
+ async processNoneOwnedRelationForCreate(kysely, contextModel, relationFieldName, payload, parentEntity) {
3122
3726
  const relationFieldDef = this.requireField(contextModel, relationFieldName);
3123
3727
  const relationModel = relationFieldDef.type;
3124
- const tasks = [];
3125
3728
  const fromRelationContext = {
3126
3729
  model: contextModel,
3127
3730
  field: relationFieldName,
3128
- ids: parentEntity
3731
+ ids: parentEntity,
3732
+ parentUpdates: {}
3129
3733
  };
3130
3734
  for (const [action, subPayload] of Object.entries(payload)) {
3131
3735
  if (!subPayload) {
@@ -3133,39 +3737,35 @@ var BaseOperationHandler = class {
3133
3737
  }
3134
3738
  switch (action) {
3135
3739
  case "create": {
3136
- tasks.push(...enumerate(subPayload).map((item) => this.create(kysely, relationModel, item, fromRelationContext)));
3740
+ for (const item of enumerate(subPayload)) {
3741
+ await this.create(kysely, relationModel, item, fromRelationContext);
3742
+ }
3137
3743
  break;
3138
3744
  }
3139
3745
  case "createMany": {
3140
- (0, import_common_helpers8.invariant)(relationFieldDef.array, "relation must be an array for createMany");
3141
- tasks.push(this.createMany(kysely, relationModel, subPayload, false, fromRelationContext));
3746
+ (0, import_common_helpers10.invariant)(relationFieldDef.array, "relation must be an array for createMany");
3747
+ await this.createMany(kysely, relationModel, subPayload, false, fromRelationContext);
3142
3748
  break;
3143
3749
  }
3144
3750
  case "connect": {
3145
- tasks.push(this.connectRelation(kysely, relationModel, subPayload, {
3146
- model: contextModel,
3147
- field: relationFieldName,
3148
- ids: parentEntity
3149
- }));
3751
+ await this.connectRelation(kysely, relationModel, subPayload, fromRelationContext);
3150
3752
  break;
3151
3753
  }
3152
3754
  case "connectOrCreate": {
3153
- tasks.push(...enumerate(subPayload).map((item) => this.exists(kysely, relationModel, item.where).then((found) => !found ? this.create(kysely, relationModel, item.create, {
3154
- model: contextModel,
3155
- field: relationFieldName,
3156
- ids: parentEntity
3157
- }) : this.connectRelation(kysely, relationModel, found, {
3158
- model: contextModel,
3159
- field: relationFieldName,
3160
- ids: parentEntity
3161
- }))));
3755
+ for (const item of enumerate(subPayload)) {
3756
+ const found = await this.exists(kysely, relationModel, item.where);
3757
+ if (!found) {
3758
+ await this.create(kysely, relationModel, item.create, fromRelationContext);
3759
+ } else {
3760
+ await this.connectRelation(kysely, relationModel, found, fromRelationContext);
3761
+ }
3762
+ }
3162
3763
  break;
3163
3764
  }
3164
3765
  default:
3165
3766
  throw new QueryError(`Invalid relation action: ${action}`);
3166
3767
  }
3167
3768
  }
3168
- return Promise.all(tasks);
3169
3769
  }
3170
3770
  async createMany(kysely, model, input, returnData, fromRelation) {
3171
3771
  if (!input.data || Array.isArray(input.data) && input.data.length === 0) {
@@ -3186,7 +3786,7 @@ var BaseOperationHandler = class {
3186
3786
  const newItem = {};
3187
3787
  for (const [name, value] of Object.entries(item)) {
3188
3788
  const fieldDef = this.requireField(model, name);
3189
- (0, import_common_helpers8.invariant)(!fieldDef.relation, "createMany does not support relations");
3789
+ (0, import_common_helpers10.invariant)(!fieldDef.relation, "createMany does not support relations");
3190
3790
  newItem[name] = this.dialect.transformPrimitive(value, fieldDef.type, !!fieldDef.array);
3191
3791
  }
3192
3792
  if (fromRelation) {
@@ -3194,7 +3794,7 @@ var BaseOperationHandler = class {
3194
3794
  newItem[fk] = fromRelation.ids[pk];
3195
3795
  }
3196
3796
  }
3197
- return this.fillGeneratedValues(modelDef, newItem);
3797
+ return this.fillGeneratedAndDefaultValues(modelDef, newItem);
3198
3798
  });
3199
3799
  if (!this.dialect.supportInsertWithDefault) {
3200
3800
  const allPassedFields = createData.reduce((acc, item) => {
@@ -3236,7 +3836,7 @@ var BaseOperationHandler = class {
3236
3836
  count: Number(result.numAffectedRows)
3237
3837
  };
3238
3838
  } else {
3239
- const idFields = getIdFields(this.schema, model);
3839
+ const idFields = requireIdFields(this.schema, model);
3240
3840
  const result = await query.returning(idFields).execute();
3241
3841
  return result;
3242
3842
  }
@@ -3245,7 +3845,7 @@ var BaseOperationHandler = class {
3245
3845
  const thisCreateRows = [];
3246
3846
  const remainingFieldRows = [];
3247
3847
  const discriminatorField = getDiscriminatorField(this.schema, model);
3248
- (0, import_common_helpers8.invariant)(discriminatorField, `Base model "${model}" must have a discriminator field`);
3848
+ (0, import_common_helpers10.invariant)(discriminatorField, `Base model "${model}" must have a discriminator field`);
3249
3849
  for (const createFields of createRows) {
3250
3850
  const thisCreateFields = {};
3251
3851
  const remainingFields = {};
@@ -3274,7 +3874,7 @@ var BaseOperationHandler = class {
3274
3874
  remainingFieldRows
3275
3875
  };
3276
3876
  }
3277
- fillGeneratedValues(modelDef, data) {
3877
+ fillGeneratedAndDefaultValues(modelDef, data) {
3278
3878
  const fields = modelDef.fields;
3279
3879
  const values = clone(data);
3280
3880
  for (const [field, fieldDef] of Object.entries(fields)) {
@@ -3289,6 +3889,16 @@ var BaseOperationHandler = class {
3289
3889
  }
3290
3890
  } else if (fields[field]?.updatedAt) {
3291
3891
  values[field] = this.dialect.transformPrimitive(/* @__PURE__ */ new Date(), "DateTime", false);
3892
+ } else if (fields[field]?.default !== void 0) {
3893
+ let value = fields[field].default;
3894
+ if (fieldDef.type === "Json") {
3895
+ if (fieldDef.array && Array.isArray(value)) {
3896
+ value = value.map((v) => typeof v === "string" ? JSON.parse(v) : v);
3897
+ } else if (typeof value === "string") {
3898
+ value = JSON.parse(value);
3899
+ }
3900
+ }
3901
+ values[field] = this.dialect.transformPrimitive(value, fields[field].type, !!fields[field].array);
3292
3902
  }
3293
3903
  }
3294
3904
  }
@@ -3331,7 +3941,7 @@ var BaseOperationHandler = class {
3331
3941
  }
3332
3942
  } else {
3333
3943
  const fromRelationFieldDef = this.requireField(fromRelation.model, fromRelation.field);
3334
- (0, import_common_helpers8.invariant)(fromRelationFieldDef.relation?.opposite);
3944
+ (0, import_common_helpers10.invariant)(fromRelationFieldDef.relation?.opposite);
3335
3945
  parentWhere[fromRelationFieldDef.relation.opposite] = {
3336
3946
  some: fromRelation.ids
3337
3947
  };
@@ -3389,10 +3999,7 @@ var BaseOperationHandler = class {
3389
3999
  throw new QueryError(`Relation update not allowed for field "${field}"`);
3390
4000
  }
3391
4001
  if (!thisEntity) {
3392
- thisEntity = await this.readUnique(kysely, model, {
3393
- where: combinedWhere,
3394
- select: this.makeIdSelect(model)
3395
- });
4002
+ thisEntity = await this.getEntityIds(kysely, model, combinedWhere);
3396
4003
  if (!thisEntity) {
3397
4004
  if (throwIfNotFound) {
3398
4005
  throw new NotFoundError(model);
@@ -3401,13 +4008,16 @@ var BaseOperationHandler = class {
3401
4008
  }
3402
4009
  }
3403
4010
  }
3404
- await this.processRelationUpdates(kysely, model, field, fieldDef, thisEntity, finalData[field], throwIfNotFound);
4011
+ const parentUpdates = await this.processRelationUpdates(kysely, model, field, fieldDef, thisEntity, finalData[field], throwIfNotFound);
4012
+ if (Object.keys(parentUpdates).length > 0) {
4013
+ Object.assign(updateFields, parentUpdates);
4014
+ }
3405
4015
  }
3406
4016
  }
3407
4017
  if (Object.keys(updateFields).length === 0) {
3408
4018
  return combinedWhere;
3409
4019
  } else {
3410
- const idFields = getIdFields(this.schema, model);
4020
+ const idFields = requireIdFields(this.schema, model);
3411
4021
  const query = kysely.updateTable(model).where((eb) => this.dialect.buildFilter(eb, model, model, combinedWhere)).set(updateFields).returning(idFields).modifyEnd(this.makeContextComment({
3412
4022
  model,
3413
4023
  operation: "update"
@@ -3452,7 +4062,7 @@ var BaseOperationHandler = class {
3452
4062
  if (!filter || typeof filter !== "object") {
3453
4063
  return false;
3454
4064
  }
3455
- const idFields = getIdFields(this.schema, model);
4065
+ const idFields = requireIdFields(this.schema, model);
3456
4066
  return idFields.length === Object.keys(filter).length && idFields.every((field) => field in filter);
3457
4067
  }
3458
4068
  async processBaseModelUpdate(kysely, model, where, updateFields, throwIfNotFound) {
@@ -3473,20 +4083,20 @@ var BaseOperationHandler = class {
3473
4083
  };
3474
4084
  }
3475
4085
  transformIncrementalUpdate(model, field, fieldDef, payload) {
3476
- (0, import_common_helpers8.invariant)(Object.keys(payload).length === 1, 'Only one of "set", "increment", "decrement", "multiply", or "divide" can be provided');
4086
+ (0, import_common_helpers10.invariant)(Object.keys(payload).length === 1, 'Only one of "set", "increment", "decrement", "multiply", or "divide" can be provided');
3477
4087
  const key = Object.keys(payload)[0];
3478
4088
  const value = this.dialect.transformPrimitive(payload[key], fieldDef.type, false);
3479
- const eb = (0, import_kysely8.expressionBuilder)();
4089
+ const eb = (0, import_kysely10.expressionBuilder)();
3480
4090
  const fieldRef = this.dialect.fieldRef(model, field, eb);
3481
4091
  return (0, import_ts_pattern9.match)(key).with("set", () => value).with("increment", () => eb(fieldRef, "+", value)).with("decrement", () => eb(fieldRef, "-", value)).with("multiply", () => eb(fieldRef, "*", value)).with("divide", () => eb(fieldRef, "/", value)).otherwise(() => {
3482
4092
  throw new InternalError(`Invalid incremental update operation: ${key}`);
3483
4093
  });
3484
4094
  }
3485
4095
  transformScalarListUpdate(model, field, fieldDef, payload) {
3486
- (0, import_common_helpers8.invariant)(Object.keys(payload).length === 1, 'Only one of "set", "push" can be provided');
4096
+ (0, import_common_helpers10.invariant)(Object.keys(payload).length === 1, 'Only one of "set", "push" can be provided');
3487
4097
  const key = Object.keys(payload)[0];
3488
4098
  const value = this.dialect.transformPrimitive(payload[key], fieldDef.type, true);
3489
- const eb = (0, import_kysely8.expressionBuilder)();
4099
+ const eb = (0, import_kysely10.expressionBuilder)();
3490
4100
  const fieldRef = this.dialect.fieldRef(model, field, eb);
3491
4101
  return (0, import_ts_pattern9.match)(key).with("set", () => value).with("push", () => {
3492
4102
  return eb(fieldRef, "||", eb.val(ensureArray(value)));
@@ -3498,7 +4108,7 @@ var BaseOperationHandler = class {
3498
4108
  return NUMERIC_FIELD_TYPES.includes(fieldDef.type) && !fieldDef.array;
3499
4109
  }
3500
4110
  makeContextComment(_context) {
3501
- return import_kysely8.sql``;
4111
+ return import_kysely10.sql``;
3502
4112
  }
3503
4113
  async updateMany(kysely, model, where, data, limit, returnData, filterModel) {
3504
4114
  if (typeof data !== "object") {
@@ -3557,7 +4167,7 @@ var BaseOperationHandler = class {
3557
4167
  count: Number(result.numAffectedRows)
3558
4168
  };
3559
4169
  } else {
3560
- const idFields = getIdFields(this.schema, model);
4170
+ const idFields = requireIdFields(this.schema, model);
3561
4171
  const result = await query.returning(idFields).execute();
3562
4172
  return result;
3563
4173
  }
@@ -3580,82 +4190,87 @@ var BaseOperationHandler = class {
3580
4190
  };
3581
4191
  }
3582
4192
  buildIdFieldRefs(kysely, model) {
3583
- const idFields = getIdFields(this.schema, model);
4193
+ const idFields = requireIdFields(this.schema, model);
3584
4194
  return idFields.map((f) => kysely.dynamic.ref(`${model}.${f}`));
3585
4195
  }
3586
4196
  async processRelationUpdates(kysely, model, field, fieldDef, parentIds, args, throwIfNotFound) {
3587
- const tasks = [];
3588
4197
  const fieldModel = fieldDef.type;
3589
4198
  const fromRelationContext = {
3590
4199
  model,
3591
4200
  field,
3592
- ids: parentIds
4201
+ ids: parentIds,
4202
+ parentUpdates: {}
3593
4203
  };
3594
4204
  for (const [key, value] of Object.entries(args)) {
3595
4205
  switch (key) {
3596
4206
  case "create": {
3597
- (0, import_common_helpers8.invariant)(!Array.isArray(value) || fieldDef.array, "relation must be an array if create is an array");
3598
- tasks.push(...enumerate(value).map((item) => this.create(kysely, fieldModel, item, fromRelationContext)));
4207
+ (0, import_common_helpers10.invariant)(!Array.isArray(value) || fieldDef.array, "relation must be an array if create is an array");
4208
+ for (const item of enumerate(value)) {
4209
+ await this.create(kysely, fieldModel, item, fromRelationContext);
4210
+ }
3599
4211
  break;
3600
4212
  }
3601
4213
  case "createMany": {
3602
- (0, import_common_helpers8.invariant)(fieldDef.array, "relation must be an array for createMany");
3603
- tasks.push(this.createMany(kysely, fieldModel, value, false, fromRelationContext));
4214
+ (0, import_common_helpers10.invariant)(fieldDef.array, "relation must be an array for createMany");
4215
+ await this.createMany(kysely, fieldModel, value, false, fromRelationContext);
3604
4216
  break;
3605
4217
  }
3606
4218
  case "connect": {
3607
- tasks.push(this.connectRelation(kysely, fieldModel, value, fromRelationContext));
4219
+ await this.connectRelation(kysely, fieldModel, value, fromRelationContext);
3608
4220
  break;
3609
4221
  }
3610
4222
  case "connectOrCreate": {
3611
- tasks.push(this.connectOrCreateRelation(kysely, fieldModel, value, fromRelationContext));
4223
+ await this.connectOrCreateRelation(kysely, fieldModel, value, fromRelationContext);
3612
4224
  break;
3613
4225
  }
3614
4226
  case "disconnect": {
3615
- tasks.push(this.disconnectRelation(kysely, fieldModel, value, fromRelationContext));
4227
+ await this.disconnectRelation(kysely, fieldModel, value, fromRelationContext);
3616
4228
  break;
3617
4229
  }
3618
4230
  case "set": {
3619
- (0, import_common_helpers8.invariant)(fieldDef.array, "relation must be an array");
3620
- tasks.push(this.setRelation(kysely, fieldModel, value, fromRelationContext));
4231
+ (0, import_common_helpers10.invariant)(fieldDef.array, "relation must be an array");
4232
+ await this.setRelation(kysely, fieldModel, value, fromRelationContext);
3621
4233
  break;
3622
4234
  }
3623
4235
  case "update": {
3624
- tasks.push(...enumerate(value).map((item) => {
4236
+ for (const _item of enumerate(value)) {
4237
+ const item = _item;
3625
4238
  let where;
3626
4239
  let data;
3627
- if ("where" in item) {
4240
+ if ("data" in item && typeof item.data === "object") {
3628
4241
  where = item.where;
3629
4242
  data = item.data;
3630
4243
  } else {
3631
4244
  where = void 0;
3632
4245
  data = item;
3633
4246
  }
3634
- return this.update(kysely, fieldModel, where, data, fromRelationContext, true, throwIfNotFound);
3635
- }));
4247
+ await this.update(kysely, fieldModel, where, data, fromRelationContext, true, throwIfNotFound);
4248
+ }
3636
4249
  break;
3637
4250
  }
3638
4251
  case "upsert": {
3639
- tasks.push(...enumerate(value).map(async (item) => {
4252
+ for (const _item of enumerate(value)) {
4253
+ const item = _item;
3640
4254
  const updated = await this.update(kysely, fieldModel, item.where, item.update, fromRelationContext, true, false);
3641
- if (updated) {
3642
- return updated;
3643
- } else {
3644
- return this.create(kysely, fieldModel, item.create, fromRelationContext);
4255
+ if (!updated) {
4256
+ await this.create(kysely, fieldModel, item.create, fromRelationContext);
3645
4257
  }
3646
- }));
4258
+ }
3647
4259
  break;
3648
4260
  }
3649
4261
  case "updateMany": {
3650
- tasks.push(...enumerate(value).map((item) => this.update(kysely, fieldModel, item.where, item.data, fromRelationContext, false, false)));
4262
+ for (const _item of enumerate(value)) {
4263
+ const item = _item;
4264
+ await this.update(kysely, fieldModel, item.where, item.data, fromRelationContext, false, false);
4265
+ }
3651
4266
  break;
3652
4267
  }
3653
4268
  case "delete": {
3654
- tasks.push(this.deleteRelation(kysely, fieldModel, value, fromRelationContext, true));
4269
+ await this.deleteRelation(kysely, fieldModel, value, fromRelationContext, true);
3655
4270
  break;
3656
4271
  }
3657
4272
  case "deleteMany": {
3658
- tasks.push(this.deleteRelation(kysely, fieldModel, value, fromRelationContext, false));
4273
+ await this.deleteRelation(kysely, fieldModel, value, fromRelationContext, false);
3659
4274
  break;
3660
4275
  }
3661
4276
  default: {
@@ -3663,7 +4278,7 @@ var BaseOperationHandler = class {
3663
4278
  }
3664
4279
  }
3665
4280
  }
3666
- await Promise.all(tasks);
4281
+ return fromRelationContext.parentUpdates;
3667
4282
  }
3668
4283
  // #region relation manipulation
3669
4284
  async connectRelation(kysely, model, data, fromRelation) {
@@ -3673,37 +4288,35 @@ var BaseOperationHandler = class {
3673
4288
  }
3674
4289
  const m2m = getManyToManyRelation(this.schema, fromRelation.model, fromRelation.field);
3675
4290
  if (m2m) {
3676
- const actions = _data.map(async (d) => {
4291
+ const results = [];
4292
+ for (const d of _data) {
3677
4293
  const ids = await this.getEntityIds(kysely, model, d);
3678
- return this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable);
3679
- });
3680
- const results = await Promise.all(actions);
4294
+ if (!ids) {
4295
+ throw new NotFoundError(model);
4296
+ }
4297
+ const r = await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable);
4298
+ results.push(r);
4299
+ }
3681
4300
  if (_data.length > results.filter((r) => !!r).length) {
3682
4301
  throw new NotFoundError(model);
3683
4302
  }
3684
4303
  } else {
3685
4304
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
3686
- let updateResult;
3687
4305
  if (ownedByModel) {
3688
- (0, import_common_helpers8.invariant)(_data.length === 1, "only one entity can be connected");
4306
+ (0, import_common_helpers10.invariant)(_data.length === 1, "only one entity can be connected");
3689
4307
  const target = await this.readUnique(kysely, model, {
3690
4308
  where: _data[0]
3691
4309
  });
3692
4310
  if (!target) {
3693
4311
  throw new NotFoundError(model);
3694
4312
  }
3695
- const query = kysely.updateTable(fromRelation.model).where((eb) => eb.and(fromRelation.ids)).set(keyPairs.reduce((acc, { fk, pk }) => ({
3696
- ...acc,
3697
- [fk]: target[pk]
3698
- }), {})).modifyEnd(this.makeContextComment({
3699
- model: fromRelation.model,
3700
- operation: "update"
3701
- }));
3702
- updateResult = await this.executeQuery(kysely, query, "connect");
4313
+ for (const { fk, pk } of keyPairs) {
4314
+ fromRelation.parentUpdates[fk] = target[pk];
4315
+ }
3703
4316
  } else {
3704
4317
  const relationFieldDef = this.requireField(fromRelation.model, fromRelation.field);
3705
4318
  if (!relationFieldDef.array) {
3706
- const query2 = kysely.updateTable(model).where((eb) => eb.and(keyPairs.map(({ fk, pk }) => eb(import_kysely8.sql.ref(fk), "=", fromRelation.ids[pk])))).set(keyPairs.reduce((acc, { fk }) => ({
4319
+ const query2 = kysely.updateTable(model).where((eb) => eb.and(keyPairs.map(({ fk, pk }) => eb(import_kysely10.sql.ref(fk), "=", fromRelation.ids[pk])))).set(keyPairs.reduce((acc, { fk }) => ({
3707
4320
  ...acc,
3708
4321
  [fk]: null
3709
4322
  }), {})).modifyEnd(this.makeContextComment({
@@ -3719,10 +4332,10 @@ var BaseOperationHandler = class {
3719
4332
  model,
3720
4333
  operation: "update"
3721
4334
  }));
3722
- updateResult = await this.executeQuery(kysely, query, "connect");
3723
- }
3724
- if (_data.length > updateResult.numAffectedRows) {
3725
- throw new NotFoundError(model);
4335
+ const updateResult = await this.executeQuery(kysely, query, "connect");
4336
+ if (!updateResult.numAffectedRows || _data.length > updateResult.numAffectedRows) {
4337
+ throw new NotFoundError(model);
4338
+ }
3726
4339
  }
3727
4340
  }
3728
4341
  }
@@ -3731,16 +4344,16 @@ var BaseOperationHandler = class {
3731
4344
  if (_data.length === 0) {
3732
4345
  return;
3733
4346
  }
3734
- return Promise.all(_data.map(async ({ where, create }) => {
4347
+ for (const { where, create } of _data) {
3735
4348
  const existing = await this.exists(kysely, model, where);
3736
4349
  if (existing) {
3737
- return this.connectRelation(kysely, model, [
4350
+ await this.connectRelation(kysely, model, [
3738
4351
  where
3739
4352
  ], fromRelation);
3740
4353
  } else {
3741
- return this.create(kysely, model, create, fromRelation);
4354
+ await this.create(kysely, model, create, fromRelation);
3742
4355
  }
3743
- }));
4356
+ }
3744
4357
  }
3745
4358
  async disconnectRelation(kysely, model, data, fromRelation) {
3746
4359
  let disconnectConditions = [];
@@ -3763,33 +4376,51 @@ var BaseOperationHandler = class {
3763
4376
  }
3764
4377
  const m2m = getManyToManyRelation(this.schema, fromRelation.model, fromRelation.field);
3765
4378
  if (m2m) {
3766
- const actions = disconnectConditions.map(async (d) => {
4379
+ for (const d of disconnectConditions) {
3767
4380
  const ids = await this.getEntityIds(kysely, model, d);
3768
4381
  if (!ids) {
3769
4382
  return;
3770
4383
  }
3771
- return this.handleManyToManyRelation(kysely, "disconnect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable);
3772
- });
3773
- await Promise.all(actions);
4384
+ await this.handleManyToManyRelation(kysely, "disconnect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable);
4385
+ }
3774
4386
  } else {
3775
4387
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
3776
- const eb = (0, import_kysely8.expressionBuilder)();
4388
+ const eb = (0, import_kysely10.expressionBuilder)();
3777
4389
  if (ownedByModel) {
3778
- (0, import_common_helpers8.invariant)(disconnectConditions.length === 1, "only one entity can be disconnected");
4390
+ (0, import_common_helpers10.invariant)(disconnectConditions.length === 1, "only one entity can be disconnected");
3779
4391
  const condition = disconnectConditions[0];
3780
- const query = kysely.updateTable(fromRelation.model).where(eb.and(fromRelation.ids)).$if(condition !== true, (qb) => qb.where(eb(
3781
- // @ts-ignore
3782
- eb.refTuple(...keyPairs.map(({ fk }) => fk)),
3783
- "in",
3784
- eb.selectFrom(model).select(keyPairs.map(({ pk }) => pk)).where(this.dialect.buildFilter(eb, model, model, condition))
3785
- ))).set(keyPairs.reduce((acc, { fk }) => ({
3786
- ...acc,
3787
- [fk]: null
3788
- }), {})).modifyEnd(this.makeContextComment({
3789
- model: fromRelation.model,
3790
- operation: "update"
3791
- }));
3792
- await this.executeQuery(kysely, query, "disconnect");
4392
+ if (condition === true) {
4393
+ for (const { fk } of keyPairs) {
4394
+ fromRelation.parentUpdates[fk] = null;
4395
+ }
4396
+ } else {
4397
+ const fromEntity = await this.readUnique(kysely, fromRelation.model, {
4398
+ where: fromRelation.ids,
4399
+ select: fieldsToSelectObject(keyPairs.map(({ fk }) => fk))
4400
+ });
4401
+ if (!fromEntity || keyPairs.some(({ fk }) => fromEntity[fk] == null)) {
4402
+ return;
4403
+ }
4404
+ const relationFilter = {
4405
+ AND: [
4406
+ condition,
4407
+ Object.fromEntries(keyPairs.map(({ fk, pk }) => [
4408
+ pk,
4409
+ fromEntity[fk]
4410
+ ]))
4411
+ ]
4412
+ };
4413
+ const targetExists = await this.read(kysely, model, {
4414
+ where: relationFilter,
4415
+ take: 1,
4416
+ select: this.makeIdSelect(model)
4417
+ });
4418
+ if (targetExists.length > 0) {
4419
+ for (const { fk } of keyPairs) {
4420
+ fromRelation.parentUpdates[fk] = null;
4421
+ }
4422
+ }
4423
+ }
3793
4424
  } else {
3794
4425
  const query = kysely.updateTable(model).where(eb.and([
3795
4426
  // fk filter
@@ -3815,11 +4446,14 @@ var BaseOperationHandler = class {
3815
4446
  const m2m = getManyToManyRelation(this.schema, fromRelation.model, fromRelation.field);
3816
4447
  if (m2m) {
3817
4448
  await this.resetManyToManyRelation(kysely, fromRelation.model, fromRelation.field, fromRelation.ids);
3818
- const actions = _data.map(async (d) => {
4449
+ const results = [];
4450
+ for (const d of _data) {
3819
4451
  const ids = await this.getEntityIds(kysely, model, d);
3820
- return this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable);
3821
- });
3822
- const results = await Promise.all(actions);
4452
+ if (!ids) {
4453
+ throw new NotFoundError(model);
4454
+ }
4455
+ results.push(await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable));
4456
+ }
3823
4457
  if (_data.length > results.filter((r) => !!r).length) {
3824
4458
  throw new NotFoundError(model);
3825
4459
  }
@@ -3854,7 +4488,7 @@ var BaseOperationHandler = class {
3854
4488
  operation: "update"
3855
4489
  }));
3856
4490
  const r = await this.executeQuery(kysely, query2, "connect");
3857
- if (_data.length > r.numAffectedRows) {
4491
+ if (!r.numAffectedRows || _data.length > r.numAffectedRows) {
3858
4492
  throw new NotFoundError(model);
3859
4493
  }
3860
4494
  }
@@ -3880,10 +4514,12 @@ var BaseOperationHandler = class {
3880
4514
  expectedDeleteCount = deleteConditions.length;
3881
4515
  }
3882
4516
  let deleteResult;
4517
+ let deleteFromModel;
3883
4518
  const m2m = getManyToManyRelation(this.schema, fromRelation.model, fromRelation.field);
3884
4519
  if (m2m) {
4520
+ deleteFromModel = model;
3885
4521
  const fieldDef = this.requireField(fromRelation.model, fromRelation.field);
3886
- (0, import_common_helpers8.invariant)(fieldDef.relation?.opposite);
4522
+ (0, import_common_helpers10.invariant)(fieldDef.relation?.opposite);
3887
4523
  deleteResult = await this.delete(kysely, model, {
3888
4524
  AND: [
3889
4525
  {
@@ -3899,14 +4535,15 @@ var BaseOperationHandler = class {
3899
4535
  } else {
3900
4536
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
3901
4537
  if (ownedByModel) {
4538
+ deleteFromModel = fromRelation.model;
3902
4539
  const fromEntity = await this.readUnique(kysely, fromRelation.model, {
3903
4540
  where: fromRelation.ids
3904
4541
  });
3905
4542
  if (!fromEntity) {
3906
- throw new NotFoundError(model);
4543
+ throw new NotFoundError(fromRelation.model);
3907
4544
  }
3908
4545
  const fieldDef = this.requireField(fromRelation.model, fromRelation.field);
3909
- (0, import_common_helpers8.invariant)(fieldDef.relation?.opposite);
4546
+ (0, import_common_helpers10.invariant)(fieldDef.relation?.opposite);
3910
4547
  deleteResult = await this.delete(kysely, model, {
3911
4548
  AND: [
3912
4549
  // filter for parent
@@ -3920,6 +4557,7 @@ var BaseOperationHandler = class {
3920
4557
  ]
3921
4558
  });
3922
4559
  } else {
4560
+ deleteFromModel = model;
3923
4561
  deleteResult = await this.delete(kysely, model, {
3924
4562
  AND: [
3925
4563
  Object.fromEntries(keyPairs.map(({ fk, pk }) => [
@@ -3934,7 +4572,7 @@ var BaseOperationHandler = class {
3934
4572
  }
3935
4573
  }
3936
4574
  if (throwForNotFound && expectedDeleteCount > deleteResult.count) {
3937
- throw new NotFoundError(model);
4575
+ throw new NotFoundError(deleteFromModel);
3938
4576
  }
3939
4577
  }
3940
4578
  normalizeRelationManipulationInput(model, data) {
@@ -4035,7 +4673,7 @@ var BaseOperationHandler = class {
4035
4673
  // reused the filter if it's a complete id filter (without extra fields)
4036
4674
  // otherwise, read the entity by the filter
4037
4675
  getEntityIds(kysely, model, uniqueFilter) {
4038
- const idFields = getIdFields(this.schema, model);
4676
+ const idFields = requireIdFields(this.schema, model);
4039
4677
  if (
4040
4678
  // all id fields are provided
4041
4679
  idFields.every((f) => f in uniqueFilter && uniqueFilter[f] !== void 0) && // no non-id filter exists
@@ -4063,7 +4701,7 @@ var BaseOperationHandler = class {
4063
4701
  for (const [key, value] of Object.entries(args)) {
4064
4702
  if (value === void 0) {
4065
4703
  delete args[key];
4066
- } else if (value && (0, import_common_helpers8.isPlainObject)(value)) {
4704
+ } else if (value && (0, import_common_helpers10.isPlainObject)(value)) {
4067
4705
  this.doNormalizeArgs(value);
4068
4706
  }
4069
4707
  }
@@ -4137,7 +4775,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
4137
4775
  if (field === "_all") {
4138
4776
  query = query.select((eb) => eb.cast(eb.fn.countAll(), "integer").as(`_count._all`));
4139
4777
  } else {
4140
- query = query.select((eb) => eb.cast(eb.fn.count(import_kysely9.sql.ref(`$sub.${field}`)), "integer").as(`${key}.${field}`));
4778
+ query = query.select((eb) => eb.cast(eb.fn.count(import_kysely11.sql.ref(`$sub.${field}`)), "integer").as(`${key}.${field}`));
4141
4779
  }
4142
4780
  }
4143
4781
  });
@@ -4152,7 +4790,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
4152
4790
  if (val === true) {
4153
4791
  query = query.select((eb) => {
4154
4792
  const fn = (0, import_ts_pattern10.match)(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
4155
- return fn(import_kysely9.sql.ref(`$sub.${field}`)).as(`${key}.${field}`);
4793
+ return fn(import_kysely11.sql.ref(`$sub.${field}`)).as(`${key}.${field}`);
4156
4794
  });
4157
4795
  }
4158
4796
  });
@@ -4199,7 +4837,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
4199
4837
  };
4200
4838
 
4201
4839
  // src/client/crud/operations/count.ts
4202
- var import_kysely10 = require("kysely");
4840
+ var import_kysely12 = require("kysely");
4203
4841
  var CountOperationHandler = class extends BaseOperationHandler {
4204
4842
  static {
4205
4843
  __name(this, "CountOperationHandler");
@@ -4223,7 +4861,7 @@ var CountOperationHandler = class extends BaseOperationHandler {
4223
4861
  return subQuery.as(subQueryName);
4224
4862
  });
4225
4863
  if (parsedArgs?.select && typeof parsedArgs.select === "object") {
4226
- 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)));
4864
+ 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_kysely12.sql.ref(`${subQueryName}.${key}`)), "integer").as(key)));
4227
4865
  const result = await this.executeQuery(this.kysely, query, "count");
4228
4866
  return result.rows[0];
4229
4867
  } else {
@@ -4259,7 +4897,7 @@ var CreateOperationHandler = class extends BaseOperationHandler {
4259
4897
  });
4260
4898
  });
4261
4899
  if (!result && this.hasPolicyEnabled) {
4262
- throw new RejectedByPolicyError(this.model, `result is not allowed to be read back`);
4900
+ throw new RejectedByPolicyError(this.model, RejectedByPolicyReason.CANNOT_READ_BACK, `result is not allowed to be read back`);
4263
4901
  }
4264
4902
  return result;
4265
4903
  }
@@ -4305,15 +4943,15 @@ var DeleteOperationHandler = class extends BaseOperationHandler {
4305
4943
  omit: args.omit,
4306
4944
  where: args.where
4307
4945
  });
4308
- if (!existing) {
4309
- throw new NotFoundError(this.model);
4310
- }
4311
4946
  await this.safeTransaction(async (tx) => {
4312
4947
  const result = await this.delete(tx, this.model, args.where);
4313
4948
  if (result.count === 0) {
4314
4949
  throw new NotFoundError(this.model);
4315
4950
  }
4316
4951
  });
4952
+ if (!existing && this.hasPolicyEnabled) {
4953
+ throw new RejectedByPolicyError(this.model, RejectedByPolicyReason.CANNOT_READ_BACK, "result is not allowed to be read back");
4954
+ }
4317
4955
  return existing;
4318
4956
  }
4319
4957
  async runDeleteMany(args) {
@@ -4347,7 +4985,7 @@ var FindOperationHandler = class extends BaseOperationHandler {
4347
4985
  };
4348
4986
 
4349
4987
  // src/client/crud/operations/group-by.ts
4350
- var import_kysely11 = require("kysely");
4988
+ var import_kysely13 = require("kysely");
4351
4989
  var import_ts_pattern13 = require("ts-pattern");
4352
4990
  var GroupByOperationHandler = class extends BaseOperationHandler {
4353
4991
  static {
@@ -4369,7 +5007,7 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
4369
5007
  subQuery = this.dialect.buildOrderBy(subQuery, this.model, this.model, void 0, skip !== void 0 || take !== void 0, negateOrderBy);
4370
5008
  return subQuery.as("$sub");
4371
5009
  });
4372
- const fieldRef = /* @__PURE__ */ __name((field) => this.dialect.fieldRef(this.model, field, (0, import_kysely11.expressionBuilder)(), "$sub"), "fieldRef");
5010
+ const fieldRef = /* @__PURE__ */ __name((field) => this.dialect.fieldRef(this.model, field, (0, import_kysely13.expressionBuilder)(), "$sub"), "fieldRef");
4373
5011
  const bys = typeof parsedArgs.by === "string" ? [
4374
5012
  parsedArgs.by
4375
5013
  ] : parsedArgs.by;
@@ -4484,7 +5122,7 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4484
5122
  });
4485
5123
  if (!readBackResult) {
4486
5124
  if (this.hasPolicyEnabled) {
4487
- throw new RejectedByPolicyError(this.model, "result is not allowed to be read back");
5125
+ throw new RejectedByPolicyError(this.model, RejectedByPolicyReason.CANNOT_READ_BACK, "result is not allowed to be read back");
4488
5126
  } else {
4489
5127
  return null;
4490
5128
  }
@@ -4501,16 +5139,24 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4501
5139
  if (!args) {
4502
5140
  return [];
4503
5141
  }
4504
- return this.safeTransaction(async (tx) => {
4505
- const updateResult = await this.updateMany(tx, this.model, args.where, args.data, args.limit, true);
4506
- return this.read(tx, this.model, {
5142
+ const { readBackResult, updateResult } = await this.safeTransaction(async (tx) => {
5143
+ const updateResult2 = await this.updateMany(tx, this.model, args.where, args.data, args.limit, true);
5144
+ const readBackResult2 = await this.read(tx, this.model, {
4507
5145
  select: args.select,
4508
5146
  omit: args.omit,
4509
5147
  where: {
4510
- OR: updateResult.map((item) => getIdValues(this.schema, this.model, item))
5148
+ OR: updateResult2.map((item) => getIdValues(this.schema, this.model, item))
4511
5149
  }
4512
5150
  });
5151
+ return {
5152
+ readBackResult: readBackResult2,
5153
+ updateResult: updateResult2
5154
+ };
4513
5155
  });
5156
+ if (readBackResult.length < updateResult.length && this.hasPolicyEnabled) {
5157
+ throw new RejectedByPolicyError(this.model, RejectedByPolicyReason.CANNOT_READ_BACK, "result is not allowed to be read back");
5158
+ }
5159
+ return readBackResult;
4514
5160
  }
4515
5161
  async runUpsert(args) {
4516
5162
  const result = await this.safeTransaction(async (tx) => {
@@ -4526,18 +5172,32 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4526
5172
  });
4527
5173
  });
4528
5174
  if (!result && this.hasPolicyEnabled) {
4529
- throw new RejectedByPolicyError(this.model, "result is not allowed to be read back");
5175
+ throw new RejectedByPolicyError(this.model, RejectedByPolicyReason.CANNOT_READ_BACK, "result is not allowed to be read back");
4530
5176
  }
4531
5177
  return result;
4532
5178
  }
4533
5179
  };
4534
5180
 
4535
5181
  // src/client/crud/validator.ts
4536
- var import_common_helpers9 = require("@zenstackhq/common-helpers");
4537
- var import_decimal = __toESM(require("decimal.js"), 1);
5182
+ var import_common_helpers11 = require("@zenstackhq/common-helpers");
5183
+ var import_decimal3 = __toESM(require("decimal.js"), 1);
4538
5184
  var import_json_stable_stringify = __toESM(require("json-stable-stringify"), 1);
4539
5185
  var import_ts_pattern15 = require("ts-pattern");
4540
5186
  var import_zod = require("zod");
5187
+
5188
+ // src/utils/zod-utils.ts
5189
+ var import_v3 = require("zod-validation-error/v3");
5190
+ var import_v4 = require("zod-validation-error/v4");
5191
+ function formatError(error) {
5192
+ if ("_zod" in error) {
5193
+ return (0, import_v4.fromError)(error).toString();
5194
+ } else {
5195
+ return (0, import_v3.fromError)(error).toString();
5196
+ }
5197
+ }
5198
+ __name(formatError, "formatError");
5199
+
5200
+ // src/client/crud/validator.ts
4541
5201
  var InputValidator = class {
4542
5202
  static {
4543
5203
  __name(this, "InputValidator");
@@ -4599,7 +5259,7 @@ var InputValidator = class {
4599
5259
  }
4600
5260
  const { error } = schema.safeParse(args);
4601
5261
  if (error) {
4602
- throw new InputValidationError(`Invalid ${operation} args: ${error.message}`, error);
5262
+ throw new InputValidationError(`Invalid ${operation} args: ${formatError(error)}`, error);
4603
5263
  }
4604
5264
  return args;
4605
5265
  }
@@ -4643,7 +5303,7 @@ var InputValidator = class {
4643
5303
  import_zod.z.bigint()
4644
5304
  ])).with("Decimal", () => import_zod.z.union([
4645
5305
  import_zod.z.number(),
4646
- import_zod.z.instanceof(import_decimal.default),
5306
+ import_zod.z.instanceof(import_decimal3.default),
4647
5307
  import_zod.z.string()
4648
5308
  ])).with("DateTime", () => import_zod.z.union([
4649
5309
  import_zod.z.date(),
@@ -4658,7 +5318,7 @@ var InputValidator = class {
4658
5318
  return schema;
4659
5319
  }
4660
5320
  const typeDef = this.schema.typeDefs?.[type];
4661
- (0, import_common_helpers9.invariant)(typeDef, `Type definition "${type}" not found in schema`);
5321
+ (0, import_common_helpers11.invariant)(typeDef, `Type definition "${type}" not found in schema`);
4662
5322
  schema = import_zod.z.object(Object.fromEntries(Object.entries(typeDef.fields).map(([field, def]) => {
4663
5323
  let fieldSchema = this.makePrimitiveSchema(def.type);
4664
5324
  if (def.array) {
@@ -4676,10 +5336,7 @@ var InputValidator = class {
4676
5336
  return schema;
4677
5337
  }
4678
5338
  makeWhereSchema(model, unique, withoutRelationFields = false, withAggregations = false) {
4679
- const modelDef = getModel(this.schema, model);
4680
- if (!modelDef) {
4681
- throw new QueryError(`Model "${model}" not found in schema`);
4682
- }
5339
+ const modelDef = requireModel(this.schema, model);
4683
5340
  const fields = {};
4684
5341
  for (const field of Object.keys(modelDef.fields)) {
4685
5342
  const fieldDef = requireField(this.schema, model, field);
@@ -4729,7 +5386,7 @@ var InputValidator = class {
4729
5386
  for (const uniqueField of uniqueFields) {
4730
5387
  if ("defs" in uniqueField) {
4731
5388
  fields[uniqueField.name] = import_zod.z.object(Object.fromEntries(Object.entries(uniqueField.defs).map(([key, def]) => {
4732
- (0, import_common_helpers9.invariant)(!def.relation, "unique field cannot be a relation");
5389
+ (0, import_common_helpers11.invariant)(!def.relation, "unique field cannot be a relation");
4733
5390
  let fieldSchema;
4734
5391
  const enumDef = getEnum(this.schema, def.type);
4735
5392
  if (enumDef) {
@@ -4935,9 +5592,16 @@ var InputValidator = class {
4935
5592
  fields[field] = import_zod.z.boolean().optional();
4936
5593
  }
4937
5594
  }
5595
+ const _countSchema = this.makeCountSelectionSchema(modelDef);
5596
+ if (_countSchema) {
5597
+ fields["_count"] = _countSchema;
5598
+ }
5599
+ return import_zod.z.strictObject(fields);
5600
+ }
5601
+ makeCountSelectionSchema(modelDef) {
4938
5602
  const toManyRelations = Object.values(modelDef.fields).filter((def) => def.relation && def.array);
4939
5603
  if (toManyRelations.length > 0) {
4940
- fields["_count"] = import_zod.z.union([
5604
+ return import_zod.z.union([
4941
5605
  import_zod.z.literal(true),
4942
5606
  import_zod.z.strictObject({
4943
5607
  select: import_zod.z.strictObject(toManyRelations.reduce((acc, fieldDef) => ({
@@ -4951,8 +5615,9 @@ var InputValidator = class {
4951
5615
  }), {}))
4952
5616
  })
4953
5617
  ]).optional();
5618
+ } else {
5619
+ return void 0;
4954
5620
  }
4955
- return import_zod.z.strictObject(fields);
4956
5621
  }
4957
5622
  makeRelationSelectIncludeSchema(fieldDef) {
4958
5623
  let objSchema = import_zod.z.strictObject({
@@ -4999,6 +5664,10 @@ var InputValidator = class {
4999
5664
  fields[field] = this.makeRelationSelectIncludeSchema(fieldDef).optional();
5000
5665
  }
5001
5666
  }
5667
+ const _countSchema = this.makeCountSelectionSchema(modelDef);
5668
+ if (_countSchema) {
5669
+ fields["_count"] = _countSchema;
5670
+ }
5002
5671
  return import_zod.z.strictObject(fields);
5003
5672
  }
5004
5673
  makeOrderBySchema(model, withRelation, WithAggregation) {
@@ -5065,13 +5734,15 @@ var InputValidator = class {
5065
5734
  // #region Create
5066
5735
  makeCreateSchema(model) {
5067
5736
  const dataSchema = this.makeCreateDataSchema(model, false);
5068
- const schema = import_zod.z.strictObject({
5737
+ let schema = import_zod.z.strictObject({
5069
5738
  data: dataSchema,
5070
5739
  select: this.makeSelectSchema(model).optional(),
5071
5740
  include: this.makeIncludeSchema(model).optional(),
5072
5741
  omit: this.makeOmitSchema(model).optional()
5073
5742
  });
5074
- return this.refineForSelectIncludeMutuallyExclusive(schema);
5743
+ schema = this.refineForSelectIncludeMutuallyExclusive(schema);
5744
+ schema = this.refineForSelectOmitMutuallyExclusive(schema);
5745
+ return schema;
5075
5746
  }
5076
5747
  makeCreateManySchema(model) {
5077
5748
  return this.makeCreateManyDataSchema(model, []).optional();
@@ -5196,11 +5867,11 @@ var InputValidator = class {
5196
5867
  fields["delete"] = this.makeDeleteRelationDataSchema(fieldType, array, true).optional();
5197
5868
  }
5198
5869
  fields["update"] = array ? this.orArray(import_zod.z.strictObject({
5199
- where: this.makeWhereSchema(fieldType, true),
5870
+ where: this.makeWhereSchema(fieldType, true).optional(),
5200
5871
  data: this.makeUpdateDataSchema(fieldType, withoutFields)
5201
5872
  }), true).optional() : import_zod.z.union([
5202
5873
  import_zod.z.strictObject({
5203
- where: this.makeWhereSchema(fieldType, true),
5874
+ where: this.makeWhereSchema(fieldType, true).optional(),
5204
5875
  data: this.makeUpdateDataSchema(fieldType, withoutFields)
5205
5876
  }),
5206
5877
  this.makeUpdateDataSchema(fieldType, withoutFields)
@@ -5260,14 +5931,16 @@ var InputValidator = class {
5260
5931
  // #endregion
5261
5932
  // #region Update
5262
5933
  makeUpdateSchema(model) {
5263
- const schema = import_zod.z.strictObject({
5934
+ let schema = import_zod.z.strictObject({
5264
5935
  where: this.makeWhereSchema(model, true),
5265
5936
  data: this.makeUpdateDataSchema(model),
5266
5937
  select: this.makeSelectSchema(model).optional(),
5267
5938
  include: this.makeIncludeSchema(model).optional(),
5268
5939
  omit: this.makeOmitSchema(model).optional()
5269
5940
  });
5270
- return this.refineForSelectIncludeMutuallyExclusive(schema);
5941
+ schema = this.refineForSelectIncludeMutuallyExclusive(schema);
5942
+ schema = this.refineForSelectOmitMutuallyExclusive(schema);
5943
+ return schema;
5271
5944
  }
5272
5945
  makeUpdateManySchema(model) {
5273
5946
  return import_zod.z.strictObject({
@@ -5278,14 +5951,15 @@ var InputValidator = class {
5278
5951
  }
5279
5952
  makeUpdateManyAndReturnSchema(model) {
5280
5953
  const base = this.makeUpdateManySchema(model);
5281
- const result = base.extend({
5954
+ let schema = base.extend({
5282
5955
  select: this.makeSelectSchema(model).optional(),
5283
5956
  omit: this.makeOmitSchema(model).optional()
5284
5957
  });
5285
- return this.refineForSelectOmitMutuallyExclusive(result);
5958
+ schema = this.refineForSelectOmitMutuallyExclusive(schema);
5959
+ return schema;
5286
5960
  }
5287
5961
  makeUpsertSchema(model) {
5288
- const schema = import_zod.z.strictObject({
5962
+ let schema = import_zod.z.strictObject({
5289
5963
  where: this.makeWhereSchema(model, true),
5290
5964
  create: this.makeCreateDataSchema(model, false),
5291
5965
  update: this.makeUpdateDataSchema(model),
@@ -5293,7 +5967,9 @@ var InputValidator = class {
5293
5967
  include: this.makeIncludeSchema(model).optional(),
5294
5968
  omit: this.makeOmitSchema(model).optional()
5295
5969
  });
5296
- return this.refineForSelectIncludeMutuallyExclusive(schema);
5970
+ schema = this.refineForSelectIncludeMutuallyExclusive(schema);
5971
+ schema = this.refineForSelectOmitMutuallyExclusive(schema);
5972
+ return schema;
5297
5973
  }
5298
5974
  makeUpdateDataSchema(model, withoutFields = [], withoutRelationFields = false) {
5299
5975
  const uncheckedVariantFields = {};
@@ -5370,12 +6046,14 @@ var InputValidator = class {
5370
6046
  // #endregion
5371
6047
  // #region Delete
5372
6048
  makeDeleteSchema(model) {
5373
- const schema = import_zod.z.strictObject({
6049
+ let schema = import_zod.z.strictObject({
5374
6050
  where: this.makeWhereSchema(model, true),
5375
6051
  select: this.makeSelectSchema(model).optional(),
5376
6052
  include: this.makeIncludeSchema(model).optional()
5377
6053
  });
5378
- return this.refineForSelectIncludeMutuallyExclusive(schema);
6054
+ schema = this.refineForSelectIncludeMutuallyExclusive(schema);
6055
+ schema = this.refineForSelectOmitMutuallyExclusive(schema);
6056
+ return schema;
5379
6057
  }
5380
6058
  makeDeleteManySchema(model) {
5381
6059
  return import_zod.z.object({
@@ -5725,33 +6403,14 @@ function performanceNow() {
5725
6403
  __name(performanceNow, "performanceNow");
5726
6404
 
5727
6405
  // src/client/executor/zenstack-query-executor.ts
5728
- var import_common_helpers12 = require("@zenstackhq/common-helpers");
5729
- var import_kysely14 = require("kysely");
6406
+ var import_common_helpers13 = require("@zenstackhq/common-helpers");
6407
+ var import_kysely15 = require("kysely");
5730
6408
  var import_ts_pattern16 = require("ts-pattern");
5731
6409
 
5732
- // src/client/executor/kysely-utils.ts
5733
- var import_common_helpers10 = require("@zenstackhq/common-helpers");
5734
- var import_kysely12 = require("kysely");
5735
- function stripAlias(node) {
5736
- if (import_kysely12.AliasNode.is(node)) {
5737
- (0, import_common_helpers10.invariant)(import_kysely12.IdentifierNode.is(node.alias), "Expected identifier as alias");
5738
- return {
5739
- alias: node.alias.name,
5740
- node: node.node
5741
- };
5742
- } else {
5743
- return {
5744
- alias: void 0,
5745
- node
5746
- };
5747
- }
5748
- }
5749
- __name(stripAlias, "stripAlias");
5750
-
5751
6410
  // src/client/executor/name-mapper.ts
5752
- var import_common_helpers11 = require("@zenstackhq/common-helpers");
5753
- var import_kysely13 = require("kysely");
5754
- var QueryNameMapper = class extends import_kysely13.OperationNodeTransformer {
6411
+ var import_common_helpers12 = require("@zenstackhq/common-helpers");
6412
+ var import_kysely14 = require("kysely");
6413
+ var QueryNameMapper = class extends import_kysely14.OperationNodeTransformer {
5755
6414
  static {
5756
6415
  __name(this, "QueryNameMapper");
5757
6416
  }
@@ -5793,7 +6452,7 @@ var QueryNameMapper = class extends import_kysely13.OperationNodeTransformer {
5793
6452
  })) : void 0;
5794
6453
  return {
5795
6454
  ...super.transformSelectQuery(node),
5796
- from: import_kysely13.FromNode.create(processedFroms.map((f) => f.node)),
6455
+ from: import_kysely14.FromNode.create(processedFroms.map((f) => f.node)),
5797
6456
  joins,
5798
6457
  selections: this.processSelectQuerySelections(node)
5799
6458
  };
@@ -5819,7 +6478,7 @@ var QueryNameMapper = class extends import_kysely13.OperationNodeTransformer {
5819
6478
  };
5820
6479
  }
5821
6480
  transformReference(node) {
5822
- if (!import_kysely13.ColumnNode.is(node.column)) {
6481
+ if (!import_kysely14.ColumnNode.is(node.column)) {
5823
6482
  return super.transformReference(node);
5824
6483
  }
5825
6484
  const scope = this.resolveFieldFromScopes(node.column.column.name, node.table?.table.identifier.name);
@@ -5827,12 +6486,12 @@ var QueryNameMapper = class extends import_kysely13.OperationNodeTransformer {
5827
6486
  const mappedFieldName = this.mapFieldName(scope.model, node.column.column.name);
5828
6487
  let mappedTableName = node.table?.table.identifier.name;
5829
6488
  if (mappedTableName) {
5830
- if (scope.alias === mappedTableName) {
6489
+ if (scope.alias && import_kysely14.IdentifierNode.is(scope.alias) && scope.alias.name === mappedTableName) {
5831
6490
  } else if (scope.model === mappedTableName) {
5832
6491
  mappedTableName = this.mapTableName(scope.model);
5833
6492
  }
5834
6493
  }
5835
- return import_kysely13.ReferenceNode.create(import_kysely13.ColumnNode.create(mappedFieldName), mappedTableName ? import_kysely13.TableNode.create(mappedTableName) : void 0);
6494
+ return import_kysely14.ReferenceNode.create(import_kysely14.ColumnNode.create(mappedFieldName), mappedTableName ? import_kysely14.TableNode.create(mappedTableName) : void 0);
5836
6495
  } else {
5837
6496
  return super.transformReference(node);
5838
6497
  }
@@ -5843,14 +6502,14 @@ var QueryNameMapper = class extends import_kysely13.OperationNodeTransformer {
5843
6502
  return super.transformColumn(node);
5844
6503
  }
5845
6504
  const mappedName = this.mapFieldName(scope.model, node.column.name);
5846
- return import_kysely13.ColumnNode.create(mappedName);
6505
+ return import_kysely14.ColumnNode.create(mappedName);
5847
6506
  }
5848
6507
  transformUpdateQuery(node) {
5849
6508
  if (!node.table) {
5850
6509
  return super.transformUpdateQuery(node);
5851
6510
  }
5852
6511
  const { alias, node: innerTable } = stripAlias(node.table);
5853
- if (!innerTable || !import_kysely13.TableNode.is(innerTable)) {
6512
+ if (!innerTable || !import_kysely14.TableNode.is(innerTable)) {
5854
6513
  return super.transformUpdateQuery(node);
5855
6514
  }
5856
6515
  return this.withScope({
@@ -5868,14 +6527,14 @@ var QueryNameMapper = class extends import_kysely13.OperationNodeTransformer {
5868
6527
  const scopes = node.from.froms.map((node2) => {
5869
6528
  const { alias, node: innerNode } = stripAlias(node2);
5870
6529
  return {
5871
- model: this.extractModelName(innerNode),
6530
+ model: extractModelName(innerNode),
5872
6531
  alias,
5873
6532
  namesMapped: false
5874
6533
  };
5875
6534
  });
5876
6535
  const froms = node.from.froms.map((from) => {
5877
6536
  const { alias, node: innerNode } = stripAlias(from);
5878
- if (import_kysely13.TableNode.is(innerNode)) {
6537
+ if (import_kysely14.TableNode.is(innerNode)) {
5879
6538
  return this.wrapAlias(this.processTableRef(innerNode), alias);
5880
6539
  } else {
5881
6540
  return super.transformNode(from);
@@ -5884,7 +6543,7 @@ var QueryNameMapper = class extends import_kysely13.OperationNodeTransformer {
5884
6543
  return this.withScopes(scopes, () => {
5885
6544
  return {
5886
6545
  ...super.transformDeleteQuery(node),
5887
- from: import_kysely13.FromNode.create(froms)
6546
+ from: import_kysely14.FromNode.create(froms)
5888
6547
  };
5889
6548
  });
5890
6549
  }
@@ -5893,24 +6552,24 @@ var QueryNameMapper = class extends import_kysely13.OperationNodeTransformer {
5893
6552
  processSelectQuerySelections(node) {
5894
6553
  const selections = [];
5895
6554
  for (const selection of node.selections ?? []) {
5896
- if (import_kysely13.SelectAllNode.is(selection.selection)) {
6555
+ if (import_kysely14.SelectAllNode.is(selection.selection)) {
5897
6556
  const scope = this.scopes[this.scopes.length - 1];
5898
6557
  if (scope?.model && !scope.namesMapped) {
5899
6558
  selections.push(...this.createSelectAllFields(scope.model, scope.alias));
5900
6559
  } else {
5901
6560
  selections.push(super.transformSelection(selection));
5902
6561
  }
5903
- } else if (import_kysely13.ReferenceNode.is(selection.selection) || import_kysely13.ColumnNode.is(selection.selection)) {
6562
+ } else if (import_kysely14.ReferenceNode.is(selection.selection) || import_kysely14.ColumnNode.is(selection.selection)) {
5904
6563
  const transformed = this.transformNode(selection.selection);
5905
- if (import_kysely13.AliasNode.is(transformed)) {
5906
- selections.push(import_kysely13.SelectionNode.create(transformed));
6564
+ if (import_kysely14.AliasNode.is(transformed)) {
6565
+ selections.push(import_kysely14.SelectionNode.create(transformed));
5907
6566
  } else {
5908
- const origFieldName = this.extractFieldName(selection.selection);
5909
- const fieldName = this.extractFieldName(transformed);
6567
+ const origFieldName = extractFieldName(selection.selection);
6568
+ const fieldName = extractFieldName(transformed);
5910
6569
  if (fieldName !== origFieldName) {
5911
- selections.push(import_kysely13.SelectionNode.create(this.wrapAlias(transformed, origFieldName)));
6570
+ selections.push(import_kysely14.SelectionNode.create(this.wrapAlias(transformed, origFieldName ? import_kysely14.IdentifierNode.create(origFieldName) : void 0)));
5912
6571
  } else {
5913
- selections.push(import_kysely13.SelectionNode.create(transformed));
6572
+ selections.push(import_kysely14.SelectionNode.create(transformed));
5914
6573
  }
5915
6574
  }
5916
6575
  } else {
@@ -5924,7 +6583,7 @@ var QueryNameMapper = class extends import_kysely13.OperationNodeTransformer {
5924
6583
  const scope = this.scopes[i];
5925
6584
  if (qualifier) {
5926
6585
  if (scope.alias) {
5927
- if (scope.alias === qualifier) {
6586
+ if (scope.alias && import_kysely14.IdentifierNode.is(scope.alias) && scope.alias.name === qualifier) {
5928
6587
  return scope;
5929
6588
  } else {
5930
6589
  continue;
@@ -5970,16 +6629,16 @@ var QueryNameMapper = class extends import_kysely13.OperationNodeTransformer {
5970
6629
  }
5971
6630
  }
5972
6631
  wrapAlias(node, alias) {
5973
- return alias ? import_kysely13.AliasNode.create(node, import_kysely13.IdentifierNode.create(alias)) : node;
6632
+ return alias ? import_kysely14.AliasNode.create(node, alias) : node;
5974
6633
  }
5975
6634
  processTableRef(node) {
5976
6635
  if (!node) {
5977
6636
  return node;
5978
6637
  }
5979
- if (!import_kysely13.TableNode.is(node)) {
6638
+ if (!import_kysely14.TableNode.is(node)) {
5980
6639
  return super.transformNode(node);
5981
6640
  }
5982
- return import_kysely13.TableNode.create(this.mapTableName(node.table.identifier.name));
6641
+ return import_kysely14.TableNode.create(this.mapTableName(node.table.identifier.name));
5983
6642
  }
5984
6643
  getMappedName(def) {
5985
6644
  const mapAttr = def.attributes?.find((attr) => attr.name === "@@map" || attr.name === "@map");
@@ -6015,14 +6674,14 @@ var QueryNameMapper = class extends import_kysely13.OperationNodeTransformer {
6015
6674
  // convert a "from" node to a nested query if there are columns with name mapping
6016
6675
  processSelectTable(node) {
6017
6676
  const { alias, node: innerNode } = stripAlias(node);
6018
- if (innerNode && import_kysely13.TableNode.is(innerNode)) {
6677
+ if (innerNode && import_kysely14.TableNode.is(innerNode)) {
6019
6678
  const modelName = innerNode.table.identifier.name;
6020
6679
  const mappedName = this.mapTableName(modelName);
6021
- const finalAlias = alias ?? (mappedName !== modelName ? modelName : void 0);
6680
+ const finalAlias = alias ?? (mappedName !== modelName ? import_kysely14.IdentifierNode.create(modelName) : void 0);
6022
6681
  return {
6023
- node: this.wrapAlias(import_kysely13.TableNode.create(mappedName), finalAlias),
6682
+ node: this.wrapAlias(import_kysely14.TableNode.create(mappedName), finalAlias),
6024
6683
  scope: {
6025
- alias: alias ?? modelName,
6684
+ alias: alias ?? import_kysely14.IdentifierNode.create(modelName),
6026
6685
  model: modelName,
6027
6686
  namesMapped: !this.hasMappedColumns(modelName)
6028
6687
  }
@@ -6042,12 +6701,12 @@ var QueryNameMapper = class extends import_kysely13.OperationNodeTransformer {
6042
6701
  const modelDef = requireModel(this.schema, model);
6043
6702
  return this.getModelFields(modelDef).map((fieldDef) => {
6044
6703
  const columnName = this.mapFieldName(model, fieldDef.name);
6045
- const columnRef = import_kysely13.ReferenceNode.create(import_kysely13.ColumnNode.create(columnName), alias ? import_kysely13.TableNode.create(alias) : void 0);
6704
+ const columnRef = import_kysely14.ReferenceNode.create(import_kysely14.ColumnNode.create(columnName), alias && import_kysely14.IdentifierNode.is(alias) ? import_kysely14.TableNode.create(alias.name) : void 0);
6046
6705
  if (columnName !== fieldDef.name) {
6047
- const aliased = import_kysely13.AliasNode.create(columnRef, import_kysely13.IdentifierNode.create(fieldDef.name));
6048
- return import_kysely13.SelectionNode.create(aliased);
6706
+ const aliased = import_kysely14.AliasNode.create(columnRef, import_kysely14.IdentifierNode.create(fieldDef.name));
6707
+ return import_kysely14.SelectionNode.create(aliased);
6049
6708
  } else {
6050
- return import_kysely13.SelectionNode.create(columnRef);
6709
+ return import_kysely14.SelectionNode.create(columnRef);
6051
6710
  }
6052
6711
  });
6053
6712
  }
@@ -6057,57 +6716,44 @@ var QueryNameMapper = class extends import_kysely13.OperationNodeTransformer {
6057
6716
  processSelections(selections) {
6058
6717
  const result = [];
6059
6718
  selections.forEach((selection) => {
6060
- if (import_kysely13.SelectAllNode.is(selection.selection)) {
6719
+ if (import_kysely14.SelectAllNode.is(selection.selection)) {
6061
6720
  const processed = this.processSelectAll(selection.selection);
6062
6721
  if (Array.isArray(processed)) {
6063
- result.push(...processed.map((s) => import_kysely13.SelectionNode.create(s)));
6722
+ result.push(...processed.map((s) => import_kysely14.SelectionNode.create(s)));
6064
6723
  } else {
6065
- result.push(import_kysely13.SelectionNode.create(processed));
6724
+ result.push(import_kysely14.SelectionNode.create(processed));
6066
6725
  }
6067
6726
  } else {
6068
- result.push(import_kysely13.SelectionNode.create(this.processSelection(selection.selection)));
6727
+ result.push(import_kysely14.SelectionNode.create(this.processSelection(selection.selection)));
6069
6728
  }
6070
6729
  });
6071
6730
  return result;
6072
6731
  }
6073
6732
  processSelection(node) {
6074
6733
  let alias;
6075
- if (!import_kysely13.AliasNode.is(node)) {
6076
- alias = this.extractFieldName(node);
6734
+ if (!import_kysely14.AliasNode.is(node)) {
6735
+ alias = extractFieldName(node);
6077
6736
  }
6078
6737
  const result = super.transformNode(node);
6079
- return this.wrapAlias(result, alias);
6738
+ return this.wrapAlias(result, alias ? import_kysely14.IdentifierNode.create(alias) : void 0);
6080
6739
  }
6081
6740
  processSelectAll(node) {
6082
6741
  const scope = this.scopes[this.scopes.length - 1];
6083
- (0, import_common_helpers11.invariant)(scope);
6742
+ (0, import_common_helpers12.invariant)(scope);
6084
6743
  if (!scope.model || !this.hasMappedColumns(scope.model)) {
6085
6744
  return super.transformSelectAll(node);
6086
6745
  }
6087
6746
  const modelDef = requireModel(this.schema, scope.model);
6088
6747
  return this.getModelFields(modelDef).map((fieldDef) => {
6089
6748
  const columnName = this.mapFieldName(modelDef.name, fieldDef.name);
6090
- const columnRef = import_kysely13.ReferenceNode.create(import_kysely13.ColumnNode.create(columnName));
6091
- return columnName !== fieldDef.name ? this.wrapAlias(columnRef, fieldDef.name) : columnRef;
6749
+ const columnRef = import_kysely14.ReferenceNode.create(import_kysely14.ColumnNode.create(columnName));
6750
+ return columnName !== fieldDef.name ? this.wrapAlias(columnRef, import_kysely14.IdentifierNode.create(fieldDef.name)) : columnRef;
6092
6751
  });
6093
6752
  }
6094
- extractModelName(node) {
6095
- const { node: innerNode } = stripAlias(node);
6096
- return import_kysely13.TableNode.is(innerNode) ? innerNode.table.identifier.name : void 0;
6097
- }
6098
- extractFieldName(node) {
6099
- if (import_kysely13.ReferenceNode.is(node) && import_kysely13.ColumnNode.is(node.column)) {
6100
- return node.column.column.name;
6101
- } else if (import_kysely13.ColumnNode.is(node)) {
6102
- return node.column.name;
6103
- } else {
6104
- return void 0;
6105
- }
6106
- }
6107
6753
  };
6108
6754
 
6109
6755
  // src/client/executor/zenstack-query-executor.ts
6110
- var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely14.DefaultQueryExecutor {
6756
+ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely15.DefaultQueryExecutor {
6111
6757
  static {
6112
6758
  __name(this, "ZenStackQueryExecutor");
6113
6759
  }
@@ -6150,7 +6796,6 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely14
6150
6796
  const hookResult = await hook({
6151
6797
  client: this.client,
6152
6798
  schema: this.client.$schema,
6153
- kysely: this.kysely,
6154
6799
  query,
6155
6800
  proceed: _p
6156
6801
  });
@@ -6164,13 +6809,13 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely14
6164
6809
  }
6165
6810
  getMutationInfo(queryNode) {
6166
6811
  const model = this.getMutationModel(queryNode);
6167
- const { action, where } = (0, import_ts_pattern16.match)(queryNode).when(import_kysely14.InsertQueryNode.is, () => ({
6812
+ const { action, where } = (0, import_ts_pattern16.match)(queryNode).when(import_kysely15.InsertQueryNode.is, () => ({
6168
6813
  action: "create",
6169
6814
  where: void 0
6170
- })).when(import_kysely14.UpdateQueryNode.is, (node) => ({
6815
+ })).when(import_kysely15.UpdateQueryNode.is, (node) => ({
6171
6816
  action: "update",
6172
6817
  where: node.where
6173
- })).when(import_kysely14.DeleteQueryNode.is, (node) => ({
6818
+ })).when(import_kysely15.DeleteQueryNode.is, (node) => ({
6174
6819
  action: "delete",
6175
6820
  where: node.where
6176
6821
  })).exhaustive();
@@ -6198,11 +6843,11 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely14
6198
6843
  result
6199
6844
  };
6200
6845
  }
6201
- if ((import_kysely14.InsertQueryNode.is(query) || import_kysely14.UpdateQueryNode.is(query)) && this.hasEntityMutationPluginsWithAfterMutationHooks) {
6846
+ if ((import_kysely15.InsertQueryNode.is(query) || import_kysely15.UpdateQueryNode.is(query)) && this.hasEntityMutationPluginsWithAfterMutationHooks) {
6202
6847
  query = {
6203
6848
  ...query,
6204
- returning: import_kysely14.ReturningNode.create([
6205
- import_kysely14.SelectionNode.createSelectAll()
6849
+ returning: import_kysely15.ReturningNode.create([
6850
+ import_kysely15.SelectionNode.createSelectAll()
6206
6851
  ])
6207
6852
  };
6208
6853
  }
@@ -6219,7 +6864,7 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely14
6219
6864
  const mutationInfo = this.getMutationInfo(finalQuery);
6220
6865
  let beforeMutationEntities;
6221
6866
  const loadBeforeMutationEntities = /* @__PURE__ */ __name(async () => {
6222
- if (beforeMutationEntities === void 0 && (import_kysely14.UpdateQueryNode.is(query) || import_kysely14.DeleteQueryNode.is(query))) {
6867
+ if (beforeMutationEntities === void 0 && (import_kysely15.UpdateQueryNode.is(query) || import_kysely15.DeleteQueryNode.is(query))) {
6223
6868
  beforeMutationEntities = await this.loadEntities(mutationInfo.model, mutationInfo.where, connection);
6224
6869
  }
6225
6870
  return beforeMutationEntities;
@@ -6261,7 +6906,7 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely14
6261
6906
  }
6262
6907
  }
6263
6908
  createClientForConnection(connection, inTx) {
6264
- const innerExecutor = this.withConnectionProvider(new import_kysely14.SingleConnectionProvider(connection));
6909
+ const innerExecutor = this.withConnectionProvider(new import_kysely15.SingleConnectionProvider(connection));
6265
6910
  innerExecutor.suppressMutationHooks = true;
6266
6911
  const innerClient = this.client.withExecutor(innerExecutor);
6267
6912
  if (inTx) {
@@ -6279,7 +6924,7 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely14
6279
6924
  return (this.client.$options.plugins ?? []).some((plugin) => plugin.onEntityMutation?.runAfterMutationWithinTransaction);
6280
6925
  }
6281
6926
  isMutationNode(queryNode) {
6282
- return import_kysely14.InsertQueryNode.is(queryNode) || import_kysely14.UpdateQueryNode.is(queryNode) || import_kysely14.DeleteQueryNode.is(queryNode);
6927
+ return import_kysely15.InsertQueryNode.is(queryNode) || import_kysely15.UpdateQueryNode.is(queryNode) || import_kysely15.DeleteQueryNode.is(queryNode);
6283
6928
  }
6284
6929
  withPlugin(plugin) {
6285
6930
  return new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, this.connectionProvider, [
@@ -6308,18 +6953,18 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely14
6308
6953
  return newExecutor;
6309
6954
  }
6310
6955
  getMutationModel(queryNode) {
6311
- return (0, import_ts_pattern16.match)(queryNode).when(import_kysely14.InsertQueryNode.is, (node) => {
6312
- (0, import_common_helpers12.invariant)(node.into, "InsertQueryNode must have an into clause");
6956
+ return (0, import_ts_pattern16.match)(queryNode).when(import_kysely15.InsertQueryNode.is, (node) => {
6957
+ (0, import_common_helpers13.invariant)(node.into, "InsertQueryNode must have an into clause");
6313
6958
  return node.into.table.identifier.name;
6314
- }).when(import_kysely14.UpdateQueryNode.is, (node) => {
6315
- (0, import_common_helpers12.invariant)(node.table, "UpdateQueryNode must have a table");
6959
+ }).when(import_kysely15.UpdateQueryNode.is, (node) => {
6960
+ (0, import_common_helpers13.invariant)(node.table, "UpdateQueryNode must have a table");
6316
6961
  const { node: tableNode } = stripAlias(node.table);
6317
- (0, import_common_helpers12.invariant)(import_kysely14.TableNode.is(tableNode), "UpdateQueryNode must use a TableNode");
6962
+ (0, import_common_helpers13.invariant)(import_kysely15.TableNode.is(tableNode), "UpdateQueryNode must use a TableNode");
6318
6963
  return tableNode.table.identifier.name;
6319
- }).when(import_kysely14.DeleteQueryNode.is, (node) => {
6320
- (0, import_common_helpers12.invariant)(node.from.froms.length === 1, "Delete query must have exactly one from table");
6964
+ }).when(import_kysely15.DeleteQueryNode.is, (node) => {
6965
+ (0, import_common_helpers13.invariant)(node.from.froms.length === 1, "Delete query must have exactly one from table");
6321
6966
  const { node: tableNode } = stripAlias(node.from.froms[0]);
6322
- (0, import_common_helpers12.invariant)(import_kysely14.TableNode.is(tableNode), "DeleteQueryNode must use a TableNode");
6967
+ (0, import_common_helpers13.invariant)(import_kysely15.TableNode.is(tableNode), "DeleteQueryNode must use a TableNode");
6323
6968
  return tableNode.table.identifier.name;
6324
6969
  }).otherwise((node) => {
6325
6970
  throw new InternalError(`Invalid query node: ${node}`);
@@ -6393,9 +7038,9 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely14
6393
7038
  }
6394
7039
  andNodes(condition1, condition2) {
6395
7040
  if (condition1 && condition2) {
6396
- return import_kysely14.WhereNode.create(import_kysely14.AndNode.create(condition1, condition2));
7041
+ return import_kysely15.WhereNode.create(import_kysely15.AndNode.create(condition1, condition2));
6397
7042
  } else if (condition1) {
6398
- return import_kysely14.WhereNode.create(condition1);
7043
+ return import_kysely15.WhereNode.create(condition1);
6399
7044
  } else {
6400
7045
  return condition2;
6401
7046
  }
@@ -6417,53 +7062,58 @@ __export(functions_exports, {
6417
7062
  search: () => search,
6418
7063
  startsWith: () => startsWith
6419
7064
  });
6420
- var import_common_helpers13 = require("@zenstackhq/common-helpers");
6421
- var import_kysely15 = require("kysely");
7065
+ var import_common_helpers14 = require("@zenstackhq/common-helpers");
7066
+ var import_kysely16 = require("kysely");
6422
7067
  var import_ts_pattern17 = require("ts-pattern");
6423
- var contains = /* @__PURE__ */ __name((eb, args) => {
6424
- const [field, search2, caseInsensitive = false] = args;
6425
- if (!field) {
6426
- throw new Error('"field" parameter is required');
6427
- }
6428
- if (!search2) {
6429
- throw new Error('"search" parameter is required');
6430
- }
6431
- const searchExpr = eb.fn("CONCAT", [
6432
- import_kysely15.sql.lit("%"),
6433
- search2,
6434
- import_kysely15.sql.lit("%")
6435
- ]);
6436
- return eb(field, caseInsensitive ? "ilike" : "like", searchExpr);
6437
- }, "contains");
7068
+ var contains = /* @__PURE__ */ __name((eb, args, context) => textMatch(eb, args, context, "contains"), "contains");
6438
7069
  var search = /* @__PURE__ */ __name((_eb, _args) => {
6439
7070
  throw new Error(`"search" function is not implemented yet`);
6440
7071
  }, "search");
6441
- var startsWith = /* @__PURE__ */ __name((eb, args) => {
6442
- const [field, search2] = args;
6443
- if (!field) {
6444
- throw new Error('"field" parameter is required');
6445
- }
6446
- if (!search2) {
6447
- throw new Error('"search" parameter is required');
6448
- }
6449
- return eb(field, "like", eb.fn("CONCAT", [
6450
- search2,
6451
- import_kysely15.sql.lit("%")
6452
- ]));
6453
- }, "startsWith");
6454
- var endsWith = /* @__PURE__ */ __name((eb, args) => {
6455
- const [field, search2] = args;
7072
+ var startsWith = /* @__PURE__ */ __name((eb, args, context) => textMatch(eb, args, context, "startsWith"), "startsWith");
7073
+ var endsWith = /* @__PURE__ */ __name((eb, args, context) => textMatch(eb, args, context, "endsWith"), "endsWith");
7074
+ var textMatch = /* @__PURE__ */ __name((eb, args, { dialect }, method) => {
7075
+ const [field, search2, caseInsensitive = void 0] = args;
6456
7076
  if (!field) {
6457
7077
  throw new Error('"field" parameter is required');
6458
7078
  }
6459
7079
  if (!search2) {
6460
7080
  throw new Error('"search" parameter is required');
6461
7081
  }
6462
- return eb(field, "like", eb.fn("CONCAT", [
6463
- import_kysely15.sql.lit("%"),
6464
- search2
6465
- ]));
6466
- }, "endsWith");
7082
+ const casingBehavior = dialect.getStringCasingBehavior();
7083
+ const caseInsensitiveValue = readBoolean(caseInsensitive, false);
7084
+ let op;
7085
+ let fieldExpr = field;
7086
+ let searchExpr = search2;
7087
+ if (caseInsensitiveValue) {
7088
+ if (casingBehavior.supportsILike) {
7089
+ op = "ilike";
7090
+ } else {
7091
+ op = "like";
7092
+ if (casingBehavior.likeCaseSensitive === true) {
7093
+ fieldExpr = eb.fn("LOWER", [
7094
+ fieldExpr
7095
+ ]);
7096
+ searchExpr = eb.fn("LOWER", [
7097
+ searchExpr
7098
+ ]);
7099
+ }
7100
+ }
7101
+ } else {
7102
+ op = "like";
7103
+ }
7104
+ searchExpr = (0, import_ts_pattern17.match)(method).with("contains", () => eb.fn("CONCAT", [
7105
+ import_kysely16.sql.lit("%"),
7106
+ import_kysely16.sql`CAST(${searchExpr} as text)`,
7107
+ import_kysely16.sql.lit("%")
7108
+ ])).with("startsWith", () => eb.fn("CONCAT", [
7109
+ import_kysely16.sql`CAST(${searchExpr} as text)`,
7110
+ import_kysely16.sql.lit("%")
7111
+ ])).with("endsWith", () => eb.fn("CONCAT", [
7112
+ import_kysely16.sql.lit("%"),
7113
+ import_kysely16.sql`CAST(${searchExpr} as text)`
7114
+ ])).exhaustive();
7115
+ return eb(fieldExpr, op, searchExpr);
7116
+ }, "textMatch");
6467
7117
  var has = /* @__PURE__ */ __name((eb, args) => {
6468
7118
  const [field, search2] = args;
6469
7119
  if (!field) {
@@ -6501,18 +7151,16 @@ var isEmpty = /* @__PURE__ */ __name((eb, args, { dialect }) => {
6501
7151
  if (!field) {
6502
7152
  throw new Error('"field" parameter is required');
6503
7153
  }
6504
- return eb(dialect.buildArrayLength(eb, field), "=", import_kysely15.sql.lit(0));
7154
+ return eb(dialect.buildArrayLength(eb, field), "=", import_kysely16.sql.lit(0));
6505
7155
  }, "isEmpty");
6506
- var now = /* @__PURE__ */ __name((eb, _args, { dialect }) => {
6507
- return (0, import_ts_pattern17.match)(dialect.provider).with("postgresql", () => eb.fn("now")).with("sqlite", () => import_kysely15.sql.raw("CURRENT_TIMESTAMP")).exhaustive();
6508
- }, "now");
7156
+ var now = /* @__PURE__ */ __name(() => import_kysely16.sql.raw("CURRENT_TIMESTAMP"), "now");
6509
7157
  var currentModel = /* @__PURE__ */ __name((_eb, args, { model }) => {
6510
7158
  let result = model;
6511
7159
  const [casing] = args;
6512
7160
  if (casing) {
6513
7161
  result = processCasing(casing, result, model);
6514
7162
  }
6515
- return import_kysely15.sql.lit(result);
7163
+ return import_kysely16.sql.lit(result);
6516
7164
  }, "currentModel");
6517
7165
  var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
6518
7166
  let result = operation;
@@ -6520,21 +7168,30 @@ var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
6520
7168
  if (casing) {
6521
7169
  result = processCasing(casing, result, operation);
6522
7170
  }
6523
- return import_kysely15.sql.lit(result);
7171
+ return import_kysely16.sql.lit(result);
6524
7172
  }, "currentOperation");
6525
7173
  function processCasing(casing, result, model) {
6526
7174
  const opNode = casing.toOperationNode();
6527
- (0, import_common_helpers13.invariant)(import_kysely15.ValueNode.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
6528
- result = (0, import_ts_pattern17.match)(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => (0, import_common_helpers13.upperCaseFirst)(result)).with("uncapitalize", () => (0, import_common_helpers13.lowerCaseFirst)(result)).otherwise(() => {
7175
+ (0, import_common_helpers14.invariant)(import_kysely16.ValueNode.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
7176
+ result = (0, import_ts_pattern17.match)(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => (0, import_common_helpers14.upperCaseFirst)(result)).with("uncapitalize", () => (0, import_common_helpers14.lowerCaseFirst)(result)).otherwise(() => {
6529
7177
  throw new Error(`Invalid casing value: ${opNode.value}. Must be "original", "upper", "lower", "capitalize", or "uncapitalize".`);
6530
7178
  });
6531
7179
  return result;
6532
7180
  }
6533
7181
  __name(processCasing, "processCasing");
7182
+ function readBoolean(expr2, defaultValue) {
7183
+ if (expr2 === void 0) {
7184
+ return defaultValue;
7185
+ }
7186
+ const opNode = expr2.toOperationNode();
7187
+ (0, import_common_helpers14.invariant)(import_kysely16.ValueNode.is(opNode), "expression must be a literal value");
7188
+ return !!opNode.value;
7189
+ }
7190
+ __name(readBoolean, "readBoolean");
6534
7191
 
6535
7192
  // src/client/helpers/schema-db-pusher.ts
6536
- var import_common_helpers14 = require("@zenstackhq/common-helpers");
6537
- var import_kysely16 = require("kysely");
7193
+ var import_common_helpers15 = require("@zenstackhq/common-helpers");
7194
+ var import_kysely17 = require("kysely");
6538
7195
  var import_toposort = __toESM(require("toposort"), 1);
6539
7196
  var import_ts_pattern18 = require("ts-pattern");
6540
7197
  var SchemaDbPusher = class {
@@ -6555,7 +7212,8 @@ var SchemaDbPusher = class {
6555
7212
  await createEnum.execute();
6556
7213
  }
6557
7214
  }
6558
- const sortedModels = this.sortModels(this.schema.models);
7215
+ const models = Object.values(this.schema.models).filter((m) => !m.isView);
7216
+ const sortedModels = this.sortModels(models);
6559
7217
  for (const modelDef of sortedModels) {
6560
7218
  const createTable = this.createModelTable(tx, modelDef);
6561
7219
  await createTable.execute();
@@ -6564,7 +7222,7 @@ var SchemaDbPusher = class {
6564
7222
  }
6565
7223
  sortModels(models) {
6566
7224
  const graph = [];
6567
- for (const model of Object.values(models)) {
7225
+ for (const model of models) {
6568
7226
  let added = false;
6569
7227
  if (model.baseModel) {
6570
7228
  const baseDef = requireModel(this.schema, model.baseModel);
@@ -6649,7 +7307,7 @@ var SchemaDbPusher = class {
6649
7307
  }
6650
7308
  addUniqueConstraint(table, modelDef) {
6651
7309
  for (const [key, value] of Object.entries(modelDef.uniqueFields)) {
6652
- (0, import_common_helpers14.invariant)(typeof value === "object", "expecting an object");
7310
+ (0, import_common_helpers15.invariant)(typeof value === "object", "expecting an object");
6653
7311
  if ("type" in value) {
6654
7312
  const fieldDef = modelDef.fields[key];
6655
7313
  if (fieldDef.unique) {
@@ -6672,7 +7330,7 @@ var SchemaDbPusher = class {
6672
7330
  if (fieldDef.default !== void 0) {
6673
7331
  if (typeof fieldDef.default === "object" && "kind" in fieldDef.default) {
6674
7332
  if (ExpressionUtils.isCall(fieldDef.default) && fieldDef.default.function === "now") {
6675
- col = col.defaultTo(import_kysely16.sql`CURRENT_TIMESTAMP`);
7333
+ col = col.defaultTo(import_kysely17.sql`CURRENT_TIMESTAMP`);
6676
7334
  }
6677
7335
  } else {
6678
7336
  col = col.defaultTo(fieldDef.default);
@@ -6692,7 +7350,7 @@ var SchemaDbPusher = class {
6692
7350
  }
6693
7351
  mapFieldType(fieldDef) {
6694
7352
  if (this.schema.enums?.[fieldDef.type]) {
6695
- return this.schema.provider.type === "postgresql" ? import_kysely16.sql.ref(fieldDef.type) : "text";
7353
+ return this.schema.provider.type === "postgresql" ? import_kysely17.sql.ref(fieldDef.type) : "text";
6696
7354
  }
6697
7355
  if (this.isAutoIncrement(fieldDef) && this.schema.provider.type === "postgresql") {
6698
7356
  return "serial";
@@ -6705,7 +7363,7 @@ var SchemaDbPusher = class {
6705
7363
  throw new Error(`Unsupported field type: ${type}`);
6706
7364
  });
6707
7365
  if (fieldDef.array) {
6708
- return import_kysely16.sql.raw(`${result}[]`);
7366
+ return import_kysely17.sql.raw(`${result}[]`);
6709
7367
  } else {
6710
7368
  return result;
6711
7369
  }
@@ -6717,7 +7375,7 @@ var SchemaDbPusher = class {
6717
7375
  return fieldDef.default && ExpressionUtils.isCall(fieldDef.default) && fieldDef.default.function === "autoincrement";
6718
7376
  }
6719
7377
  addForeignKeyConstraint(table, model, fieldName, fieldDef) {
6720
- (0, import_common_helpers14.invariant)(fieldDef.relation, "field must be a relation");
7378
+ (0, import_common_helpers15.invariant)(fieldDef.relation, "field must be a relation");
6721
7379
  if (!fieldDef.relation.fields || !fieldDef.relation.references) {
6722
7380
  return table;
6723
7381
  }
@@ -6774,16 +7432,15 @@ function valueToPromise(thing) {
6774
7432
  __name(valueToPromise, "valueToPromise");
6775
7433
 
6776
7434
  // src/client/result-processor.ts
6777
- var import_common_helpers15 = require("@zenstackhq/common-helpers");
6778
- var import_decimal2 = __toESM(require("decimal.js"), 1);
6779
- var import_ts_pattern19 = require("ts-pattern");
6780
7435
  var ResultProcessor = class {
6781
7436
  static {
6782
7437
  __name(this, "ResultProcessor");
6783
7438
  }
6784
7439
  schema;
6785
- constructor(schema) {
7440
+ dialect;
7441
+ constructor(schema, options) {
6786
7442
  this.schema = schema;
7443
+ this.dialect = getCrudDialect(schema, options);
6787
7444
  }
6788
7445
  processResult(data, model, args) {
6789
7446
  const result = this.doProcessResult(data, model);
@@ -6812,7 +7469,7 @@ var ResultProcessor = class {
6812
7469
  }
6813
7470
  if (key.startsWith(DELEGATE_JOINED_FIELD_PREFIX)) {
6814
7471
  if (value) {
6815
- const subRow = this.transformJson(value);
7472
+ const subRow = this.dialect.transformOutput(value, "Json");
6816
7473
  const subModel = key.slice(DELEGATE_JOINED_FIELD_PREFIX.length);
6817
7474
  const idValues = getIdValues(this.schema, subModel, subRow);
6818
7475
  if (Object.values(idValues).some((v) => v === null || v === void 0)) {
@@ -6846,10 +7503,10 @@ var ResultProcessor = class {
6846
7503
  processFieldValue(value, fieldDef) {
6847
7504
  const type = fieldDef.type;
6848
7505
  if (Array.isArray(value)) {
6849
- value.forEach((v, i) => value[i] = this.transformScalar(v, type));
7506
+ value.forEach((v, i) => value[i] = this.dialect.transformOutput(v, type));
6850
7507
  return value;
6851
7508
  } else {
6852
- return this.transformScalar(value, type);
7509
+ return this.dialect.transformOutput(value, type);
6853
7510
  }
6854
7511
  }
6855
7512
  processRelation(value, fieldDef) {
@@ -6863,42 +7520,6 @@ var ResultProcessor = class {
6863
7520
  }
6864
7521
  return this.doProcessResult(relationData, fieldDef.type);
6865
7522
  }
6866
- transformScalar(value, type) {
6867
- if (this.schema.typeDefs && type in this.schema.typeDefs) {
6868
- return this.transformJson(value);
6869
- } else {
6870
- return (0, import_ts_pattern19.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);
6871
- }
6872
- }
6873
- transformDecimal(value) {
6874
- if (value instanceof import_decimal2.default) {
6875
- return value;
6876
- }
6877
- (0, import_common_helpers15.invariant)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal2.default, `Expected string, number or Decimal, got ${typeof value}`);
6878
- return new import_decimal2.default(value);
6879
- }
6880
- transformBigInt(value) {
6881
- if (typeof value === "bigint") {
6882
- return value;
6883
- }
6884
- (0, import_common_helpers15.invariant)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
6885
- return BigInt(value);
6886
- }
6887
- transformBoolean(value) {
6888
- return !!value;
6889
- }
6890
- transformDate(value) {
6891
- if (typeof value === "number") {
6892
- return new Date(value);
6893
- } else if (typeof value === "string") {
6894
- return new Date(Date.parse(value));
6895
- } else {
6896
- return value;
6897
- }
6898
- }
6899
- transformBytes(value) {
6900
- return Buffer.isBuffer(value) ? Uint8Array.from(value) : value;
6901
- }
6902
7523
  fixReversedResult(data, model, args) {
6903
7524
  if (!data) {
6904
7525
  return;
@@ -6923,12 +7544,6 @@ var ResultProcessor = class {
6923
7544
  }
6924
7545
  }
6925
7546
  }
6926
- transformJson(value) {
6927
- return (0, import_ts_pattern19.match)(this.schema.provider.type).with("sqlite", () => {
6928
- (0, import_common_helpers15.invariant)(typeof value === "string", "Expected string, got " + typeof value);
6929
- return JSON.parse(value);
6930
- }).otherwise(() => value);
6931
- }
6932
7547
  };
6933
7548
 
6934
7549
  // src/client/client-impl.ts
@@ -6951,7 +7566,7 @@ var ClientImpl = class _ClientImpl {
6951
7566
  this.schema = schema;
6952
7567
  this.options = options;
6953
7568
  this.$schema = schema;
6954
- this.$options = options ?? {};
7569
+ this.$options = options;
6955
7570
  this.$options.functions = {
6956
7571
  ...functions_exports,
6957
7572
  ...this.$options.functions
@@ -6959,15 +7574,15 @@ var ClientImpl = class _ClientImpl {
6959
7574
  if (baseClient) {
6960
7575
  this.kyselyProps = {
6961
7576
  ...baseClient.kyselyProps,
6962
- executor: executor ?? new ZenStackQueryExecutor(this, baseClient.kyselyProps.driver, baseClient.kyselyProps.dialect.createQueryCompiler(), baseClient.kyselyProps.dialect.createAdapter(), new import_kysely17.DefaultConnectionProvider(baseClient.kyselyProps.driver))
7577
+ executor: executor ?? new ZenStackQueryExecutor(this, baseClient.kyselyProps.driver, baseClient.kyselyProps.dialect.createQueryCompiler(), baseClient.kyselyProps.dialect.createAdapter(), new import_kysely18.DefaultConnectionProvider(baseClient.kyselyProps.driver))
6963
7578
  };
6964
7579
  this.kyselyRaw = baseClient.kyselyRaw;
6965
7580
  this.auth = baseClient.auth;
6966
7581
  } else {
6967
- const driver = new ZenStackDriver(options.dialect.createDriver(), new import_kysely17.Log(this.$options.log ?? []));
7582
+ const driver = new ZenStackDriver(options.dialect.createDriver(), new import_kysely18.Log(this.$options.log ?? []));
6968
7583
  const compiler = options.dialect.createQueryCompiler();
6969
7584
  const adapter = options.dialect.createAdapter();
6970
- const connectionProvider = new import_kysely17.DefaultConnectionProvider(driver);
7585
+ const connectionProvider = new import_kysely18.DefaultConnectionProvider(driver);
6971
7586
  this.kyselyProps = {
6972
7587
  config: {
6973
7588
  dialect: options.dialect,
@@ -6977,12 +7592,12 @@ var ClientImpl = class _ClientImpl {
6977
7592
  driver,
6978
7593
  executor: executor ?? new ZenStackQueryExecutor(this, driver, compiler, adapter, connectionProvider)
6979
7594
  };
6980
- this.kyselyRaw = new import_kysely17.Kysely({
7595
+ this.kyselyRaw = new import_kysely18.Kysely({
6981
7596
  ...this.kyselyProps,
6982
- executor: new import_kysely17.DefaultQueryExecutor(compiler, adapter, connectionProvider, [])
7597
+ executor: new import_kysely18.DefaultQueryExecutor(compiler, adapter, connectionProvider, [])
6983
7598
  });
6984
7599
  }
6985
- this.kysely = new import_kysely17.Kysely(this.kyselyProps);
7600
+ this.kysely = new import_kysely18.Kysely(this.kyselyProps);
6986
7601
  return createClientProxy(this);
6987
7602
  }
6988
7603
  get $qb() {
@@ -7011,7 +7626,7 @@ var ClientImpl = class _ClientImpl {
7011
7626
  }
7012
7627
  forceTransaction() {
7013
7628
  if (!this.kysely.isTransaction) {
7014
- this.kysely = new import_kysely17.Transaction(this.kyselyProps);
7629
+ this.kysely = new import_kysely18.Transaction(this.kyselyProps);
7015
7630
  }
7016
7631
  }
7017
7632
  async interactiveTransaction(callback, options) {
@@ -7118,7 +7733,7 @@ var ClientImpl = class _ClientImpl {
7118
7733
  }
7119
7734
  $executeRaw(query, ...values) {
7120
7735
  return createZenStackPromise(async () => {
7121
- const result = await (0, import_kysely17.sql)(query, ...values).execute(this.kysely);
7736
+ const result = await (0, import_kysely18.sql)(query, ...values).execute(this.kysely);
7122
7737
  return Number(result.numAffectedRows ?? 0);
7123
7738
  });
7124
7739
  }
@@ -7131,7 +7746,7 @@ var ClientImpl = class _ClientImpl {
7131
7746
  }
7132
7747
  $queryRaw(query, ...values) {
7133
7748
  return createZenStackPromise(async () => {
7134
- const result = await (0, import_kysely17.sql)(query, ...values).execute(this.kysely);
7749
+ const result = await (0, import_kysely18.sql)(query, ...values).execute(this.kysely);
7135
7750
  return result.rows;
7136
7751
  });
7137
7752
  }
@@ -7143,7 +7758,7 @@ var ClientImpl = class _ClientImpl {
7143
7758
  });
7144
7759
  }
7145
7760
  createRawCompiledQuery(query, values) {
7146
- const q = import_kysely17.CompiledQuery.raw(query, values);
7761
+ const q = import_kysely18.CompiledQuery.raw(query, values);
7147
7762
  return {
7148
7763
  ...q,
7149
7764
  $raw: true
@@ -7152,7 +7767,7 @@ var ClientImpl = class _ClientImpl {
7152
7767
  };
7153
7768
  function createClientProxy(client) {
7154
7769
  const inputValidator = new InputValidator(client.$schema);
7155
- const resultProcessor = new ResultProcessor(client.$schema);
7770
+ const resultProcessor = new ResultProcessor(client.$schema, client.$options);
7156
7771
  return new Proxy(client, {
7157
7772
  get: /* @__PURE__ */ __name((target, prop, receiver) => {
7158
7773
  if (typeof prop === "string" && prop.startsWith("$")) {
@@ -7270,7 +7885,7 @@ function definePlugin(plugin) {
7270
7885
  __name(definePlugin, "definePlugin");
7271
7886
 
7272
7887
  // src/client/index.ts
7273
- var import_kysely18 = require("kysely");
7888
+ var import_kysely19 = require("kysely");
7274
7889
  // Annotate the CommonJS export names for ESM import in node:
7275
7890
  0 && (module.exports = {
7276
7891
  InputValidationError,