@zenstackhq/runtime 3.0.0-beta.7 → 3.0.0-beta.8

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.
@@ -37,48 +37,13 @@ __export(policy_exports, {
37
37
  });
38
38
  module.exports = __toCommonJS(policy_exports);
39
39
 
40
- // src/plugins/policy/errors.ts
41
- var RejectedByPolicyReason = /* @__PURE__ */ function(RejectedByPolicyReason2) {
42
- RejectedByPolicyReason2["NO_ACCESS"] = "no-access";
43
- RejectedByPolicyReason2["CANNOT_READ_BACK"] = "cannot-read-back";
44
- RejectedByPolicyReason2["OTHER"] = "other";
45
- return RejectedByPolicyReason2;
46
- }({});
47
- var RejectedByPolicyError = class extends Error {
48
- static {
49
- __name(this, "RejectedByPolicyError");
50
- }
51
- model;
52
- reason;
53
- constructor(model, reason = "no-access", message) {
54
- super(message ?? `Operation rejected by policy${model ? ": " + model : ""}`), this.model = model, this.reason = reason;
55
- }
56
- };
40
+ // src/client/client-impl.ts
41
+ var import_common_helpers12 = require("@zenstackhq/common-helpers");
42
+ var import_kysely13 = require("kysely");
57
43
 
58
- // src/plugins/policy/functions.ts
59
- var import_common_helpers8 = require("@zenstackhq/common-helpers");
60
- var import_kysely9 = require("kysely");
61
-
62
- // src/client/contract.ts
63
- var CRUD = [
64
- "create",
65
- "read",
66
- "update",
67
- "delete"
68
- ];
69
-
70
- // src/client/kysely-utils.ts
71
- var import_kysely = require("kysely");
72
- function extractFieldName(node) {
73
- if (import_kysely.ReferenceNode.is(node) && import_kysely.ColumnNode.is(node.column)) {
74
- return node.column.column.name;
75
- } else if (import_kysely.ColumnNode.is(node)) {
76
- return node.column.name;
77
- } else {
78
- return void 0;
79
- }
80
- }
81
- __name(extractFieldName, "extractFieldName");
44
+ // src/client/crud/operations/aggregate.ts
45
+ var import_kysely5 = require("kysely");
46
+ var import_ts_pattern7 = require("ts-pattern");
82
47
 
83
48
  // src/client/query-utils.ts
84
49
  var import_common_helpers = require("@zenstackhq/common-helpers");
@@ -170,7 +135,12 @@ var ExpressionUtils = {
170
135
  };
171
136
 
172
137
  // src/client/errors.ts
173
- var QueryError = class extends Error {
138
+ var ZenStackError = class extends Error {
139
+ static {
140
+ __name(this, "ZenStackError");
141
+ }
142
+ };
143
+ var QueryError = class extends ZenStackError {
174
144
  static {
175
145
  __name(this, "QueryError");
176
146
  }
@@ -180,7 +150,7 @@ var QueryError = class extends Error {
180
150
  });
181
151
  }
182
152
  };
183
- var InternalError = class extends Error {
153
+ var InternalError = class extends ZenStackError {
184
154
  static {
185
155
  __name(this, "InternalError");
186
156
  }
@@ -461,19 +431,31 @@ function aggregate(eb, expr2, op) {
461
431
  }
462
432
  __name(aggregate, "aggregate");
463
433
 
464
- // src/plugins/policy/policy-handler.ts
465
- var import_common_helpers7 = require("@zenstackhq/common-helpers");
466
- var import_kysely8 = require("kysely");
467
- var import_ts_pattern8 = require("ts-pattern");
434
+ // src/client/crud/operations/base.ts
435
+ var import_cuid2 = require("@paralleldrive/cuid2");
436
+ var import_common_helpers6 = require("@zenstackhq/common-helpers");
437
+ var import_kysely4 = require("kysely");
438
+ var import_nanoid = require("nanoid");
439
+ var import_ts_pattern6 = require("ts-pattern");
440
+ var import_ulid = require("ulid");
441
+ var uuid = __toESM(require("uuid"), 1);
468
442
 
469
- // src/client/crud/dialects/index.ts
470
- var import_ts_pattern5 = require("ts-pattern");
443
+ // src/utils/clone.ts
444
+ var import_common_helpers2 = require("@zenstackhq/common-helpers");
471
445
 
472
- // src/client/crud/dialects/postgresql.ts
473
- var import_common_helpers3 = require("@zenstackhq/common-helpers");
474
- var import_decimal = __toESM(require("decimal.js"), 1);
475
- var import_kysely3 = require("kysely");
476
- var import_ts_pattern3 = require("ts-pattern");
446
+ // src/utils/enumerate.ts
447
+ function enumerate(x) {
448
+ if (x === null || x === void 0) {
449
+ return [];
450
+ } else if (Array.isArray(x)) {
451
+ return x;
452
+ } else {
453
+ return [
454
+ x
455
+ ];
456
+ }
457
+ }
458
+ __name(enumerate, "enumerate");
477
459
 
478
460
  // src/client/constants.ts
479
461
  var DELEGATE_JOINED_FIELD_PREFIX = "$delegate$";
@@ -490,26 +472,31 @@ var AGGREGATE_OPERATORS = [
490
472
  "_max"
491
473
  ];
492
474
 
493
- // src/client/crud/dialects/base-dialect.ts
494
- var import_common_helpers2 = require("@zenstackhq/common-helpers");
495
- var import_kysely2 = require("kysely");
496
- var import_ts_pattern2 = require("ts-pattern");
475
+ // src/client/contract.ts
476
+ var CRUD = [
477
+ "create",
478
+ "read",
479
+ "update",
480
+ "delete"
481
+ ];
482
+ var CRUD_EXT = [
483
+ ...CRUD,
484
+ "post-update"
485
+ ];
497
486
 
498
- // src/utils/enumerate.ts
499
- function enumerate(x) {
500
- if (x === null || x === void 0) {
501
- return [];
502
- } else if (Array.isArray(x)) {
503
- return x;
504
- } else {
505
- return [
506
- x
507
- ];
508
- }
509
- }
510
- __name(enumerate, "enumerate");
487
+ // src/client/crud/dialects/index.ts
488
+ var import_ts_pattern5 = require("ts-pattern");
489
+
490
+ // src/client/crud/dialects/postgresql.ts
491
+ var import_common_helpers4 = require("@zenstackhq/common-helpers");
492
+ var import_decimal = __toESM(require("decimal.js"), 1);
493
+ var import_kysely2 = require("kysely");
494
+ var import_ts_pattern3 = require("ts-pattern");
511
495
 
512
496
  // src/client/crud/dialects/base-dialect.ts
497
+ var import_common_helpers3 = require("@zenstackhq/common-helpers");
498
+ var import_kysely = require("kysely");
499
+ var import_ts_pattern2 = require("ts-pattern");
513
500
  var BaseCrudDialect = class {
514
501
  static {
515
502
  __name(this, "BaseCrudDialect");
@@ -554,7 +541,7 @@ var BaseCrudDialect = class {
554
541
  if ("distinct" in args && args.distinct) {
555
542
  const distinct = ensureArray(args.distinct);
556
543
  if (this.supportsDistinctOn) {
557
- result = result.distinctOn(distinct.map((f) => import_kysely2.sql.ref(`${modelAlias}.${f}`)));
544
+ result = result.distinctOn(distinct.map((f) => import_kysely.sql.ref(`${modelAlias}.${f}`)));
558
545
  } else {
559
546
  throw new QueryError(`"distinct" is not supported by "${this.schema.provider.type}" provider`);
560
547
  }
@@ -604,7 +591,7 @@ var BaseCrudDialect = class {
604
591
  buildCursorFilter(model, query, cursor, orderBy, negateOrderBy, modelAlias) {
605
592
  const _orderBy = orderBy ?? makeDefaultOrderBy(this.schema, model);
606
593
  const orderByItems = ensureArray(_orderBy).flatMap((obj) => Object.entries(obj));
607
- const eb = (0, import_kysely2.expressionBuilder)();
594
+ const eb = (0, import_kysely.expressionBuilder)();
608
595
  const subQueryAlias = `${model}$cursor$sub`;
609
596
  const cursorFilter = this.buildFilter(eb, model, subQueryAlias, cursor);
610
597
  let result = query;
@@ -639,7 +626,7 @@ var BaseCrudDialect = class {
639
626
  if (payload === null) {
640
627
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, model, field);
641
628
  if (ownedByModel && !fieldDef.originModel) {
642
- return this.and(eb, ...keyPairs.map(({ fk }) => eb(import_kysely2.sql.ref(`${modelAlias}.${fk}`), "is", null)));
629
+ return this.and(eb, ...keyPairs.map(({ fk }) => eb(import_kysely.sql.ref(`${modelAlias}.${fk}`), "is", null)));
643
630
  } else {
644
631
  return this.buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, {
645
632
  is: null
@@ -656,7 +643,7 @@ var BaseCrudDialect = class {
656
643
  joinAlias
657
644
  );
658
645
  const filterResultField = `${field}$filter`;
659
- 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));
646
+ 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));
660
647
  const conditions = [];
661
648
  if ("is" in payload || "isNot" in payload) {
662
649
  if ("is" in payload) {
@@ -686,7 +673,7 @@ var BaseCrudDialect = class {
686
673
  }
687
674
  buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
688
675
  if (payload === null) {
689
- return eb(import_kysely2.sql.ref(`${modelAlias}.${field}`), "is", null);
676
+ return eb(import_kysely.sql.ref(`${modelAlias}.${field}`), "is", null);
690
677
  }
691
678
  const relationModel = fieldDef.type;
692
679
  const relationFilterSelectAlias = `${modelAlias}$${field}$filter`;
@@ -694,18 +681,18 @@ var BaseCrudDialect = class {
694
681
  const m2m = getManyToManyRelation(this.schema, model, field);
695
682
  if (m2m) {
696
683
  const modelIdFields = requireIdFields(this.schema, model);
697
- (0, import_common_helpers2.invariant)(modelIdFields.length === 1, "many-to-many relation must have exactly one id field");
684
+ (0, import_common_helpers3.invariant)(modelIdFields.length === 1, "many-to-many relation must have exactly one id field");
698
685
  const relationIdFields = requireIdFields(this.schema, relationModel);
699
- (0, import_common_helpers2.invariant)(relationIdFields.length === 1, "many-to-many relation must have exactly one id field");
700
- 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]}`)));
686
+ (0, import_common_helpers3.invariant)(relationIdFields.length === 1, "many-to-many relation must have exactly one id field");
687
+ return eb2(import_kysely.sql.ref(`${relationFilterSelectAlias}.${relationIdFields[0]}`), "in", eb2.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(import_kysely.sql.ref(`${m2m.joinTable}.${m2m.parentFkName}`), "=", import_kysely.sql.ref(`${modelAlias}.${modelIdFields[0]}`)));
701
688
  } else {
702
689
  const relationKeyPairs = getRelationForeignKeyFieldPairs(this.schema, model, field);
703
690
  let result2 = this.true(eb2);
704
691
  for (const { fk, pk } of relationKeyPairs.keyPairs) {
705
692
  if (relationKeyPairs.ownedByModel) {
706
- result2 = this.and(eb2, result2, eb2(import_kysely2.sql.ref(`${modelAlias}.${fk}`), "=", import_kysely2.sql.ref(`${relationFilterSelectAlias}.${pk}`)));
693
+ result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${modelAlias}.${fk}`), "=", import_kysely.sql.ref(`${relationFilterSelectAlias}.${pk}`)));
707
694
  } else {
708
- result2 = this.and(eb2, result2, eb2(import_kysely2.sql.ref(`${modelAlias}.${pk}`), "=", import_kysely2.sql.ref(`${relationFilterSelectAlias}.${fk}`)));
695
+ result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${modelAlias}.${pk}`), "=", import_kysely.sql.ref(`${relationFilterSelectAlias}.${fk}`)));
709
696
  }
710
697
  }
711
698
  return result2;
@@ -788,7 +775,7 @@ var BaseCrudDialect = class {
788
775
  return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type, false) : rhs);
789
776
  }
790
777
  buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0, excludeKeys = []) {
791
- if (payload === null || !(0, import_common_helpers2.isPlainObject)(payload)) {
778
+ if (payload === null || !(0, import_common_helpers3.isPlainObject)(payload)) {
792
779
  return {
793
780
  conditions: [
794
781
  this.buildLiteralFilter(eb, lhs, type, payload)
@@ -807,14 +794,14 @@ var BaseCrudDialect = class {
807
794
  }
808
795
  const rhs = Array.isArray(value) ? value.map(getRhs) : getRhs(value);
809
796
  const condition = (0, import_ts_pattern2.match)(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
810
- (0, import_common_helpers2.invariant)(Array.isArray(rhs), "right hand side must be an array");
797
+ (0, import_common_helpers3.invariant)(Array.isArray(rhs), "right hand side must be an array");
811
798
  if (rhs.length === 0) {
812
799
  return this.false(eb);
813
800
  } else {
814
801
  return eb(lhs, "in", rhs);
815
802
  }
816
803
  }).with("notIn", () => {
817
- (0, import_common_helpers2.invariant)(Array.isArray(rhs), "right hand side must be an array");
804
+ (0, import_common_helpers3.invariant)(Array.isArray(rhs), "right hand side must be an array");
818
805
  if (rhs.length === 0) {
819
806
  return this.true(eb);
820
807
  } else {
@@ -854,7 +841,7 @@ var BaseCrudDialect = class {
854
841
  if (key === "mode" || consumedKeys.includes(key)) {
855
842
  continue;
856
843
  }
857
- 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(() => {
844
+ 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(() => {
858
845
  throw new QueryError(`Invalid string filter key: ${key}`);
859
846
  });
860
847
  if (condition) {
@@ -866,16 +853,16 @@ var BaseCrudDialect = class {
866
853
  }
867
854
  prepStringCasing(eb, value, mode) {
868
855
  if (!mode || mode === "default") {
869
- return value === null ? value : import_kysely2.sql.val(value);
856
+ return value === null ? value : import_kysely.sql.val(value);
870
857
  }
871
858
  if (typeof value === "string") {
872
859
  return eb.fn("lower", [
873
- import_kysely2.sql.val(value)
860
+ import_kysely.sql.val(value)
874
861
  ]);
875
862
  } else if (Array.isArray(value)) {
876
863
  return value.map((v) => this.prepStringCasing(eb, v, mode));
877
864
  } else {
878
- return value === null ? null : import_kysely2.sql.val(value);
865
+ return value === null ? null : import_kysely.sql.val(value);
879
866
  }
880
867
  }
881
868
  buildNumberFilter(eb, fieldRef, type, payload) {
@@ -932,19 +919,19 @@ var BaseCrudDialect = class {
932
919
  "_min",
933
920
  "_max"
934
921
  ].includes(field)) {
935
- (0, import_common_helpers2.invariant)(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
922
+ (0, import_common_helpers3.invariant)(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
936
923
  for (const [k, v] of Object.entries(value)) {
937
- (0, import_common_helpers2.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
938
- result = result.orderBy((eb) => aggregate(eb, this.fieldRef(model, k, eb, modelAlias), field), import_kysely2.sql.raw(this.negateSort(v, negated)));
924
+ (0, import_common_helpers3.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
925
+ result = result.orderBy((eb) => aggregate(eb, this.fieldRef(model, k, eb, modelAlias), field), import_kysely.sql.raw(this.negateSort(v, negated)));
939
926
  }
940
927
  continue;
941
928
  }
942
929
  switch (field) {
943
930
  case "_count": {
944
- (0, import_common_helpers2.invariant)(value && typeof value === "object", 'invalid orderBy value for field "_count"');
931
+ (0, import_common_helpers3.invariant)(value && typeof value === "object", 'invalid orderBy value for field "_count"');
945
932
  for (const [k, v] of Object.entries(value)) {
946
- (0, import_common_helpers2.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
947
- result = result.orderBy((eb) => eb.fn.count(this.fieldRef(model, k, eb, modelAlias)), import_kysely2.sql.raw(this.negateSort(v, negated)));
933
+ (0, import_common_helpers3.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
934
+ result = result.orderBy((eb) => eb.fn.count(this.fieldRef(model, k, eb, modelAlias)), import_kysely.sql.raw(this.negateSort(v, negated)));
948
935
  }
949
936
  continue;
950
937
  }
@@ -953,11 +940,11 @@ var BaseCrudDialect = class {
953
940
  }
954
941
  const fieldDef = requireField(this.schema, model, field);
955
942
  if (!fieldDef.relation) {
956
- const fieldRef = this.fieldRef(model, field, (0, import_kysely2.expressionBuilder)(), modelAlias);
943
+ const fieldRef = this.fieldRef(model, field, (0, import_kysely.expressionBuilder)(), modelAlias);
957
944
  if (value === "asc" || value === "desc") {
958
945
  result = result.orderBy(fieldRef, this.negateSort(value, negated));
959
946
  } else if (value && typeof value === "object" && "nulls" in value && "sort" in value && (value.sort === "asc" || value.sort === "desc") && (value.nulls === "first" || value.nulls === "last")) {
960
- result = result.orderBy(fieldRef, import_kysely2.sql.raw(`${this.negateSort(value.sort, negated)} nulls ${value.nulls}`));
947
+ result = result.orderBy(fieldRef, import_kysely.sql.raw(`${this.negateSort(value.sort, negated)} nulls ${value.nulls}`));
961
948
  }
962
949
  } else {
963
950
  const relationModel = fieldDef.type;
@@ -966,13 +953,13 @@ var BaseCrudDialect = class {
966
953
  throw new QueryError(`invalid orderBy value for field "${field}"`);
967
954
  }
968
955
  if ("_count" in value) {
969
- (0, import_common_helpers2.invariant)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
956
+ (0, import_common_helpers3.invariant)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
970
957
  const sort = this.negateSort(value._count, negated);
971
958
  result = result.orderBy((eb) => {
972
959
  const subQueryAlias = `${modelAlias}$orderBy$${field}$count`;
973
960
  let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
974
961
  const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, subQueryAlias);
975
- subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right)))));
962
+ subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely.sql.ref(left), "=", import_kysely.sql.ref(right)))));
976
963
  subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
977
964
  return subQuery;
978
965
  }, sort);
@@ -980,7 +967,7 @@ var BaseCrudDialect = class {
980
967
  } else {
981
968
  result = result.leftJoin(relationModel, (join) => {
982
969
  const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, relationModel);
983
- return join.on((eb) => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right)))));
970
+ return join.on((eb) => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely.sql.ref(left), "=", import_kysely.sql.ref(right)))));
984
971
  });
985
972
  result = this.buildOrderBy(result, fieldDef.type, relationModel, value, false, negated);
986
973
  }
@@ -1032,7 +1019,7 @@ var BaseCrudDialect = class {
1032
1019
  if (fieldDef.computed) {
1033
1020
  return query.select((eb) => this.fieldRef(model, field, eb, modelAlias).as(field));
1034
1021
  } else if (!fieldDef.originModel) {
1035
- return query.select(import_kysely2.sql.ref(`${modelAlias}.${field}`).as(field));
1022
+ return query.select(import_kysely.sql.ref(`${modelAlias}.${field}`).as(field));
1036
1023
  } else {
1037
1024
  return this.buildSelectField(query, fieldDef.originModel, fieldDef.originModel, field);
1038
1025
  }
@@ -1179,14 +1166,14 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1179
1166
  if (typeof value === "bigint") {
1180
1167
  return value;
1181
1168
  }
1182
- (0, import_common_helpers3.invariant)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
1169
+ (0, import_common_helpers4.invariant)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
1183
1170
  return BigInt(value);
1184
1171
  }
1185
1172
  transformDecimal(value) {
1186
1173
  if (value instanceof import_decimal.default) {
1187
1174
  return value;
1188
1175
  }
1189
- (0, import_common_helpers3.invariant)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal.default, `Expected string, number or Decimal, got ${typeof value}`);
1176
+ (0, import_common_helpers4.invariant)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal.default, `Expected string, number or Decimal, got ${typeof value}`);
1190
1177
  return new import_decimal.default(value);
1191
1178
  }
1192
1179
  transformOutputDate(value) {
@@ -1233,12 +1220,12 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1233
1220
  if (m2m) {
1234
1221
  const parentIds = requireIdFields(this.schema, model);
1235
1222
  const relationIds = requireIdFields(this.schema, relationModel);
1236
- (0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1237
- (0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1223
+ (0, import_common_helpers4.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1224
+ (0, import_common_helpers4.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1238
1225
  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}`)));
1239
1226
  } else {
1240
1227
  const joinPairs = buildJoinPairs(this.schema, model, parentAlias, relationField, relationModelAlias);
1241
- query = query.where((eb) => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely3.sql.ref(left), "=", import_kysely3.sql.ref(right)))));
1228
+ query = query.where((eb) => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right)))));
1242
1229
  }
1243
1230
  return query;
1244
1231
  }
@@ -1246,9 +1233,9 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1246
1233
  qb = qb.select((eb) => {
1247
1234
  const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias, eb, payload, parentResultName);
1248
1235
  if (relationFieldDef.array) {
1249
- return eb.fn.coalesce(import_kysely3.sql`jsonb_agg(jsonb_build_object(${import_kysely3.sql.join(objArgs)}))`, import_kysely3.sql`'[]'::jsonb`).as("$data");
1236
+ return eb.fn.coalesce(import_kysely2.sql`jsonb_agg(jsonb_build_object(${import_kysely2.sql.join(objArgs)}))`, import_kysely2.sql`'[]'::jsonb`).as("$data");
1250
1237
  } else {
1251
- return import_kysely3.sql`jsonb_build_object(${import_kysely3.sql.join(objArgs)})`.as("$data");
1238
+ return import_kysely2.sql`jsonb_build_object(${import_kysely2.sql.join(objArgs)})`.as("$data");
1252
1239
  }
1253
1240
  });
1254
1241
  return qb;
@@ -1259,13 +1246,13 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1259
1246
  const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
1260
1247
  if (descendantModels.length > 0) {
1261
1248
  objArgs.push(...descendantModels.map((subModel) => [
1262
- import_kysely3.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1249
+ import_kysely2.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1263
1250
  eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
1264
1251
  ]).flatMap((v) => v));
1265
1252
  }
1266
1253
  if (payload === true || !payload.select) {
1267
1254
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
1268
- import_kysely3.sql.lit(field),
1255
+ import_kysely2.sql.lit(field),
1269
1256
  this.fieldRef(relationModel, field, eb, relationModelAlias, false)
1270
1257
  ]).flatMap((v) => v));
1271
1258
  } else if (payload.select) {
@@ -1273,14 +1260,14 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1273
1260
  if (field === "_count") {
1274
1261
  const subJson = this.buildCountJson(relationModel, eb, relationModelAlias, value);
1275
1262
  return [
1276
- import_kysely3.sql.lit(field),
1263
+ import_kysely2.sql.lit(field),
1277
1264
  subJson
1278
1265
  ];
1279
1266
  } else {
1280
1267
  const fieldDef = requireField(this.schema, relationModel, field);
1281
1268
  const fieldValue = fieldDef.relation ? eb.ref(`${parentResultName}$${field}.$data`) : this.fieldRef(relationModel, field, eb, relationModelAlias, false);
1282
1269
  return [
1283
- import_kysely3.sql.lit(field),
1270
+ import_kysely2.sql.lit(field),
1284
1271
  fieldValue
1285
1272
  ];
1286
1273
  }
@@ -1288,7 +1275,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1288
1275
  }
1289
1276
  if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
1290
1277
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field]) => [
1291
- import_kysely3.sql.lit(field),
1278
+ import_kysely2.sql.lit(field),
1292
1279
  // reference the synthesized JSON field
1293
1280
  eb.ref(`${parentResultName}$${field}.$data`)
1294
1281
  ]).flatMap((v) => v));
@@ -1318,7 +1305,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1318
1305
  }
1319
1306
  buildJsonObject(eb, value) {
1320
1307
  return eb.fn("jsonb_build_object", Object.entries(value).flatMap(([key, value2]) => [
1321
- import_kysely3.sql.lit(key),
1308
+ import_kysely2.sql.lit(key),
1322
1309
  value2
1323
1310
  ]));
1324
1311
  }
@@ -1370,9 +1357,9 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1370
1357
  };
1371
1358
 
1372
1359
  // src/client/crud/dialects/sqlite.ts
1373
- var import_common_helpers4 = require("@zenstackhq/common-helpers");
1360
+ var import_common_helpers5 = require("@zenstackhq/common-helpers");
1374
1361
  var import_decimal2 = __toESM(require("decimal.js"), 1);
1375
- var import_kysely4 = require("kysely");
1362
+ var import_kysely3 = require("kysely");
1376
1363
  var import_ts_pattern4 = require("ts-pattern");
1377
1364
  var SqliteCrudDialect = class extends BaseCrudDialect {
1378
1365
  static {
@@ -1408,14 +1395,14 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1408
1395
  if (value instanceof import_decimal2.default) {
1409
1396
  return value;
1410
1397
  }
1411
- (0, import_common_helpers4.invariant)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal2.default, `Expected string, number or Decimal, got ${typeof value}`);
1398
+ (0, import_common_helpers5.invariant)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal2.default, `Expected string, number or Decimal, got ${typeof value}`);
1412
1399
  return new import_decimal2.default(value);
1413
1400
  }
1414
1401
  transformOutputBigInt(value) {
1415
1402
  if (typeof value === "bigint") {
1416
1403
  return value;
1417
1404
  }
1418
- (0, import_common_helpers4.invariant)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
1405
+ (0, import_common_helpers5.invariant)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
1419
1406
  return BigInt(value);
1420
1407
  }
1421
1408
  transformOutputBoolean(value) {
@@ -1468,13 +1455,13 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1468
1455
  const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
1469
1456
  if (descendantModels.length > 0) {
1470
1457
  objArgs.push(...descendantModels.map((subModel) => [
1471
- import_kysely4.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1458
+ import_kysely3.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1472
1459
  eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
1473
1460
  ]).flatMap((v) => v));
1474
1461
  }
1475
1462
  if (payload === true || !payload.select) {
1476
1463
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
1477
- import_kysely4.sql.lit(field),
1464
+ import_kysely3.sql.lit(field),
1478
1465
  this.fieldRef(relationModel, field, eb, subQueryName, false)
1479
1466
  ]).flatMap((v) => v));
1480
1467
  } else if (payload.select) {
@@ -1482,7 +1469,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1482
1469
  if (field === "_count") {
1483
1470
  const subJson = this.buildCountJson(relationModel, eb, `${parentAlias}$${relationField}`, value);
1484
1471
  return [
1485
- import_kysely4.sql.lit(field),
1472
+ import_kysely3.sql.lit(field),
1486
1473
  subJson
1487
1474
  ];
1488
1475
  } else {
@@ -1490,12 +1477,12 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1490
1477
  if (fieldDef.relation) {
1491
1478
  const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
1492
1479
  return [
1493
- import_kysely4.sql.lit(field),
1480
+ import_kysely3.sql.lit(field),
1494
1481
  subJson
1495
1482
  ];
1496
1483
  } else {
1497
1484
  return [
1498
- import_kysely4.sql.lit(field),
1485
+ import_kysely3.sql.lit(field),
1499
1486
  this.fieldRef(relationModel, field, eb, subQueryName, false)
1500
1487
  ];
1501
1488
  }
@@ -1506,15 +1493,15 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1506
1493
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field, value]) => {
1507
1494
  const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
1508
1495
  return [
1509
- import_kysely4.sql.lit(field),
1496
+ import_kysely3.sql.lit(field),
1510
1497
  subJson
1511
1498
  ];
1512
1499
  }).flatMap((v) => v));
1513
1500
  }
1514
1501
  if (relationFieldDef.array) {
1515
- return eb.fn.coalesce(import_kysely4.sql`json_group_array(json_object(${import_kysely4.sql.join(objArgs)}))`, import_kysely4.sql`json_array()`).as("$data");
1502
+ return eb.fn.coalesce(import_kysely3.sql`json_group_array(json_object(${import_kysely3.sql.join(objArgs)}))`, import_kysely3.sql`json_array()`).as("$data");
1516
1503
  } else {
1517
- return import_kysely4.sql`json_object(${import_kysely4.sql.join(objArgs)})`.as("$data");
1504
+ return import_kysely3.sql`json_object(${import_kysely3.sql.join(objArgs)})`.as("$data");
1518
1505
  }
1519
1506
  });
1520
1507
  return tbl;
@@ -1526,8 +1513,8 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1526
1513
  if (m2m) {
1527
1514
  const parentIds = requireIdFields(this.schema, model);
1528
1515
  const relationIds = requireIdFields(this.schema, relationModel);
1529
- (0, import_common_helpers4.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1530
- (0, import_common_helpers4.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1516
+ (0, import_common_helpers5.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1517
+ (0, import_common_helpers5.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1531
1518
  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}`)));
1532
1519
  } else {
1533
1520
  const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
@@ -1555,7 +1542,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1555
1542
  }
1556
1543
  buildJsonObject(eb, value) {
1557
1544
  return eb.fn("json_object", Object.entries(value).flatMap(([key, value2]) => [
1558
- import_kysely4.sql.lit(key),
1545
+ import_kysely3.sql.lit(key),
1559
1546
  value2
1560
1547
  ]));
1561
1548
  }
@@ -1605,9 +1592,152 @@ function getCrudDialect(schema, options) {
1605
1592
  }
1606
1593
  __name(getCrudDialect, "getCrudDialect");
1607
1594
 
1595
+ // src/client/crud/operations/count.ts
1596
+ var import_kysely6 = require("kysely");
1597
+
1598
+ // src/client/crud/operations/create.ts
1599
+ var import_ts_pattern8 = require("ts-pattern");
1600
+
1601
+ // src/client/crud/operations/delete.ts
1602
+ var import_ts_pattern9 = require("ts-pattern");
1603
+
1604
+ // src/client/crud/operations/group-by.ts
1605
+ var import_kysely7 = require("kysely");
1606
+ var import_ts_pattern10 = require("ts-pattern");
1607
+
1608
+ // src/client/crud/operations/update.ts
1609
+ var import_ts_pattern11 = require("ts-pattern");
1610
+
1611
+ // src/client/crud/validator.ts
1612
+ var import_common_helpers7 = require("@zenstackhq/common-helpers");
1613
+ var import_decimal3 = __toESM(require("decimal.js"), 1);
1614
+ var import_json_stable_stringify = __toESM(require("json-stable-stringify"), 1);
1615
+ var import_ts_pattern12 = require("ts-pattern");
1616
+ var import_zod = require("zod");
1617
+
1618
+ // src/utils/zod-utils.ts
1619
+ var import_v3 = require("zod-validation-error/v3");
1620
+ var import_v4 = require("zod-validation-error/v4");
1621
+
1622
+ // src/client/executor/zenstack-query-executor.ts
1623
+ var import_common_helpers9 = require("@zenstackhq/common-helpers");
1624
+ var import_kysely10 = require("kysely");
1625
+ var import_ts_pattern13 = require("ts-pattern");
1626
+
1627
+ // src/client/kysely-utils.ts
1628
+ var import_kysely8 = require("kysely");
1629
+ function extractFieldName(node) {
1630
+ if (import_kysely8.ReferenceNode.is(node) && import_kysely8.ColumnNode.is(node.column)) {
1631
+ return node.column.column.name;
1632
+ } else if (import_kysely8.ColumnNode.is(node)) {
1633
+ return node.column.name;
1634
+ } else {
1635
+ return void 0;
1636
+ }
1637
+ }
1638
+ __name(extractFieldName, "extractFieldName");
1639
+
1640
+ // src/client/executor/name-mapper.ts
1641
+ var import_common_helpers8 = require("@zenstackhq/common-helpers");
1642
+ var import_kysely9 = require("kysely");
1643
+
1644
+ // src/client/functions.ts
1645
+ var import_common_helpers10 = require("@zenstackhq/common-helpers");
1646
+ var import_kysely11 = require("kysely");
1647
+ var import_ts_pattern14 = require("ts-pattern");
1648
+
1649
+ // src/client/helpers/schema-db-pusher.ts
1650
+ var import_common_helpers11 = require("@zenstackhq/common-helpers");
1651
+ var import_kysely12 = require("kysely");
1652
+ var import_toposort = __toESM(require("toposort"), 1);
1653
+ var import_ts_pattern15 = require("ts-pattern");
1654
+
1655
+ // src/client/index.ts
1656
+ var import_kysely14 = require("kysely");
1657
+
1658
+ // src/plugins/policy/errors.ts
1659
+ var RejectedByPolicyReason = /* @__PURE__ */ function(RejectedByPolicyReason2) {
1660
+ RejectedByPolicyReason2["NO_ACCESS"] = "no-access";
1661
+ RejectedByPolicyReason2["CANNOT_READ_BACK"] = "cannot-read-back";
1662
+ RejectedByPolicyReason2["OTHER"] = "other";
1663
+ return RejectedByPolicyReason2;
1664
+ }({});
1665
+ var RejectedByPolicyError = class extends ZenStackError {
1666
+ static {
1667
+ __name(this, "RejectedByPolicyError");
1668
+ }
1669
+ model;
1670
+ reason;
1671
+ constructor(model, reason = "no-access", message) {
1672
+ super(message ?? `Operation rejected by policy${model ? ": " + model : ""}`), this.model = model, this.reason = reason;
1673
+ }
1674
+ };
1675
+
1676
+ // src/plugins/policy/functions.ts
1677
+ var import_common_helpers16 = require("@zenstackhq/common-helpers");
1678
+ var import_kysely19 = require("kysely");
1679
+
1680
+ // src/plugins/policy/policy-handler.ts
1681
+ var import_common_helpers15 = require("@zenstackhq/common-helpers");
1682
+ var import_kysely18 = require("kysely");
1683
+ var import_ts_pattern19 = require("ts-pattern");
1684
+
1685
+ // src/utils/expression-utils.ts
1686
+ var import_ts_pattern16 = require("ts-pattern");
1687
+ var ExpressionVisitor = class {
1688
+ static {
1689
+ __name(this, "ExpressionVisitor");
1690
+ }
1691
+ visit(expr2) {
1692
+ (0, import_ts_pattern16.match)(expr2).with({
1693
+ kind: "literal"
1694
+ }, (e) => this.visitLiteral(e)).with({
1695
+ kind: "array"
1696
+ }, (e) => this.visitArray(e)).with({
1697
+ kind: "field"
1698
+ }, (e) => this.visitField(e)).with({
1699
+ kind: "member"
1700
+ }, (e) => this.visitMember(e)).with({
1701
+ kind: "binary"
1702
+ }, (e) => this.visitBinary(e)).with({
1703
+ kind: "unary"
1704
+ }, (e) => this.visitUnary(e)).with({
1705
+ kind: "call"
1706
+ }, (e) => this.visitCall(e)).with({
1707
+ kind: "this"
1708
+ }, (e) => this.visitThis(e)).with({
1709
+ kind: "null"
1710
+ }, (e) => this.visitNull(e)).exhaustive();
1711
+ }
1712
+ visitLiteral(_e) {
1713
+ }
1714
+ visitArray(e) {
1715
+ e.items.forEach((item) => this.visit(item));
1716
+ }
1717
+ visitField(_e) {
1718
+ }
1719
+ visitMember(e) {
1720
+ this.visit(e.receiver);
1721
+ }
1722
+ visitBinary(e) {
1723
+ this.visit(e.left);
1724
+ this.visit(e.right);
1725
+ }
1726
+ visitUnary(e) {
1727
+ this.visit(e.operand);
1728
+ }
1729
+ visitCall(e) {
1730
+ e.args?.forEach((arg) => this.visit(arg));
1731
+ }
1732
+ visitThis(_e) {
1733
+ }
1734
+ visitNull(_e) {
1735
+ }
1736
+ };
1737
+
1608
1738
  // src/utils/default-operation-node-visitor.ts
1609
- var import_kysely5 = require("kysely");
1610
- var DefaultOperationNodeVisitor = class extends import_kysely5.OperationNodeVisitor {
1739
+ var import_kysely15 = require("kysely");
1740
+ var DefaultOperationNodeVisitor = class extends import_kysely15.OperationNodeVisitor {
1611
1741
  static {
1612
1742
  __name(this, "DefaultOperationNodeVisitor");
1613
1743
  }
@@ -1924,19 +2054,19 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
1924
2054
  };
1925
2055
 
1926
2056
  // src/plugins/policy/expression-transformer.ts
1927
- var import_common_helpers6 = require("@zenstackhq/common-helpers");
1928
- var import_kysely7 = require("kysely");
1929
- var import_ts_pattern7 = require("ts-pattern");
2057
+ var import_common_helpers14 = require("@zenstackhq/common-helpers");
2058
+ var import_kysely17 = require("kysely");
2059
+ var import_ts_pattern18 = require("ts-pattern");
1930
2060
 
1931
2061
  // src/plugins/policy/expression-evaluator.ts
1932
- var import_common_helpers5 = require("@zenstackhq/common-helpers");
1933
- var import_ts_pattern6 = require("ts-pattern");
2062
+ var import_common_helpers13 = require("@zenstackhq/common-helpers");
2063
+ var import_ts_pattern17 = require("ts-pattern");
1934
2064
  var ExpressionEvaluator = class {
1935
2065
  static {
1936
2066
  __name(this, "ExpressionEvaluator");
1937
2067
  }
1938
2068
  evaluate(expression, context) {
1939
- const result = (0, import_ts_pattern6.match)(expression).when(ExpressionUtils.isArray, (expr2) => this.evaluateArray(expr2, context)).when(ExpressionUtils.isBinary, (expr2) => this.evaluateBinary(expr2, context)).when(ExpressionUtils.isField, (expr2) => this.evaluateField(expr2, context)).when(ExpressionUtils.isLiteral, (expr2) => this.evaluateLiteral(expr2)).when(ExpressionUtils.isMember, (expr2) => this.evaluateMember(expr2, context)).when(ExpressionUtils.isUnary, (expr2) => this.evaluateUnary(expr2, context)).when(ExpressionUtils.isCall, (expr2) => this.evaluateCall(expr2, context)).when(ExpressionUtils.isThis, () => context.thisValue).when(ExpressionUtils.isNull, () => null).exhaustive();
2069
+ const result = (0, import_ts_pattern17.match)(expression).when(ExpressionUtils.isArray, (expr2) => this.evaluateArray(expr2, context)).when(ExpressionUtils.isBinary, (expr2) => this.evaluateBinary(expr2, context)).when(ExpressionUtils.isField, (expr2) => this.evaluateField(expr2, context)).when(ExpressionUtils.isLiteral, (expr2) => this.evaluateLiteral(expr2)).when(ExpressionUtils.isMember, (expr2) => this.evaluateMember(expr2, context)).when(ExpressionUtils.isUnary, (expr2) => this.evaluateUnary(expr2, context)).when(ExpressionUtils.isCall, (expr2) => this.evaluateCall(expr2, context)).when(ExpressionUtils.isThis, () => context.thisValue).when(ExpressionUtils.isNull, () => null).exhaustive();
1940
2070
  return result ?? null;
1941
2071
  }
1942
2072
  evaluateCall(expr2, context) {
@@ -1947,7 +2077,7 @@ var ExpressionEvaluator = class {
1947
2077
  }
1948
2078
  }
1949
2079
  evaluateUnary(expr2, context) {
1950
- return (0, import_ts_pattern6.match)(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
2080
+ return (0, import_ts_pattern17.match)(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1951
2081
  }
1952
2082
  evaluateMember(expr2, context) {
1953
2083
  let val = this.evaluate(expr2.receiver, context);
@@ -1971,21 +2101,21 @@ var ExpressionEvaluator = class {
1971
2101
  }
1972
2102
  const left = this.evaluate(expr2.left, context);
1973
2103
  const right = this.evaluate(expr2.right, context);
1974
- 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", () => {
2104
+ return (0, import_ts_pattern17.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", () => {
1975
2105
  const _right = right ?? [];
1976
- (0, import_common_helpers5.invariant)(Array.isArray(_right), 'expected array for "in" operator');
2106
+ (0, import_common_helpers13.invariant)(Array.isArray(_right), 'expected array for "in" operator');
1977
2107
  return _right.includes(left);
1978
2108
  }).exhaustive();
1979
2109
  }
1980
2110
  evaluateCollectionPredicate(expr2, context) {
1981
2111
  const op = expr2.op;
1982
- (0, import_common_helpers5.invariant)(op === "?" || op === "!" || op === "^", 'expected "?" or "!" or "^" operator');
2112
+ (0, import_common_helpers13.invariant)(op === "?" || op === "!" || op === "^", 'expected "?" or "!" or "^" operator');
1983
2113
  const left = this.evaluate(expr2.left, context);
1984
2114
  if (!left) {
1985
2115
  return false;
1986
2116
  }
1987
- (0, import_common_helpers5.invariant)(Array.isArray(left), "expected array");
1988
- return (0, import_ts_pattern6.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
2117
+ (0, import_common_helpers13.invariant)(Array.isArray(left), "expected array");
2118
+ return (0, import_ts_pattern17.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1989
2119
  ...context,
1990
2120
  thisValue: item
1991
2121
  }))).with("!", () => left.every((item) => this.evaluate(expr2.right, {
@@ -1999,21 +2129,21 @@ var ExpressionEvaluator = class {
1999
2129
  };
2000
2130
 
2001
2131
  // src/plugins/policy/utils.ts
2002
- var import_kysely6 = require("kysely");
2132
+ var import_kysely16 = require("kysely");
2003
2133
  function trueNode(dialect) {
2004
- return import_kysely6.ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean", false));
2134
+ return import_kysely16.ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean", false));
2005
2135
  }
2006
2136
  __name(trueNode, "trueNode");
2007
2137
  function falseNode(dialect) {
2008
- return import_kysely6.ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean", false));
2138
+ return import_kysely16.ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean", false));
2009
2139
  }
2010
2140
  __name(falseNode, "falseNode");
2011
2141
  function isTrueNode(node) {
2012
- return import_kysely6.ValueNode.is(node) && (node.value === true || node.value === 1);
2142
+ return import_kysely16.ValueNode.is(node) && (node.value === true || node.value === 1);
2013
2143
  }
2014
2144
  __name(isTrueNode, "isTrueNode");
2015
2145
  function isFalseNode(node) {
2016
- return import_kysely6.ValueNode.is(node) && (node.value === false || node.value === 0);
2146
+ return import_kysely16.ValueNode.is(node) && (node.value === false || node.value === 0);
2017
2147
  }
2018
2148
  __name(isFalseNode, "isFalseNode");
2019
2149
  function conjunction(dialect, nodes) {
@@ -2030,7 +2160,7 @@ function conjunction(dialect, nodes) {
2030
2160
  if (items.length === 0) {
2031
2161
  return trueNode(dialect);
2032
2162
  }
2033
- return items.reduce((acc, node) => import_kysely6.AndNode.create(wrapParensIf(acc, import_kysely6.OrNode.is), wrapParensIf(node, import_kysely6.OrNode.is)));
2163
+ return items.reduce((acc, node) => import_kysely16.AndNode.create(wrapParensIf(acc, import_kysely16.OrNode.is), wrapParensIf(node, import_kysely16.OrNode.is)));
2034
2164
  }
2035
2165
  __name(conjunction, "conjunction");
2036
2166
  function disjunction(dialect, nodes) {
@@ -2047,7 +2177,7 @@ function disjunction(dialect, nodes) {
2047
2177
  if (items.length === 0) {
2048
2178
  return falseNode(dialect);
2049
2179
  }
2050
- return items.reduce((acc, node) => import_kysely6.OrNode.create(wrapParensIf(acc, import_kysely6.AndNode.is), wrapParensIf(node, import_kysely6.AndNode.is)));
2180
+ return items.reduce((acc, node) => import_kysely16.OrNode.create(wrapParensIf(acc, import_kysely16.AndNode.is), wrapParensIf(node, import_kysely16.AndNode.is)));
2051
2181
  }
2052
2182
  __name(disjunction, "disjunction");
2053
2183
  function logicalNot(dialect, node) {
@@ -2057,11 +2187,11 @@ function logicalNot(dialect, node) {
2057
2187
  if (isFalseNode(node)) {
2058
2188
  return trueNode(dialect);
2059
2189
  }
2060
- return import_kysely6.UnaryOperationNode.create(import_kysely6.OperatorNode.create("not"), wrapParensIf(node, (n) => import_kysely6.AndNode.is(n) || import_kysely6.OrNode.is(n)));
2190
+ return import_kysely16.UnaryOperationNode.create(import_kysely16.OperatorNode.create("not"), wrapParensIf(node, (n) => import_kysely16.AndNode.is(n) || import_kysely16.OrNode.is(n)));
2061
2191
  }
2062
2192
  __name(logicalNot, "logicalNot");
2063
2193
  function wrapParensIf(node, predicate) {
2064
- return predicate(node) ? import_kysely6.ParensNode.create(node) : node;
2194
+ return predicate(node) ? import_kysely16.ParensNode.create(node) : node;
2065
2195
  }
2066
2196
  __name(wrapParensIf, "wrapParensIf");
2067
2197
  function buildIsFalse(node, dialect) {
@@ -2070,13 +2200,13 @@ function buildIsFalse(node, dialect) {
2070
2200
  } else if (isTrueNode(node)) {
2071
2201
  return falseNode(dialect);
2072
2202
  }
2073
- return import_kysely6.BinaryOperationNode.create(
2203
+ return import_kysely16.BinaryOperationNode.create(
2074
2204
  // coalesce so null is treated as false
2075
- import_kysely6.FunctionNode.create("coalesce", [
2205
+ import_kysely16.FunctionNode.create("coalesce", [
2076
2206
  node,
2077
2207
  falseNode(dialect)
2078
2208
  ]),
2079
- import_kysely6.OperatorNode.create("="),
2209
+ import_kysely16.OperatorNode.create("="),
2080
2210
  falseNode(dialect)
2081
2211
  );
2082
2212
  }
@@ -2085,16 +2215,20 @@ function getTableName(node) {
2085
2215
  if (!node) {
2086
2216
  return node;
2087
2217
  }
2088
- if (import_kysely6.TableNode.is(node)) {
2218
+ if (import_kysely16.TableNode.is(node)) {
2089
2219
  return node.table.identifier.name;
2090
- } else if (import_kysely6.AliasNode.is(node)) {
2220
+ } else if (import_kysely16.AliasNode.is(node)) {
2091
2221
  return getTableName(node.node);
2092
- } else if (import_kysely6.ReferenceNode.is(node) && node.table) {
2222
+ } else if (import_kysely16.ReferenceNode.is(node) && node.table) {
2093
2223
  return getTableName(node.table);
2094
2224
  }
2095
2225
  return void 0;
2096
2226
  }
2097
2227
  __name(getTableName, "getTableName");
2228
+ function isBeforeInvocation(expr2) {
2229
+ return ExpressionUtils.isCall(expr2) && expr2.function === "before";
2230
+ }
2231
+ __name(isBeforeInvocation, "isBeforeInvocation");
2098
2232
 
2099
2233
  // src/plugins/policy/expression-transformer.ts
2100
2234
  function _ts_decorate(decorators, target, key, desc) {
@@ -2154,7 +2288,7 @@ var ExpressionTransformer = class {
2154
2288
  return this.transformValue(expr2.value, typeof expr2.value === "string" ? "String" : typeof expr2.value === "boolean" ? "Boolean" : "Int");
2155
2289
  }
2156
2290
  _array(expr2, context) {
2157
- return import_kysely7.ValueListNode.create(expr2.items.map((item) => this.transform(item, context)));
2291
+ return import_kysely17.ValueListNode.create(expr2.items.map((item) => this.transform(item, context)));
2158
2292
  }
2159
2293
  _field(expr2, context) {
2160
2294
  const fieldDef = requireField(this.schema, context.model, expr2.field);
@@ -2174,18 +2308,18 @@ var ExpressionTransformer = class {
2174
2308
  }
2175
2309
  mergeWhere(where, memberFilter) {
2176
2310
  if (!where) {
2177
- return import_kysely7.WhereNode.create(memberFilter ?? trueNode(this.dialect));
2311
+ return import_kysely17.WhereNode.create(memberFilter ?? trueNode(this.dialect));
2178
2312
  }
2179
2313
  if (!memberFilter) {
2180
2314
  return where;
2181
2315
  }
2182
- return import_kysely7.WhereNode.create(conjunction(this.dialect, [
2316
+ return import_kysely17.WhereNode.create(conjunction(this.dialect, [
2183
2317
  where.where,
2184
2318
  memberFilter
2185
2319
  ]));
2186
2320
  }
2187
2321
  _null() {
2188
- return import_kysely7.ValueNode.createImmediate(null);
2322
+ return import_kysely17.ValueNode.createImmediate(null);
2189
2323
  }
2190
2324
  _binary(expr2, context) {
2191
2325
  if (expr2.op === "&&") {
@@ -2213,10 +2347,10 @@ var ExpressionTransformer = class {
2213
2347
  if (this.isNullNode(left)) {
2214
2348
  return this.transformValue(false, "Boolean");
2215
2349
  } else {
2216
- if (import_kysely7.ValueListNode.is(right)) {
2217
- return import_kysely7.BinaryOperationNode.create(left, import_kysely7.OperatorNode.create("in"), right);
2350
+ if (import_kysely17.ValueListNode.is(right)) {
2351
+ return import_kysely17.BinaryOperationNode.create(left, import_kysely17.OperatorNode.create("in"), right);
2218
2352
  } else {
2219
- return import_kysely7.BinaryOperationNode.create(left, import_kysely7.OperatorNode.create("="), import_kysely7.FunctionNode.create("any", [
2353
+ return import_kysely17.BinaryOperationNode.create(left, import_kysely17.OperatorNode.create("="), import_kysely17.FunctionNode.create("any", [
2220
2354
  right
2221
2355
  ]));
2222
2356
  }
@@ -2227,35 +2361,35 @@ var ExpressionTransformer = class {
2227
2361
  } else if (this.isNullNode(left)) {
2228
2362
  return this.transformNullCheck(right, expr2.op);
2229
2363
  } else {
2230
- return import_kysely7.BinaryOperationNode.create(left, this.transformOperator(op), right);
2364
+ return import_kysely17.BinaryOperationNode.create(left, this.transformOperator(op), right);
2231
2365
  }
2232
2366
  }
2233
2367
  transformNullCheck(expr2, operator) {
2234
- (0, import_common_helpers6.invariant)(operator === "==" || operator === "!=", 'operator must be "==" or "!=" for null comparison');
2235
- if (import_kysely7.ValueNode.is(expr2)) {
2368
+ (0, import_common_helpers14.invariant)(operator === "==" || operator === "!=", 'operator must be "==" or "!=" for null comparison');
2369
+ if (import_kysely17.ValueNode.is(expr2)) {
2236
2370
  if (expr2.value === null) {
2237
2371
  return operator === "==" ? trueNode(this.dialect) : falseNode(this.dialect);
2238
2372
  } else {
2239
2373
  return operator === "==" ? falseNode(this.dialect) : trueNode(this.dialect);
2240
2374
  }
2241
2375
  } else {
2242
- 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));
2376
+ return operator === "==" ? import_kysely17.BinaryOperationNode.create(expr2, import_kysely17.OperatorNode.create("is"), import_kysely17.ValueNode.createImmediate(null)) : import_kysely17.BinaryOperationNode.create(expr2, import_kysely17.OperatorNode.create("is not"), import_kysely17.ValueNode.createImmediate(null));
2243
2377
  }
2244
2378
  }
2245
2379
  normalizeBinaryOperationOperands(expr2, context) {
2246
2380
  let normalizedLeft = expr2.left;
2247
2381
  if (this.isRelationField(expr2.left, context.model)) {
2248
- (0, import_common_helpers6.invariant)(ExpressionUtils.isNull(expr2.right), "only null comparison is supported for relation field");
2382
+ (0, import_common_helpers14.invariant)(ExpressionUtils.isNull(expr2.right), "only null comparison is supported for relation field");
2249
2383
  const leftRelDef = this.getFieldDefFromFieldRef(expr2.left, context.model);
2250
- (0, import_common_helpers6.invariant)(leftRelDef, "failed to get relation field definition");
2384
+ (0, import_common_helpers14.invariant)(leftRelDef, "failed to get relation field definition");
2251
2385
  const idFields = requireIdFields(this.schema, leftRelDef.type);
2252
2386
  normalizedLeft = this.makeOrAppendMember(normalizedLeft, idFields[0]);
2253
2387
  }
2254
2388
  let normalizedRight = expr2.right;
2255
2389
  if (this.isRelationField(expr2.right, context.model)) {
2256
- (0, import_common_helpers6.invariant)(ExpressionUtils.isNull(expr2.left), "only null comparison is supported for relation field");
2390
+ (0, import_common_helpers14.invariant)(ExpressionUtils.isNull(expr2.left), "only null comparison is supported for relation field");
2257
2391
  const rightRelDef = this.getFieldDefFromFieldRef(expr2.right, context.model);
2258
- (0, import_common_helpers6.invariant)(rightRelDef, "failed to get relation field definition");
2392
+ (0, import_common_helpers14.invariant)(rightRelDef, "failed to get relation field definition");
2259
2393
  const idFields = requireIdFields(this.schema, rightRelDef.type);
2260
2394
  normalizedRight = this.makeOrAppendMember(normalizedRight, idFields[0]);
2261
2395
  }
@@ -2265,21 +2399,21 @@ var ExpressionTransformer = class {
2265
2399
  };
2266
2400
  }
2267
2401
  transformCollectionPredicate(expr2, context) {
2268
- (0, import_common_helpers6.invariant)(expr2.op === "?" || expr2.op === "!" || expr2.op === "^", 'expected "?" or "!" or "^" operator');
2402
+ (0, import_common_helpers14.invariant)(expr2.op === "?" || expr2.op === "!" || expr2.op === "^", 'expected "?" or "!" or "^" operator');
2269
2403
  if (this.isAuthCall(expr2.left) || this.isAuthMember(expr2.left)) {
2270
2404
  const value = new ExpressionEvaluator().evaluate(expr2, {
2271
2405
  auth: this.auth
2272
2406
  });
2273
2407
  return this.transformValue(value, "Boolean");
2274
2408
  }
2275
- (0, import_common_helpers6.invariant)(ExpressionUtils.isField(expr2.left) || ExpressionUtils.isMember(expr2.left), "left operand must be field or member access");
2409
+ (0, import_common_helpers14.invariant)(ExpressionUtils.isField(expr2.left) || ExpressionUtils.isMember(expr2.left), "left operand must be field or member access");
2276
2410
  let newContextModel;
2277
2411
  const fieldDef = this.getFieldDefFromFieldRef(expr2.left, context.model);
2278
2412
  if (fieldDef) {
2279
- (0, import_common_helpers6.invariant)(fieldDef.relation, `field is not a relation: ${JSON.stringify(expr2.left)}`);
2413
+ (0, import_common_helpers14.invariant)(fieldDef.relation, `field is not a relation: ${JSON.stringify(expr2.left)}`);
2280
2414
  newContextModel = fieldDef.type;
2281
2415
  } else {
2282
- (0, import_common_helpers6.invariant)(ExpressionUtils.isMember(expr2.left) && ExpressionUtils.isField(expr2.left.receiver), "left operand must be member access with field receiver");
2416
+ (0, import_common_helpers14.invariant)(ExpressionUtils.isMember(expr2.left) && ExpressionUtils.isField(expr2.left.receiver), "left operand must be member access with field receiver");
2283
2417
  const fieldDef2 = requireField(this.schema, context.model, expr2.left.receiver.field);
2284
2418
  newContextModel = fieldDef2.type;
2285
2419
  for (const member of expr2.left.members) {
@@ -2295,13 +2429,13 @@ var ExpressionTransformer = class {
2295
2429
  if (expr2.op === "!") {
2296
2430
  predicateFilter = logicalNot(this.dialect, predicateFilter);
2297
2431
  }
2298
- const count = import_kysely7.FunctionNode.create("count", [
2299
- import_kysely7.ValueNode.createImmediate(1)
2432
+ const count = import_kysely17.FunctionNode.create("count", [
2433
+ import_kysely17.ValueNode.createImmediate(1)
2300
2434
  ]);
2301
- 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();
2435
+ const predicateResult = (0, import_ts_pattern18.match)(expr2.op).with("?", () => import_kysely17.BinaryOperationNode.create(count, import_kysely17.OperatorNode.create(">"), import_kysely17.ValueNode.createImmediate(0))).with("!", () => import_kysely17.BinaryOperationNode.create(count, import_kysely17.OperatorNode.create("="), import_kysely17.ValueNode.createImmediate(0))).with("^", () => import_kysely17.BinaryOperationNode.create(count, import_kysely17.OperatorNode.create("="), import_kysely17.ValueNode.createImmediate(0))).exhaustive();
2302
2436
  return this.transform(expr2.left, {
2303
2437
  ...context,
2304
- memberSelect: import_kysely7.SelectionNode.create(import_kysely7.AliasNode.create(predicateResult, import_kysely7.IdentifierNode.create("$t"))),
2438
+ memberSelect: import_kysely17.SelectionNode.create(import_kysely17.AliasNode.create(predicateResult, import_kysely17.IdentifierNode.create("$t"))),
2305
2439
  memberFilter: predicateFilter
2306
2440
  });
2307
2441
  }
@@ -2326,7 +2460,7 @@ var ExpressionTransformer = class {
2326
2460
  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`);
2327
2461
  }
2328
2462
  const idFields = Object.values(authModel.fields).filter((f) => f.id).map((f) => f.name);
2329
- (0, import_common_helpers6.invariant)(idFields.length > 0, "auth type model must have at least one id field");
2463
+ (0, import_common_helpers14.invariant)(idFields.length > 0, "auth type model must have at least one id field");
2330
2464
  const conditions = idFields.map((fieldName) => ExpressionUtils.binary(ExpressionUtils.member(authExpr, [
2331
2465
  fieldName
2332
2466
  ]), "==", this.makeOrAppendMember(other, fieldName)));
@@ -2355,16 +2489,16 @@ var ExpressionTransformer = class {
2355
2489
  } else if (value === false) {
2356
2490
  return falseNode(this.dialect);
2357
2491
  } else {
2358
- return import_kysely7.ValueNode.create(this.dialect.transformPrimitive(value, type, false) ?? null);
2492
+ return import_kysely17.ValueNode.create(this.dialect.transformPrimitive(value, type, false) ?? null);
2359
2493
  }
2360
2494
  }
2361
2495
  _unary(expr2, context) {
2362
- (0, import_common_helpers6.invariant)(expr2.op === "!", 'only "!" operator is supported');
2496
+ (0, import_common_helpers14.invariant)(expr2.op === "!", 'only "!" operator is supported');
2363
2497
  return logicalNot(this.dialect, this.transform(expr2.operand, context));
2364
2498
  }
2365
2499
  transformOperator(op) {
2366
- const mappedOp = (0, import_ts_pattern7.match)(op).with("==", () => "=").otherwise(() => op);
2367
- return import_kysely7.OperatorNode.create(mappedOp);
2500
+ const mappedOp = (0, import_ts_pattern18.match)(op).with("==", () => "=").otherwise(() => op);
2501
+ return import_kysely17.OperatorNode.create(mappedOp);
2368
2502
  }
2369
2503
  _call(expr2, context) {
2370
2504
  const result = this.transformCall(expr2, context);
@@ -2375,7 +2509,7 @@ var ExpressionTransformer = class {
2375
2509
  if (!func) {
2376
2510
  throw new QueryError(`Function not implemented: ${expr2.function}`);
2377
2511
  }
2378
- const eb = (0, import_kysely7.expressionBuilder)();
2512
+ const eb = (0, import_kysely17.expressionBuilder)();
2379
2513
  return func(eb, (expr2.args ?? []).map((arg) => this.transformCallArg(eb, arg, context)), {
2380
2514
  client: this.client,
2381
2515
  dialect: this.dialect,
@@ -2407,7 +2541,7 @@ var ExpressionTransformer = class {
2407
2541
  return this.transformCall(arg, context);
2408
2542
  }
2409
2543
  if (this.isAuthMember(arg)) {
2410
- const valNode = this.valueMemberAccess(context.auth, arg, this.authType);
2544
+ const valNode = this.valueMemberAccess(this.auth, arg, this.authType);
2411
2545
  return valNode ? eb.val(valNode.value) : eb.val(null);
2412
2546
  }
2413
2547
  throw new InternalError(`Unsupported argument expression: ${arg.kind}`);
@@ -2416,7 +2550,12 @@ var ExpressionTransformer = class {
2416
2550
  if (this.isAuthCall(expr2.receiver)) {
2417
2551
  return this.valueMemberAccess(this.auth, expr2, this.authType);
2418
2552
  }
2419
- (0, import_common_helpers6.invariant)(ExpressionUtils.isField(expr2.receiver) || ExpressionUtils.isThis(expr2.receiver), 'expect receiver to be field expression or "this"');
2553
+ if (isBeforeInvocation(expr2.receiver)) {
2554
+ (0, import_common_helpers14.invariant)(context.operation === "post-update", "before() can only be used in post-update policy");
2555
+ (0, import_common_helpers14.invariant)(expr2.members.length === 1, "before() can only be followed by a scalar field access");
2556
+ return import_kysely17.ReferenceNode.create(import_kysely17.ColumnNode.create(expr2.members[0]), import_kysely17.TableNode.create("$before"));
2557
+ }
2558
+ (0, import_common_helpers14.invariant)(ExpressionUtils.isField(expr2.receiver) || ExpressionUtils.isThis(expr2.receiver), 'expect receiver to be field expression or "this"');
2420
2559
  let members = expr2.members;
2421
2560
  let receiver;
2422
2561
  const { memberFilter, memberSelect, ...restContext } = context;
@@ -2431,7 +2570,7 @@ var ExpressionTransformer = class {
2431
2570
  } else {
2432
2571
  receiver = this.transform(expr2.receiver, restContext);
2433
2572
  }
2434
- (0, import_common_helpers6.invariant)(import_kysely7.SelectQueryNode.is(receiver), "expected receiver to be select query");
2573
+ (0, import_common_helpers14.invariant)(import_kysely17.SelectQueryNode.is(receiver), "expected receiver to be select query");
2435
2574
  let startType;
2436
2575
  if (ExpressionUtils.isField(expr2.receiver)) {
2437
2576
  const receiverField = requireField(this.schema, context.model, expr2.receiver.field);
@@ -2460,11 +2599,10 @@ var ExpressionTransformer = class {
2460
2599
  alias: void 0
2461
2600
  });
2462
2601
  if (currNode) {
2463
- (0, import_common_helpers6.invariant)(import_kysely7.SelectQueryNode.is(currNode), "expected select query node");
2464
2602
  currNode = {
2465
2603
  ...relation,
2466
2604
  selections: [
2467
- import_kysely7.SelectionNode.create(import_kysely7.AliasNode.create(currNode, import_kysely7.IdentifierNode.create(members[i + 1])))
2605
+ import_kysely17.SelectionNode.create(import_kysely17.AliasNode.create(currNode, import_kysely17.IdentifierNode.create(members[i + 1])))
2468
2606
  ]
2469
2607
  };
2470
2608
  } else {
@@ -2477,21 +2615,21 @@ var ExpressionTransformer = class {
2477
2615
  };
2478
2616
  }
2479
2617
  } else {
2480
- (0, import_common_helpers6.invariant)(i === members.length - 1, "plain field access must be the last segment");
2481
- (0, import_common_helpers6.invariant)(!currNode, "plain field access must be the last segment");
2482
- currNode = import_kysely7.ColumnNode.create(member);
2618
+ (0, import_common_helpers14.invariant)(i === members.length - 1, "plain field access must be the last segment");
2619
+ (0, import_common_helpers14.invariant)(!currNode, "plain field access must be the last segment");
2620
+ currNode = import_kysely17.ColumnNode.create(member);
2483
2621
  }
2484
2622
  }
2485
2623
  return {
2486
2624
  ...receiver,
2487
2625
  selections: [
2488
- import_kysely7.SelectionNode.create(import_kysely7.AliasNode.create(currNode, import_kysely7.IdentifierNode.create("$t")))
2626
+ import_kysely17.SelectionNode.create(import_kysely17.AliasNode.create(currNode, import_kysely17.IdentifierNode.create("$t")))
2489
2627
  ]
2490
2628
  };
2491
2629
  }
2492
2630
  valueMemberAccess(receiver, expr2, receiverType) {
2493
2631
  if (!receiver) {
2494
- return import_kysely7.ValueNode.createImmediate(null);
2632
+ return import_kysely17.ValueNode.createImmediate(null);
2495
2633
  }
2496
2634
  if (expr2.members.length !== 1) {
2497
2635
  throw new Error(`Only single member access is supported`);
@@ -2510,25 +2648,25 @@ var ExpressionTransformer = class {
2510
2648
  const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, fromModel, field);
2511
2649
  let condition;
2512
2650
  if (ownedByModel) {
2513
- 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)))));
2651
+ condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => import_kysely17.BinaryOperationNode.create(import_kysely17.ReferenceNode.create(import_kysely17.ColumnNode.create(fk), import_kysely17.TableNode.create(context.alias ?? fromModel)), import_kysely17.OperatorNode.create("="), import_kysely17.ReferenceNode.create(import_kysely17.ColumnNode.create(pk), import_kysely17.TableNode.create(relationModel)))));
2514
2652
  } else {
2515
- 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)))));
2653
+ condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => import_kysely17.BinaryOperationNode.create(import_kysely17.ReferenceNode.create(import_kysely17.ColumnNode.create(pk), import_kysely17.TableNode.create(context.alias ?? fromModel)), import_kysely17.OperatorNode.create("="), import_kysely17.ReferenceNode.create(import_kysely17.ColumnNode.create(fk), import_kysely17.TableNode.create(relationModel)))));
2516
2654
  }
2517
2655
  return {
2518
2656
  kind: "SelectQueryNode",
2519
- from: import_kysely7.FromNode.create([
2520
- import_kysely7.TableNode.create(relationModel)
2657
+ from: import_kysely17.FromNode.create([
2658
+ import_kysely17.TableNode.create(relationModel)
2521
2659
  ]),
2522
- where: import_kysely7.WhereNode.create(condition)
2660
+ where: import_kysely17.WhereNode.create(condition)
2523
2661
  };
2524
2662
  }
2525
2663
  transformManyToManyRelationAccess(m2m, context) {
2526
- const eb = (0, import_kysely7.expressionBuilder)();
2664
+ const eb = (0, import_kysely17.expressionBuilder)();
2527
2665
  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}`));
2528
2666
  return relationQuery.toOperationNode();
2529
2667
  }
2530
2668
  createColumnRef(column, context) {
2531
- return import_kysely7.ReferenceNode.create(import_kysely7.ColumnNode.create(column), import_kysely7.TableNode.create(context.alias ?? context.model));
2669
+ return import_kysely17.ReferenceNode.create(import_kysely17.ColumnNode.create(column), import_kysely17.TableNode.create(context.alias ?? context.model));
2532
2670
  }
2533
2671
  isAuthCall(value) {
2534
2672
  return ExpressionUtils.isCall(value) && value.function === "auth";
@@ -2537,7 +2675,7 @@ var ExpressionTransformer = class {
2537
2675
  return ExpressionUtils.isMember(expr2) && this.isAuthCall(expr2.receiver);
2538
2676
  }
2539
2677
  isNullNode(node) {
2540
- return import_kysely7.ValueNode.is(node) && node.value === null;
2678
+ return import_kysely17.ValueNode.is(node) && node.value === null;
2541
2679
  }
2542
2680
  buildLogicalNot(result) {
2543
2681
  return ExpressionUtils.unary("!", result);
@@ -2635,7 +2773,7 @@ _ts_decorate([
2635
2773
  ], ExpressionTransformer.prototype, "_member", null);
2636
2774
 
2637
2775
  // src/plugins/policy/policy-handler.ts
2638
- var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2776
+ var PolicyHandler = class extends import_kysely18.OperationNodeTransformer {
2639
2777
  static {
2640
2778
  __name(this, "PolicyHandler");
2641
2779
  }
@@ -2656,7 +2794,7 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2656
2794
  return proceed(this.transformNode(node));
2657
2795
  }
2658
2796
  const { mutationModel } = this.getMutationModel(node);
2659
- if (import_kysely8.InsertQueryNode.is(node)) {
2797
+ if (import_kysely18.InsertQueryNode.is(node)) {
2660
2798
  const isManyToManyJoinTable = this.isManyToManyJoinTable(mutationModel);
2661
2799
  let needCheckPreCreate = true;
2662
2800
  if (!isManyToManyJoinTable) {
@@ -2671,9 +2809,45 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2671
2809
  await this.enforcePreCreatePolicy(node, mutationModel, isManyToManyJoinTable, proceed);
2672
2810
  }
2673
2811
  }
2812
+ const hasPostUpdatePolicies = import_kysely18.UpdateQueryNode.is(node) && this.hasPostUpdatePolicies(mutationModel);
2813
+ let beforeUpdateInfo;
2814
+ if (hasPostUpdatePolicies) {
2815
+ beforeUpdateInfo = await this.loadBeforeUpdateEntities(mutationModel, node.where, proceed);
2816
+ }
2674
2817
  const result = await proceed(this.transformNode(node));
2818
+ if (hasPostUpdatePolicies && result.rows.length > 0) {
2819
+ const idConditions = this.buildIdConditions(mutationModel, result.rows);
2820
+ const postUpdateFilter = this.buildPolicyFilter(mutationModel, void 0, "post-update");
2821
+ const eb = (0, import_kysely18.expressionBuilder)();
2822
+ const beforeUpdateTable = beforeUpdateInfo ? {
2823
+ kind: "SelectQueryNode",
2824
+ from: import_kysely18.FromNode.create([
2825
+ import_kysely18.ParensNode.create(import_kysely18.ValuesNode.create(beforeUpdateInfo.rows.map((r) => import_kysely18.PrimitiveValueListNode.create(beforeUpdateInfo.fields.map((f) => r[f])))))
2826
+ ]),
2827
+ selections: beforeUpdateInfo.fields.map((name, index) => {
2828
+ const def = requireField(this.client.$schema, mutationModel, name);
2829
+ const castedColumnRef = import_kysely18.sql`CAST(${eb.ref(`column${index + 1}`)} as ${import_kysely18.sql.raw(this.dialect.getFieldSqlType(def))})`.as(name);
2830
+ return import_kysely18.SelectionNode.create(castedColumnRef.toOperationNode());
2831
+ })
2832
+ } : void 0;
2833
+ const postUpdateQuery = eb.selectFrom(mutationModel).select(() => [
2834
+ eb(eb.fn("COUNT", [
2835
+ eb.lit(1)
2836
+ ]), "=", result.rows.length).as("$condition")
2837
+ ]).where(() => new import_kysely18.ExpressionWrapper(conjunction(this.dialect, [
2838
+ idConditions,
2839
+ postUpdateFilter
2840
+ ]))).$if(!!beforeUpdateInfo, (qb) => qb.leftJoin(() => new import_kysely18.ExpressionWrapper(beforeUpdateTable).as("$before"), (join) => {
2841
+ const idFields = requireIdFields(this.client.$schema, mutationModel);
2842
+ return idFields.reduce((acc, f) => acc.onRef(`${mutationModel}.${f}`, "=", `$before.${f}`), join);
2843
+ }));
2844
+ const postUpdateResult = await proceed(postUpdateQuery.toOperationNode());
2845
+ if (!postUpdateResult.rows[0]?.$condition) {
2846
+ throw new RejectedByPolicyError(mutationModel, RejectedByPolicyReason.NO_ACCESS, "some or all updated rows failed to pass post-update policy check");
2847
+ }
2848
+ }
2675
2849
  if (!node.returning || this.onlyReturningId(node)) {
2676
- return result;
2850
+ return this.postProcessMutationResult(result, node);
2677
2851
  } else {
2678
2852
  const readBackResult = await this.processReadBack(node, result, proceed);
2679
2853
  if (readBackResult.rows.length !== result.rows.length) {
@@ -2682,12 +2856,74 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2682
2856
  return readBackResult;
2683
2857
  }
2684
2858
  }
2859
+ // correction to kysely mutation result may be needed because we might have added
2860
+ // returning clause to the query and caused changes to the result shape
2861
+ postProcessMutationResult(result, node) {
2862
+ if (node.returning) {
2863
+ return result;
2864
+ } else {
2865
+ return {
2866
+ ...result,
2867
+ rows: [],
2868
+ numAffectedRows: result.numAffectedRows ?? BigInt(result.rows.length)
2869
+ };
2870
+ }
2871
+ }
2872
+ hasPostUpdatePolicies(model) {
2873
+ const policies = this.getModelPolicies(model, "post-update");
2874
+ return policies.length > 0;
2875
+ }
2876
+ async loadBeforeUpdateEntities(model, where, proceed) {
2877
+ const beforeUpdateAccessFields = this.getFieldsAccessForBeforeUpdatePolicies(model);
2878
+ if (!beforeUpdateAccessFields || beforeUpdateAccessFields.length === 0) {
2879
+ return void 0;
2880
+ }
2881
+ const query = {
2882
+ kind: "SelectQueryNode",
2883
+ from: import_kysely18.FromNode.create([
2884
+ import_kysely18.TableNode.create(model)
2885
+ ]),
2886
+ where,
2887
+ selections: [
2888
+ ...beforeUpdateAccessFields.map((f) => import_kysely18.SelectionNode.create(import_kysely18.ColumnNode.create(f)))
2889
+ ]
2890
+ };
2891
+ const result = await proceed(query);
2892
+ return {
2893
+ fields: beforeUpdateAccessFields,
2894
+ rows: result.rows
2895
+ };
2896
+ }
2897
+ getFieldsAccessForBeforeUpdatePolicies(model) {
2898
+ const policies = this.getModelPolicies(model, "post-update");
2899
+ if (policies.length === 0) {
2900
+ return void 0;
2901
+ }
2902
+ const fields = /* @__PURE__ */ new Set();
2903
+ const fieldCollector = new class extends ExpressionVisitor {
2904
+ visitMember(e) {
2905
+ if (isBeforeInvocation(e.receiver)) {
2906
+ (0, import_common_helpers15.invariant)(e.members.length === 1, "before() can only be followed by a scalar field access");
2907
+ fields.add(e.members[0]);
2908
+ }
2909
+ super.visitMember(e);
2910
+ }
2911
+ }();
2912
+ for (const policy of policies) {
2913
+ fieldCollector.visit(policy.condition);
2914
+ }
2915
+ if (fields.size === 0) {
2916
+ return void 0;
2917
+ }
2918
+ requireIdFields(this.client.$schema, model).forEach((f) => fields.add(f));
2919
+ return Array.from(fields).sort();
2920
+ }
2685
2921
  // #region overrides
2686
2922
  transformSelectQuery(node) {
2687
2923
  let whereNode = this.transformNode(node.where);
2688
2924
  const policyFilter = this.createPolicyFilterForFrom(node.from);
2689
2925
  if (policyFilter) {
2690
- whereNode = import_kysely8.WhereNode.create(whereNode?.where ? conjunction(this.dialect, [
2926
+ whereNode = import_kysely18.WhereNode.create(whereNode?.where ? conjunction(this.dialect, [
2691
2927
  whereNode.where,
2692
2928
  policyFilter
2693
2929
  ]) : policyFilter);
@@ -2709,17 +2945,17 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2709
2945
  const filter = this.buildPolicyFilter(table.model, table.alias, "read");
2710
2946
  const nestedSelect = {
2711
2947
  kind: "SelectQueryNode",
2712
- from: import_kysely8.FromNode.create([
2948
+ from: import_kysely18.FromNode.create([
2713
2949
  node.table
2714
2950
  ]),
2715
2951
  selections: [
2716
- import_kysely8.SelectionNode.createSelectAll()
2952
+ import_kysely18.SelectionNode.createSelectAll()
2717
2953
  ],
2718
- where: import_kysely8.WhereNode.create(filter)
2954
+ where: import_kysely18.WhereNode.create(filter)
2719
2955
  };
2720
2956
  return {
2721
2957
  ...node,
2722
- table: import_kysely8.AliasNode.create(import_kysely8.ParensNode.create(nestedSelect), import_kysely8.IdentifierNode.create(table.alias ?? table.model))
2958
+ table: import_kysely18.AliasNode.create(import_kysely18.ParensNode.create(nestedSelect), import_kysely18.IdentifierNode.create(table.alias ?? table.model))
2723
2959
  };
2724
2960
  }
2725
2961
  transformInsertQuery(node) {
@@ -2730,7 +2966,7 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2730
2966
  if (onConflict.updateWhere) {
2731
2967
  onConflict = {
2732
2968
  ...onConflict,
2733
- updateWhere: import_kysely8.WhereNode.create(conjunction(this.dialect, [
2969
+ updateWhere: import_kysely18.WhereNode.create(conjunction(this.dialect, [
2734
2970
  onConflict.updateWhere.where,
2735
2971
  filter
2736
2972
  ]))
@@ -2738,7 +2974,7 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2738
2974
  } else {
2739
2975
  onConflict = {
2740
2976
  ...onConflict,
2741
- updateWhere: import_kysely8.WhereNode.create(filter)
2977
+ updateWhere: import_kysely18.WhereNode.create(filter)
2742
2978
  };
2743
2979
  }
2744
2980
  }
@@ -2747,19 +2983,16 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2747
2983
  onConflict
2748
2984
  } : node;
2749
2985
  const result = super.transformInsertQuery(processedNode);
2750
- if (!node.returning) {
2751
- return result;
2752
- }
2753
- if (this.onlyReturningId(node)) {
2754
- return result;
2755
- } else {
2986
+ let returning = result.returning;
2987
+ if (returning) {
2756
2988
  const { mutationModel } = this.getMutationModel(node);
2757
2989
  const idFields = requireIdFields(this.client.$schema, mutationModel);
2758
- return {
2759
- ...result,
2760
- returning: import_kysely8.ReturningNode.create(idFields.map((field) => import_kysely8.SelectionNode.create(import_kysely8.ColumnNode.create(field))))
2761
- };
2990
+ returning = import_kysely18.ReturningNode.create(idFields.map((f) => import_kysely18.SelectionNode.create(import_kysely18.ColumnNode.create(f))));
2762
2991
  }
2992
+ return {
2993
+ ...result,
2994
+ returning
2995
+ };
2763
2996
  }
2764
2997
  transformUpdateQuery(node) {
2765
2998
  const result = super.transformUpdateQuery(node);
@@ -2774,12 +3007,18 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2774
3007
  ]);
2775
3008
  }
2776
3009
  }
3010
+ let returning = result.returning;
3011
+ if (returning || this.hasPostUpdatePolicies(mutationModel)) {
3012
+ const idFields = requireIdFields(this.client.$schema, mutationModel);
3013
+ returning = import_kysely18.ReturningNode.create(idFields.map((f) => import_kysely18.SelectionNode.create(import_kysely18.ColumnNode.create(f))));
3014
+ }
2777
3015
  return {
2778
3016
  ...result,
2779
- where: import_kysely8.WhereNode.create(result.where ? conjunction(this.dialect, [
3017
+ where: import_kysely18.WhereNode.create(result.where ? conjunction(this.dialect, [
2780
3018
  result.where.where,
2781
3019
  filter
2782
- ]) : filter)
3020
+ ]) : filter),
3021
+ returning
2783
3022
  };
2784
3023
  }
2785
3024
  transformDeleteQuery(node) {
@@ -2797,7 +3036,7 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2797
3036
  }
2798
3037
  return {
2799
3038
  ...result,
2800
- where: import_kysely8.WhereNode.create(result.where ? conjunction(this.dialect, [
3039
+ where: import_kysely18.WhereNode.create(result.where ? conjunction(this.dialect, [
2801
3040
  result.where.where,
2802
3041
  filter
2803
3042
  ]) : filter)
@@ -2811,6 +3050,14 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2811
3050
  }
2812
3051
  const { mutationModel } = this.getMutationModel(node);
2813
3052
  const idFields = requireIdFields(this.client.$schema, mutationModel);
3053
+ if (node.returning.selections.some((s) => import_kysely18.SelectAllNode.is(s.selection))) {
3054
+ const modelDef = requireModel(this.client.$schema, mutationModel);
3055
+ if (Object.keys(modelDef.fields).some((f) => !idFields.includes(f))) {
3056
+ return false;
3057
+ } else {
3058
+ return true;
3059
+ }
3060
+ }
2814
3061
  const collector = new ColumnCollector();
2815
3062
  const selectedColumns = collector.collect(node.returning);
2816
3063
  return selectedColumns.every((c) => idFields.includes(c));
@@ -2830,27 +3077,27 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2830
3077
  }
2831
3078
  async enforcePreCreatePolicyForManyToManyJoinTable(tableName, fields, values, proceed) {
2832
3079
  const m2m = this.resolveManyToManyJoinTable(tableName);
2833
- (0, import_common_helpers7.invariant)(m2m);
2834
- (0, import_common_helpers7.invariant)(fields.includes("A") && fields.includes("B"), "many-to-many join table must have A and B fk fields");
3080
+ (0, import_common_helpers15.invariant)(m2m);
3081
+ (0, import_common_helpers15.invariant)(fields.includes("A") && fields.includes("B"), "many-to-many join table must have A and B fk fields");
2835
3082
  const aIndex = fields.indexOf("A");
2836
3083
  const aNode = values[aIndex];
2837
3084
  const bIndex = fields.indexOf("B");
2838
3085
  const bNode = values[bIndex];
2839
- (0, import_common_helpers7.invariant)(import_kysely8.ValueNode.is(aNode) && import_kysely8.ValueNode.is(bNode), "A and B values must be ValueNode");
3086
+ (0, import_common_helpers15.invariant)(import_kysely18.ValueNode.is(aNode) && import_kysely18.ValueNode.is(bNode), "A and B values must be ValueNode");
2840
3087
  const aValue = aNode.value;
2841
3088
  const bValue = bNode.value;
2842
- (0, import_common_helpers7.invariant)(aValue !== null && aValue !== void 0, "A value cannot be null or undefined");
2843
- (0, import_common_helpers7.invariant)(bValue !== null && bValue !== void 0, "B value cannot be null or undefined");
2844
- const eb = (0, import_kysely8.expressionBuilder)();
3089
+ (0, import_common_helpers15.invariant)(aValue !== null && aValue !== void 0, "A value cannot be null or undefined");
3090
+ (0, import_common_helpers15.invariant)(bValue !== null && bValue !== void 0, "B value cannot be null or undefined");
3091
+ const eb = (0, import_kysely18.expressionBuilder)();
2845
3092
  const filterA = this.buildPolicyFilter(m2m.firstModel, void 0, "update");
2846
- const queryA = eb.selectFrom(m2m.firstModel).where(eb(eb.ref(`${m2m.firstModel}.${m2m.firstIdField}`), "=", aValue)).select(() => new import_kysely8.ExpressionWrapper(filterA).as("$t"));
3093
+ const queryA = eb.selectFrom(m2m.firstModel).where(eb(eb.ref(`${m2m.firstModel}.${m2m.firstIdField}`), "=", aValue)).select(() => new import_kysely18.ExpressionWrapper(filterA).as("$t"));
2847
3094
  const filterB = this.buildPolicyFilter(m2m.secondModel, void 0, "update");
2848
- const queryB = eb.selectFrom(m2m.secondModel).where(eb(eb.ref(`${m2m.secondModel}.${m2m.secondIdField}`), "=", bValue)).select(() => new import_kysely8.ExpressionWrapper(filterB).as("$t"));
3095
+ const queryB = eb.selectFrom(m2m.secondModel).where(eb(eb.ref(`${m2m.secondModel}.${m2m.secondIdField}`), "=", bValue)).select(() => new import_kysely18.ExpressionWrapper(filterB).as("$t"));
2849
3096
  const queryNode = {
2850
3097
  kind: "SelectQueryNode",
2851
3098
  selections: [
2852
- import_kysely8.SelectionNode.create(import_kysely8.AliasNode.create(queryA.toOperationNode(), import_kysely8.IdentifierNode.create("$conditionA"))),
2853
- import_kysely8.SelectionNode.create(import_kysely8.AliasNode.create(queryB.toOperationNode(), import_kysely8.IdentifierNode.create("$conditionB")))
3099
+ import_kysely18.SelectionNode.create(import_kysely18.AliasNode.create(queryA.toOperationNode(), import_kysely18.IdentifierNode.create("$conditionA"))),
3100
+ import_kysely18.SelectionNode.create(import_kysely18.AliasNode.create(queryB.toOperationNode(), import_kysely18.IdentifierNode.create("$conditionB")))
2854
3101
  ]
2855
3102
  };
2856
3103
  const result = await proceed(queryNode);
@@ -2869,34 +3116,34 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2869
3116
  if (index >= 0) {
2870
3117
  allValues.push(values[index]);
2871
3118
  } else {
2872
- allValues.push(import_kysely8.ValueNode.createImmediate(null));
3119
+ allValues.push(import_kysely18.ValueNode.createImmediate(null));
2873
3120
  }
2874
3121
  }
2875
- const eb = (0, import_kysely8.expressionBuilder)();
3122
+ const eb = (0, import_kysely18.expressionBuilder)();
2876
3123
  const constTable = {
2877
3124
  kind: "SelectQueryNode",
2878
- from: import_kysely8.FromNode.create([
2879
- import_kysely8.AliasNode.create(import_kysely8.ParensNode.create(import_kysely8.ValuesNode.create([
2880
- import_kysely8.ValueListNode.create(allValues)
2881
- ])), import_kysely8.IdentifierNode.create("$t"))
3125
+ from: import_kysely18.FromNode.create([
3126
+ import_kysely18.AliasNode.create(import_kysely18.ParensNode.create(import_kysely18.ValuesNode.create([
3127
+ import_kysely18.ValueListNode.create(allValues)
3128
+ ])), import_kysely18.IdentifierNode.create("$t"))
2882
3129
  ]),
2883
3130
  selections: allFields.map(([name, def], index) => {
2884
- const castedColumnRef = import_kysely8.sql`CAST(${eb.ref(`column${index + 1}`)} as ${import_kysely8.sql.raw(this.dialect.getFieldSqlType(def))})`.as(name);
2885
- return import_kysely8.SelectionNode.create(castedColumnRef.toOperationNode());
3131
+ const castedColumnRef = import_kysely18.sql`CAST(${eb.ref(`column${index + 1}`)} as ${import_kysely18.sql.raw(this.dialect.getFieldSqlType(def))})`.as(name);
3132
+ return import_kysely18.SelectionNode.create(castedColumnRef.toOperationNode());
2886
3133
  })
2887
3134
  };
2888
3135
  const filter = this.buildPolicyFilter(model, void 0, "create");
2889
3136
  const preCreateCheck = {
2890
3137
  kind: "SelectQueryNode",
2891
- from: import_kysely8.FromNode.create([
2892
- import_kysely8.AliasNode.create(constTable, import_kysely8.IdentifierNode.create(model))
3138
+ from: import_kysely18.FromNode.create([
3139
+ import_kysely18.AliasNode.create(constTable, import_kysely18.IdentifierNode.create(model))
2893
3140
  ]),
2894
3141
  selections: [
2895
- import_kysely8.SelectionNode.create(import_kysely8.AliasNode.create(import_kysely8.BinaryOperationNode.create(import_kysely8.FunctionNode.create("COUNT", [
2896
- import_kysely8.ValueNode.createImmediate(1)
2897
- ]), import_kysely8.OperatorNode.create(">"), import_kysely8.ValueNode.createImmediate(0)), import_kysely8.IdentifierNode.create("$condition")))
3142
+ import_kysely18.SelectionNode.create(import_kysely18.AliasNode.create(import_kysely18.BinaryOperationNode.create(import_kysely18.FunctionNode.create("COUNT", [
3143
+ import_kysely18.ValueNode.createImmediate(1)
3144
+ ]), import_kysely18.OperatorNode.create(">"), import_kysely18.ValueNode.createImmediate(0)), import_kysely18.IdentifierNode.create("$condition")))
2898
3145
  ],
2899
- where: import_kysely8.WhereNode.create(filter)
3146
+ where: import_kysely18.WhereNode.create(filter)
2900
3147
  };
2901
3148
  const result = await proceed(preCreateCheck);
2902
3149
  if (!result.rows[0]?.$condition) {
@@ -2904,9 +3151,9 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2904
3151
  }
2905
3152
  }
2906
3153
  unwrapCreateValueRows(node, model, fields, isManyToManyJoinTable) {
2907
- if (import_kysely8.ValuesNode.is(node)) {
3154
+ if (import_kysely18.ValuesNode.is(node)) {
2908
3155
  return node.values.map((v) => this.unwrapCreateValueRow(v.values, model, fields, isManyToManyJoinTable));
2909
- } else if (import_kysely8.PrimitiveValueListNode.is(node)) {
3156
+ } else if (import_kysely18.PrimitiveValueListNode.is(node)) {
2910
3157
  return [
2911
3158
  this.unwrapCreateValueRow(node.values, model, fields, isManyToManyJoinTable)
2912
3159
  ];
@@ -2915,15 +3162,15 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2915
3162
  }
2916
3163
  }
2917
3164
  unwrapCreateValueRow(data, model, fields, isImplicitManyToManyJoinTable) {
2918
- (0, import_common_helpers7.invariant)(data.length === fields.length, "data length must match fields length");
3165
+ (0, import_common_helpers15.invariant)(data.length === fields.length, "data length must match fields length");
2919
3166
  const result = [];
2920
3167
  for (let i = 0; i < data.length; i++) {
2921
3168
  const item = data[i];
2922
3169
  if (typeof item === "object" && item && "kind" in item) {
2923
3170
  const fieldDef = requireField(this.client.$schema, model, fields[i]);
2924
- (0, import_common_helpers7.invariant)(item.kind === "ValueNode", "expecting a ValueNode");
3171
+ (0, import_common_helpers15.invariant)(item.kind === "ValueNode", "expecting a ValueNode");
2925
3172
  result.push({
2926
- node: import_kysely8.ValueNode.create(this.dialect.transformPrimitive(item.value, fieldDef.type, !!fieldDef.array)),
3173
+ node: import_kysely18.ValueNode.create(this.dialect.transformPrimitive(item.value, fieldDef.type, !!fieldDef.array)),
2927
3174
  raw: item.value
2928
3175
  });
2929
3176
  } else {
@@ -2934,12 +3181,12 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2934
3181
  }
2935
3182
  if (Array.isArray(value)) {
2936
3183
  result.push({
2937
- node: import_kysely8.RawNode.createWithSql(this.dialect.buildArrayLiteralSQL(value)),
3184
+ node: import_kysely18.RawNode.createWithSql(this.dialect.buildArrayLiteralSQL(value)),
2938
3185
  raw: value
2939
3186
  });
2940
3187
  } else {
2941
3188
  result.push({
2942
- node: import_kysely8.ValueNode.create(value),
3189
+ node: import_kysely18.ValueNode.create(value),
2943
3190
  raw: value
2944
3191
  });
2945
3192
  }
@@ -2980,10 +3227,10 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2980
3227
  const policyFilter = this.buildPolicyFilter(mutationModel, void 0, "read");
2981
3228
  const select = {
2982
3229
  kind: "SelectQueryNode",
2983
- from: import_kysely8.FromNode.create([
2984
- import_kysely8.TableNode.create(mutationModel)
3230
+ from: import_kysely18.FromNode.create([
3231
+ import_kysely18.TableNode.create(mutationModel)
2985
3232
  ]),
2986
- where: import_kysely8.WhereNode.create(conjunction(this.dialect, [
3233
+ where: import_kysely18.WhereNode.create(conjunction(this.dialect, [
2987
3234
  idConditions,
2988
3235
  policyFilter
2989
3236
  ])),
@@ -2994,13 +3241,13 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
2994
3241
  }
2995
3242
  buildIdConditions(table, rows) {
2996
3243
  const idFields = requireIdFields(this.client.$schema, table);
2997
- 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]))))));
3244
+ return disjunction(this.dialect, rows.map((row) => conjunction(this.dialect, idFields.map((field) => import_kysely18.BinaryOperationNode.create(import_kysely18.ReferenceNode.create(import_kysely18.ColumnNode.create(field), import_kysely18.TableNode.create(table)), import_kysely18.OperatorNode.create("="), import_kysely18.ValueNode.create(row[field]))))));
2998
3245
  }
2999
3246
  getMutationModel(node) {
3000
- const r = (0, import_ts_pattern8.match)(node).when(import_kysely8.InsertQueryNode.is, (node2) => ({
3247
+ const r = (0, import_ts_pattern19.match)(node).when(import_kysely18.InsertQueryNode.is, (node2) => ({
3001
3248
  mutationModel: getTableName(node2.into),
3002
3249
  alias: void 0
3003
- })).when(import_kysely8.UpdateQueryNode.is, (node2) => {
3250
+ })).when(import_kysely18.UpdateQueryNode.is, (node2) => {
3004
3251
  if (!node2.table) {
3005
3252
  throw new QueryError("Update query must have a table");
3006
3253
  }
@@ -3009,7 +3256,7 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
3009
3256
  mutationModel: r2.model,
3010
3257
  alias: r2.alias
3011
3258
  } : void 0;
3012
- }).when(import_kysely8.DeleteQueryNode.is, (node2) => {
3259
+ }).when(import_kysely18.DeleteQueryNode.is, (node2) => {
3013
3260
  if (node2.from.froms.length !== 1) {
3014
3261
  throw new QueryError("Only one from table is supported for delete");
3015
3262
  }
@@ -3025,10 +3272,10 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
3025
3272
  return r;
3026
3273
  }
3027
3274
  isCrudQueryNode(node) {
3028
- return import_kysely8.SelectQueryNode.is(node) || import_kysely8.InsertQueryNode.is(node) || import_kysely8.UpdateQueryNode.is(node) || import_kysely8.DeleteQueryNode.is(node);
3275
+ return import_kysely18.SelectQueryNode.is(node) || import_kysely18.InsertQueryNode.is(node) || import_kysely18.UpdateQueryNode.is(node) || import_kysely18.DeleteQueryNode.is(node);
3029
3276
  }
3030
3277
  isMutationQueryNode(node) {
3031
- return import_kysely8.InsertQueryNode.is(node) || import_kysely8.UpdateQueryNode.is(node) || import_kysely8.DeleteQueryNode.is(node);
3278
+ return import_kysely18.InsertQueryNode.is(node) || import_kysely18.UpdateQueryNode.is(node) || import_kysely18.DeleteQueryNode.is(node);
3032
3279
  }
3033
3280
  buildPolicyFilter(model, alias, operation) {
3034
3281
  const m2mFilter = this.getModelPolicyFilterForManyToManyJoinTable(model, alias, operation);
@@ -3036,40 +3283,41 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
3036
3283
  return m2mFilter;
3037
3284
  }
3038
3285
  const policies = this.getModelPolicies(model, operation);
3039
- if (policies.length === 0) {
3040
- return falseNode(this.dialect);
3041
- }
3042
3286
  const allows = policies.filter((policy) => policy.kind === "allow").map((policy) => this.compilePolicyCondition(model, alias, operation, policy));
3043
3287
  const denies = policies.filter((policy) => policy.kind === "deny").map((policy) => this.compilePolicyCondition(model, alias, operation, policy));
3044
3288
  let combinedPolicy;
3045
3289
  if (allows.length === 0) {
3046
- combinedPolicy = falseNode(this.dialect);
3290
+ if (operation === "post-update") {
3291
+ combinedPolicy = trueNode(this.dialect);
3292
+ } else {
3293
+ combinedPolicy = falseNode(this.dialect);
3294
+ }
3047
3295
  } else {
3048
3296
  combinedPolicy = disjunction(this.dialect, allows);
3049
- if (denies.length !== 0) {
3050
- const combinedDenies = conjunction(this.dialect, denies.map((d) => buildIsFalse(d, this.dialect)));
3051
- combinedPolicy = conjunction(this.dialect, [
3052
- combinedPolicy,
3053
- combinedDenies
3054
- ]);
3055
- }
3297
+ }
3298
+ if (denies.length !== 0) {
3299
+ const combinedDenies = conjunction(this.dialect, denies.map((d) => buildIsFalse(d, this.dialect)));
3300
+ combinedPolicy = conjunction(this.dialect, [
3301
+ combinedPolicy,
3302
+ combinedDenies
3303
+ ]);
3056
3304
  }
3057
3305
  return combinedPolicy;
3058
3306
  }
3059
3307
  extractTableName(node) {
3060
- if (import_kysely8.TableNode.is(node)) {
3308
+ if (import_kysely18.TableNode.is(node)) {
3061
3309
  return {
3062
3310
  model: node.table.identifier.name
3063
3311
  };
3064
3312
  }
3065
- if (import_kysely8.AliasNode.is(node)) {
3313
+ if (import_kysely18.AliasNode.is(node)) {
3066
3314
  const inner = this.extractTableName(node.node);
3067
3315
  if (!inner) {
3068
3316
  return void 0;
3069
3317
  }
3070
3318
  return {
3071
3319
  model: inner.model,
3072
- alias: import_kysely8.IdentifierNode.is(node.alias) ? node.alias.name : void 0
3320
+ alias: import_kysely18.IdentifierNode.is(node.alias) ? node.alias.name : void 0
3073
3321
  };
3074
3322
  } else {
3075
3323
  return void 0;
@@ -3099,16 +3347,15 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
3099
3347
  return new ExpressionTransformer(this.client).transform(policy.condition, {
3100
3348
  model,
3101
3349
  alias,
3102
- operation,
3103
- auth: this.client.$auth
3350
+ operation
3104
3351
  });
3105
3352
  }
3106
3353
  getModelPolicies(model, operation) {
3107
3354
  const modelDef = requireModel(this.client.$schema, model);
3108
3355
  const result = [];
3109
3356
  const extractOperations = /* @__PURE__ */ __name((expr2) => {
3110
- (0, import_common_helpers7.invariant)(ExpressionUtils.isLiteral(expr2), "expecting a literal");
3111
- (0, import_common_helpers7.invariant)(typeof expr2.value === "string", "expecting a string literal");
3357
+ (0, import_common_helpers15.invariant)(ExpressionUtils.isLiteral(expr2), "expecting a literal");
3358
+ (0, import_common_helpers15.invariant)(typeof expr2.value === "string", "expecting a string literal");
3112
3359
  return expr2.value.split(",").filter((v) => !!v).map((v) => v.trim());
3113
3360
  }, "extractOperations");
3114
3361
  if (modelDef.attributes) {
@@ -3116,7 +3363,7 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
3116
3363
  kind: attr.name === "@@allow" ? "allow" : "deny",
3117
3364
  operations: extractOperations(attr.args[0].value),
3118
3365
  condition: attr.args[1].value
3119
- })).filter((policy) => policy.operations.includes("all") || policy.operations.includes(operation)));
3366
+ })).filter((policy) => operation !== "post-update" && policy.operations.includes("all") || policy.operations.includes(operation)));
3120
3367
  }
3121
3368
  return result;
3122
3369
  }
@@ -3137,7 +3384,7 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
3137
3384
  ].sort(this.manyToManySorter);
3138
3385
  const firstIdFields = requireIdFields(this.client.$schema, sortedRecord[0].model);
3139
3386
  const secondIdFields = requireIdFields(this.client.$schema, sortedRecord[1].model);
3140
- (0, import_common_helpers7.invariant)(firstIdFields.length === 1 && secondIdFields.length === 1, "only single-field id is supported for implicit many-to-many join table");
3387
+ (0, import_common_helpers15.invariant)(firstIdFields.length === 1 && secondIdFields.length === 1, "only single-field id is supported for implicit many-to-many join table");
3141
3388
  return {
3142
3389
  firstModel: sortedRecord[0].model,
3143
3390
  firstField: sortedRecord[0].field,
@@ -3163,10 +3410,10 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
3163
3410
  return void 0;
3164
3411
  }
3165
3412
  const checkForOperation = operation === "read" ? "read" : "update";
3166
- const eb = (0, import_kysely8.expressionBuilder)();
3413
+ const eb = (0, import_kysely18.expressionBuilder)();
3167
3414
  const joinTable = alias ?? tableName;
3168
- 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"));
3169
- 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"));
3415
+ const aQuery = eb.selectFrom(m2m.firstModel).whereRef(`${m2m.firstModel}.${m2m.firstIdField}`, "=", `${joinTable}.A`).select(() => new import_kysely18.ExpressionWrapper(this.buildPolicyFilter(m2m.firstModel, void 0, checkForOperation)).as("$conditionA"));
3416
+ const bQuery = eb.selectFrom(m2m.secondModel).whereRef(`${m2m.secondModel}.${m2m.secondIdField}`, "=", `${joinTable}.B`).select(() => new import_kysely18.ExpressionWrapper(this.buildPolicyFilter(m2m.secondModel, void 0, checkForOperation)).as("$conditionB"));
3170
3417
  return eb.and([
3171
3418
  aQuery,
3172
3419
  bQuery
@@ -3176,25 +3423,25 @@ var PolicyHandler = class extends import_kysely8.OperationNodeTransformer {
3176
3423
 
3177
3424
  // src/plugins/policy/functions.ts
3178
3425
  var check = /* @__PURE__ */ __name((eb, args, { client, model, modelAlias, operation }) => {
3179
- (0, import_common_helpers8.invariant)(args.length === 1 || args.length === 2, '"check" function requires 1 or 2 arguments');
3426
+ (0, import_common_helpers16.invariant)(args.length === 1 || args.length === 2, '"check" function requires 1 or 2 arguments');
3180
3427
  const arg1Node = args[0].toOperationNode();
3181
3428
  const arg2Node = args.length === 2 ? args[1].toOperationNode() : void 0;
3182
3429
  if (arg2Node) {
3183
- (0, import_common_helpers8.invariant)(import_kysely9.ValueNode.is(arg2Node) && typeof arg2Node.value === "string", '"operation" parameter must be a string literal when provided');
3184
- (0, import_common_helpers8.invariant)(CRUD.includes(arg2Node.value), '"operation" parameter must be one of "create", "read", "update", "delete"');
3430
+ (0, import_common_helpers16.invariant)(import_kysely19.ValueNode.is(arg2Node) && typeof arg2Node.value === "string", '"operation" parameter must be a string literal when provided');
3431
+ (0, import_common_helpers16.invariant)(CRUD.includes(arg2Node.value), '"operation" parameter must be one of "create", "read", "update", "delete"');
3185
3432
  }
3186
3433
  const fieldName = extractFieldName(arg1Node);
3187
- (0, import_common_helpers8.invariant)(fieldName, 'Failed to extract field name from the first argument of "check" function');
3434
+ (0, import_common_helpers16.invariant)(fieldName, 'Failed to extract field name from the first argument of "check" function');
3188
3435
  const fieldDef = requireField(client.$schema, model, fieldName);
3189
- (0, import_common_helpers8.invariant)(fieldDef.relation, `Field "${fieldName}" is not a relation field in model "${model}"`);
3190
- (0, import_common_helpers8.invariant)(!fieldDef.array, `Field "${fieldName}" is a to-many relation, which is not supported by "check"`);
3436
+ (0, import_common_helpers16.invariant)(fieldDef.relation, `Field "${fieldName}" is not a relation field in model "${model}"`);
3437
+ (0, import_common_helpers16.invariant)(!fieldDef.array, `Field "${fieldName}" is a to-many relation, which is not supported by "check"`);
3191
3438
  const relationModel = fieldDef.type;
3192
3439
  const op = arg2Node ? arg2Node.value : operation;
3193
3440
  const policyHandler = new PolicyHandler(client);
3194
3441
  const joinPairs = buildJoinPairs(client.$schema, model, modelAlias, fieldName, relationModel);
3195
3442
  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))));
3196
3443
  const policyCondition = policyHandler.buildPolicyFilter(relationModel, void 0, op);
3197
- const result = eb.selectFrom(relationModel).where(joinCondition).select(new import_kysely9.ExpressionWrapper(policyCondition).as("$condition"));
3444
+ const result = eb.selectFrom(relationModel).where(joinCondition).select(new import_kysely19.ExpressionWrapper(policyCondition).as("$condition"));
3198
3445
  return result;
3199
3446
  }, "check");
3200
3447
 
@@ -3217,18 +3464,9 @@ var PolicyPlugin = class {
3217
3464
  check
3218
3465
  };
3219
3466
  }
3220
- onKyselyQuery({
3221
- query,
3222
- client,
3223
- proceed
3224
- /*, transaction*/
3225
- }) {
3467
+ onKyselyQuery({ query, client, proceed }) {
3226
3468
  const handler = new PolicyHandler(client);
3227
- return handler.handle(
3228
- query,
3229
- proceed
3230
- /*, transaction*/
3231
- );
3469
+ return handler.handle(query, proceed);
3232
3470
  }
3233
3471
  };
3234
3472
  // Annotate the CommonJS export names for ESM import in node: