@zenstackhq/runtime 3.0.0-alpha.0 → 3.0.0-alpha.10

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.
Files changed (40) hide show
  1. package/dist/{contract-DguafRNB.d.cts → contract-BiU0iYAh.d.cts} +813 -709
  2. package/dist/{contract-DguafRNB.d.ts → contract-BiU0iYAh.d.ts} +813 -709
  3. package/dist/{utils/pg-utils.cjs → helpers.cjs} +8 -16
  4. package/dist/helpers.cjs.map +1 -0
  5. package/dist/helpers.d.cts +1 -0
  6. package/dist/helpers.d.ts +1 -0
  7. package/dist/helpers.js +6 -0
  8. package/dist/helpers.js.map +1 -0
  9. package/dist/index.cjs +517 -328
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +28 -6
  12. package/dist/index.d.ts +28 -6
  13. package/dist/index.js +466 -282
  14. package/dist/index.js.map +1 -1
  15. package/dist/plugins/policy.cjs +115 -104
  16. package/dist/plugins/policy.cjs.map +1 -1
  17. package/dist/plugins/policy.d.cts +2 -4
  18. package/dist/plugins/policy.d.ts +2 -4
  19. package/dist/plugins/policy.js +87 -66
  20. package/dist/plugins/policy.js.map +1 -1
  21. package/dist/schema.cjs.map +1 -1
  22. package/dist/schema.js.map +1 -1
  23. package/package.json +23 -46
  24. package/dist/client.cjs +0 -6094
  25. package/dist/client.cjs.map +0 -1
  26. package/dist/client.d.cts +0 -19
  27. package/dist/client.d.ts +0 -19
  28. package/dist/client.js +0 -6060
  29. package/dist/client.js.map +0 -1
  30. package/dist/utils/pg-utils.cjs.map +0 -1
  31. package/dist/utils/pg-utils.d.cts +0 -8
  32. package/dist/utils/pg-utils.d.ts +0 -8
  33. package/dist/utils/pg-utils.js +0 -16
  34. package/dist/utils/pg-utils.js.map +0 -1
  35. package/dist/utils/sqlite-utils.cjs +0 -55
  36. package/dist/utils/sqlite-utils.cjs.map +0 -1
  37. package/dist/utils/sqlite-utils.d.cts +0 -8
  38. package/dist/utils/sqlite-utils.d.ts +0 -8
  39. package/dist/utils/sqlite-utils.js +0 -22
  40. package/dist/utils/sqlite-utils.js.map +0 -1
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
7
  var __export = (target, all) => {
@@ -18,14 +16,6 @@ var __copyProps = (to, from, except, desc) => {
18
16
  }
19
17
  return to;
20
18
  };
21
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
- // If the importer is in node compatibility mode or this is not an ESM
23
- // file that has been converted to a CommonJS file using a Babel-
24
- // compatible transform (i.e. "__esModule" has not been set), then set
25
- // "default" to the CommonJS "module.exports" for node compatibility.
26
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
- mod
28
- ));
29
19
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
20
 
31
21
  // src/plugins/policy/index.ts
@@ -49,16 +39,16 @@ var RejectedByPolicyError = class extends Error {
49
39
  };
50
40
 
51
41
  // src/plugins/policy/policy-handler.ts
42
+ var import_common_helpers6 = require("@zenstackhq/common-helpers");
52
43
  var import_kysely7 = require("kysely");
53
- var import_tiny_invariant6 = __toESM(require("tiny-invariant"), 1);
54
44
  var import_ts_pattern7 = require("ts-pattern");
55
45
 
56
46
  // src/client/crud/dialects/index.ts
57
47
  var import_ts_pattern4 = require("ts-pattern");
58
48
 
59
49
  // src/client/crud/dialects/postgresql.ts
50
+ var import_common_helpers2 = require("@zenstackhq/common-helpers");
60
51
  var import_kysely2 = require("kysely");
61
- var import_tiny_invariant2 = __toESM(require("tiny-invariant"), 1);
62
52
  var import_ts_pattern2 = require("ts-pattern");
63
53
 
64
54
  // src/client/errors.ts
@@ -66,17 +56,16 @@ var QueryError = class extends Error {
66
56
  static {
67
57
  __name(this, "QueryError");
68
58
  }
69
- constructor(message) {
70
- super(message);
59
+ constructor(message, cause) {
60
+ super(message, {
61
+ cause
62
+ });
71
63
  }
72
64
  };
73
65
  var InternalError = class extends Error {
74
66
  static {
75
67
  __name(this, "InternalError");
76
68
  }
77
- constructor(message) {
78
- super(message);
79
- }
80
69
  };
81
70
 
82
71
  // src/client/query-utils.ts
@@ -87,7 +76,7 @@ __name(getModel, "getModel");
87
76
  function requireModel(schema, model) {
88
77
  const matchedName = Object.keys(schema.models).find((k) => k.toLowerCase() === model.toLowerCase());
89
78
  if (!matchedName) {
90
- throw new QueryError(`Model "${model}" not found`);
79
+ throw new QueryError(`Model "${model}" not found in schema`);
91
80
  }
92
81
  return schema.models[matchedName];
93
82
  }
@@ -150,6 +139,11 @@ function getRelationForeignKeyFieldPairs(schema, model, relationField) {
150
139
  }
151
140
  }
152
141
  __name(getRelationForeignKeyFieldPairs, "getRelationForeignKeyFieldPairs");
142
+ function isRelationField(schema, model, field) {
143
+ const fieldDef = requireField(schema, model, field);
144
+ return !!fieldDef.relation;
145
+ }
146
+ __name(isRelationField, "isRelationField");
153
147
  function getUniqueFields(schema, model) {
154
148
  const modelDef = requireModel(schema, model);
155
149
  const result = [];
@@ -186,7 +180,7 @@ function buildFieldRef(schema, model, field, options, eb, modelAlias) {
186
180
  computer = computedFields?.[model]?.[field];
187
181
  }
188
182
  if (!computer) {
189
- throw new QueryError(`Computed field "${field}" implementation not provided`);
183
+ throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
190
184
  }
191
185
  return computer(eb);
192
186
  }
@@ -265,8 +259,8 @@ function flattenCompoundUniqueFilters(schema, model, filter) {
265
259
  __name(flattenCompoundUniqueFilters, "flattenCompoundUniqueFilters");
266
260
 
267
261
  // src/client/crud/dialects/base.ts
262
+ var import_common_helpers = require("@zenstackhq/common-helpers");
268
263
  var import_kysely = require("kysely");
269
- var import_tiny_invariant = __toESM(require("tiny-invariant"), 1);
270
264
  var import_ts_pattern = require("ts-pattern");
271
265
 
272
266
  // src/utils/enumerate.ts
@@ -284,7 +278,6 @@ function enumerate(x) {
284
278
  __name(enumerate, "enumerate");
285
279
 
286
280
  // src/client/crud/dialects/base.ts
287
- var import_is_plain_object = require("is-plain-object");
288
281
  var BaseCrudDialect = class {
289
282
  static {
290
283
  __name(this, "BaseCrudDialect");
@@ -295,7 +288,7 @@ var BaseCrudDialect = class {
295
288
  this.schema = schema;
296
289
  this.options = options;
297
290
  }
298
- transformPrimitive(value, _type) {
291
+ transformPrimitive(value, _type, _forArrayField) {
299
292
  return value;
300
293
  }
301
294
  buildFilter(eb, model, modelAlias, where) {
@@ -438,7 +431,7 @@ var BaseCrudDialect = class {
438
431
  if (_value === void 0) {
439
432
  continue;
440
433
  }
441
- const value = this.transformPrimitive(_value, fieldType);
434
+ const value = this.transformPrimitive(_value, fieldType, !!fieldDef.array);
442
435
  switch (key) {
443
436
  case "equals": {
444
437
  clauses.push(this.buildLiteralFilter(eb, fieldRef, fieldType, eb.val(value)));
@@ -476,13 +469,17 @@ var BaseCrudDialect = class {
476
469
  if (isEnum(this.schema, fieldDef.type)) {
477
470
  return this.buildEnumFilter(eb, modelAlias, field, fieldDef, payload);
478
471
  }
479
- return (0, import_ts_pattern.match)(fieldDef.type).with("String", () => this.buildStringFilter(eb, modelAlias, field, payload)).with(import_ts_pattern.P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.buildNumberFilter(eb, model, modelAlias, field, type, payload)).with("Boolean", () => this.buildBooleanFilter(eb, modelAlias, field, payload)).with("DateTime", () => this.buildDateTimeFilter(eb, modelAlias, field, payload)).with("Bytes", () => this.buildBytesFilter(eb, modelAlias, field, payload)).exhaustive();
472
+ return (0, import_ts_pattern.match)(fieldDef.type).with("String", () => this.buildStringFilter(eb, modelAlias, field, payload)).with(import_ts_pattern.P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.buildNumberFilter(eb, model, modelAlias, field, type, payload)).with("Boolean", () => this.buildBooleanFilter(eb, modelAlias, field, payload)).with("DateTime", () => this.buildDateTimeFilter(eb, modelAlias, field, payload)).with("Bytes", () => this.buildBytesFilter(eb, modelAlias, field, payload)).with("Json", () => {
473
+ throw new InternalError("JSON filters are not supported yet");
474
+ }).with("Unsupported", () => {
475
+ throw new QueryError(`Unsupported field cannot be used in filters`);
476
+ }).exhaustive();
480
477
  }
481
478
  buildLiteralFilter(eb, lhs, type, rhs) {
482
- return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type) : rhs);
479
+ return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type, false) : rhs);
483
480
  }
484
481
  buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0) {
485
- if (payload === null || !(0, import_is_plain_object.isPlainObject)(payload)) {
482
+ if (payload === null || !(0, import_common_helpers.isPlainObject)(payload)) {
486
483
  return {
487
484
  conditions: [
488
485
  this.buildLiteralFilter(eb, lhs, type, payload)
@@ -498,14 +495,14 @@ var BaseCrudDialect = class {
498
495
  }
499
496
  const rhs = Array.isArray(value) ? value.map(getRhs) : getRhs(value);
500
497
  const condition = (0, import_ts_pattern.match)(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
501
- (0, import_tiny_invariant.default)(Array.isArray(rhs), "right hand side must be an array");
498
+ (0, import_common_helpers.invariant)(Array.isArray(rhs), "right hand side must be an array");
502
499
  if (rhs.length === 0) {
503
500
  return this.false(eb);
504
501
  } else {
505
502
  return eb(lhs, "in", rhs);
506
503
  }
507
504
  }).with("notIn", () => {
508
- (0, import_tiny_invariant.default)(Array.isArray(rhs), "right hand side must be an array");
505
+ (0, import_common_helpers.invariant)(Array.isArray(rhs), "right hand side must be an array");
509
506
  if (rhs.length === 0) {
510
507
  return this.true(eb);
511
508
  } else {
@@ -566,22 +563,22 @@ var BaseCrudDialect = class {
566
563
  }
567
564
  }
568
565
  buildNumberFilter(eb, model, table, field, type, payload) {
569
- const { conditions } = this.buildStandardFilter(eb, type, payload, buildFieldRef(this.schema, model, field, this.options, eb), (value) => this.transformPrimitive(value, type), (value) => this.buildNumberFilter(eb, model, table, field, type, value));
566
+ const { conditions } = this.buildStandardFilter(eb, type, payload, buildFieldRef(this.schema, model, field, this.options, eb), (value) => this.transformPrimitive(value, type, false), (value) => this.buildNumberFilter(eb, model, table, field, type, value));
570
567
  return this.and(eb, ...conditions);
571
568
  }
572
569
  buildBooleanFilter(eb, table, field, payload) {
573
- const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, import_kysely.sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Boolean"), (value) => this.buildBooleanFilter(eb, table, field, value), true, [
570
+ const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, import_kysely.sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Boolean", false), (value) => this.buildBooleanFilter(eb, table, field, value), true, [
574
571
  "equals",
575
572
  "not"
576
573
  ]);
577
574
  return this.and(eb, ...conditions);
578
575
  }
579
576
  buildDateTimeFilter(eb, table, field, payload) {
580
- const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, import_kysely.sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "DateTime"), (value) => this.buildDateTimeFilter(eb, table, field, value), true);
577
+ const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, import_kysely.sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "DateTime", false), (value) => this.buildDateTimeFilter(eb, table, field, value), true);
581
578
  return this.and(eb, ...conditions);
582
579
  }
583
580
  buildBytesFilter(eb, table, field, payload) {
584
- const conditions = this.buildStandardFilter(eb, "Bytes", payload, import_kysely.sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Bytes"), (value) => this.buildBytesFilter(eb, table, field, value), true, [
581
+ const conditions = this.buildStandardFilter(eb, "Bytes", payload, import_kysely.sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Bytes", false), (value) => this.buildBytesFilter(eb, table, field, value), true, [
585
582
  "equals",
586
583
  "in",
587
584
  "notIn",
@@ -619,9 +616,9 @@ var BaseCrudDialect = class {
619
616
  "_min",
620
617
  "_max"
621
618
  ].includes(field)) {
622
- (0, import_tiny_invariant.default)(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
619
+ (0, import_common_helpers.invariant)(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
623
620
  for (const [k, v] of Object.entries(value)) {
624
- (0, import_tiny_invariant.default)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
621
+ (0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
625
622
  result = result.orderBy((eb) => eb.fn(field.slice(1), [
626
623
  import_kysely.sql.ref(k)
627
624
  ]), import_kysely.sql.raw(this.negateSort(v, negated)));
@@ -630,9 +627,9 @@ var BaseCrudDialect = class {
630
627
  }
631
628
  switch (field) {
632
629
  case "_count": {
633
- (0, import_tiny_invariant.default)(value && typeof value === "object", 'invalid orderBy value for field "_count"');
630
+ (0, import_common_helpers.invariant)(value && typeof value === "object", 'invalid orderBy value for field "_count"');
634
631
  for (const [k, v] of Object.entries(value)) {
635
- (0, import_tiny_invariant.default)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
632
+ (0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
636
633
  result = result.orderBy((eb) => eb.fn.count(import_kysely.sql.ref(k)), import_kysely.sql.raw(this.negateSort(v, negated)));
637
634
  }
638
635
  continue;
@@ -654,7 +651,7 @@ var BaseCrudDialect = class {
654
651
  throw new QueryError(`invalid orderBy value for field "${field}"`);
655
652
  }
656
653
  if ("_count" in value) {
657
- (0, import_tiny_invariant.default)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
654
+ (0, import_common_helpers.invariant)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
658
655
  const sort = this.negateSort(value._count, negated);
659
656
  result = result.orderBy((eb) => {
660
657
  let subQuery = eb.selectFrom(relationModel);
@@ -680,10 +677,10 @@ var BaseCrudDialect = class {
680
677
  return negated ? sort === "asc" ? "desc" : "asc" : sort;
681
678
  }
682
679
  true(eb) {
683
- return eb.lit(this.transformPrimitive(true, "Boolean"));
680
+ return eb.lit(this.transformPrimitive(true, "Boolean", false));
684
681
  }
685
682
  false(eb) {
686
- return eb.lit(this.transformPrimitive(false, "Boolean"));
683
+ return eb.lit(this.transformPrimitive(false, "Boolean", false));
687
684
  }
688
685
  isTrue(expression) {
689
686
  const node = expression.toOperationNode();
@@ -732,14 +729,18 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
732
729
  get provider() {
733
730
  return "postgresql";
734
731
  }
735
- transformPrimitive(value, type) {
732
+ transformPrimitive(value, type, forArrayField) {
736
733
  if (value === void 0) {
737
734
  return value;
738
735
  }
739
736
  if (Array.isArray(value)) {
740
- return value.map((v) => this.transformPrimitive(v, type));
737
+ if (type === "Json" && !forArrayField) {
738
+ return JSON.stringify(value);
739
+ } else {
740
+ return value.map((v) => this.transformPrimitive(v, type, false));
741
+ }
741
742
  } else {
742
- return (0, import_ts_pattern2.match)(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).otherwise(() => value);
743
+ return (0, import_ts_pattern2.match)(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).with("Decimal", () => value !== null ? value.toString() : value).otherwise(() => value);
743
744
  }
744
745
  }
745
746
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
@@ -772,8 +773,8 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
772
773
  if (m2m) {
773
774
  const parentIds = getIdFields(this.schema, model);
774
775
  const relationIds = getIdFields(this.schema, relationModel);
775
- (0, import_tiny_invariant2.default)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
776
- (0, import_tiny_invariant2.default)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
776
+ (0, import_common_helpers2.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
777
+ (0, import_common_helpers2.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
777
778
  subQuery = subQuery.where(eb(eb.ref(`${relationModel}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentName}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
778
779
  } else {
779
780
  const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, relationModel);
@@ -806,25 +807,33 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
806
807
  buildFieldRef(this.schema, relationModel, field, this.options, eb)
807
808
  ]).flatMap((v) => v));
808
809
  } else if (payload.select) {
809
- objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field]) => [
810
- import_kysely2.sql.lit(field),
811
- buildFieldRef(this.schema, relationModel, field, this.options, eb)
812
- ]).flatMap((v) => v));
810
+ objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field]) => {
811
+ const fieldDef = requireField(this.schema, relationModel, field);
812
+ const fieldValue = fieldDef.relation ? eb.ref(`${parentName}$${relationField}$${field}.$j`) : buildFieldRef(this.schema, relationModel, field, this.options, eb);
813
+ return [
814
+ import_kysely2.sql.lit(field),
815
+ fieldValue
816
+ ];
817
+ }).flatMap((v) => v));
813
818
  }
814
819
  if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
815
820
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field]) => [
816
821
  import_kysely2.sql.lit(field),
822
+ // reference the synthesized JSON field
817
823
  eb.ref(`${parentName}$${relationField}$${field}.$j`)
818
824
  ]).flatMap((v) => v));
819
825
  }
820
826
  return objArgs;
821
827
  }
822
- buildRelationJoins(model, relationField, qb, payload, parentName) {
828
+ buildRelationJoins(relationModel, relationField, qb, payload, parentName) {
823
829
  let result = qb;
824
- if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
825
- Object.entries(payload.include).filter(([, value]) => value).forEach(([field, value]) => {
826
- result = this.buildRelationJSON(model, result, field, `${parentName}$${relationField}`, value);
827
- });
830
+ if (typeof payload === "object") {
831
+ const selectInclude = payload.include ?? payload.select;
832
+ if (selectInclude && typeof selectInclude === "object") {
833
+ Object.entries(selectInclude).filter(([, value]) => value).filter(([field]) => isRelationField(this.schema, relationModel, field)).forEach(([field, value]) => {
834
+ result = this.buildRelationJSON(relationModel, result, field, `${parentName}$${relationField}`, value);
835
+ });
836
+ }
828
837
  }
829
838
  return result;
830
839
  }
@@ -867,8 +876,8 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
867
876
  };
868
877
 
869
878
  // src/client/crud/dialects/sqlite.ts
879
+ var import_common_helpers3 = require("@zenstackhq/common-helpers");
870
880
  var import_kysely3 = require("kysely");
871
- var import_tiny_invariant3 = __toESM(require("tiny-invariant"), 1);
872
881
  var import_ts_pattern3 = require("ts-pattern");
873
882
  var SqliteCrudDialect = class extends BaseCrudDialect {
874
883
  static {
@@ -877,14 +886,14 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
877
886
  get provider() {
878
887
  return "sqlite";
879
888
  }
880
- transformPrimitive(value, type) {
889
+ transformPrimitive(value, type, _forArrayField) {
881
890
  if (value === void 0) {
882
891
  return value;
883
892
  }
884
893
  if (Array.isArray(value)) {
885
- return value.map((v) => this.transformPrimitive(v, type));
894
+ return value.map((v) => this.transformPrimitive(v, type, false));
886
895
  } else {
887
- return (0, import_ts_pattern3.match)(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => value instanceof Date ? value.toISOString() : value).with("Decimal", () => value.toString()).with("Bytes", () => Buffer.from(value)).otherwise(() => value);
896
+ return (0, import_ts_pattern3.match)(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => value instanceof Date ? value.toISOString() : value).with("Decimal", () => value.toString()).with("Bytes", () => Buffer.from(value)).with("Json", () => JSON.stringify(value)).otherwise(() => value);
888
897
  }
889
898
  }
890
899
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
@@ -915,8 +924,8 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
915
924
  if (m2m) {
916
925
  const parentIds = getIdFields(this.schema, model);
917
926
  const relationIds = getIdFields(this.schema, relationModel);
918
- (0, import_tiny_invariant3.default)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
919
- (0, import_tiny_invariant3.default)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
927
+ (0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
928
+ (0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
920
929
  subQuery = subQuery.where(eb(eb.ref(`${relationModel}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentName}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
921
930
  } else {
922
931
  const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
@@ -1412,12 +1421,12 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
1412
1421
  };
1413
1422
 
1414
1423
  // src/plugins/policy/expression-transformer.ts
1424
+ var import_common_helpers5 = require("@zenstackhq/common-helpers");
1415
1425
  var import_kysely6 = require("kysely");
1416
- var import_tiny_invariant5 = __toESM(require("tiny-invariant"), 1);
1417
1426
  var import_ts_pattern6 = require("ts-pattern");
1418
1427
 
1419
1428
  // src/plugins/policy/expression-evaluator.ts
1420
- var import_tiny_invariant4 = __toESM(require("tiny-invariant"), 1);
1429
+ var import_common_helpers4 = require("@zenstackhq/common-helpers");
1421
1430
  var import_ts_pattern5 = require("ts-pattern");
1422
1431
  var ExpressionEvaluator = class {
1423
1432
  static {
@@ -1461,18 +1470,18 @@ var ExpressionEvaluator = class {
1461
1470
  const right = this.evaluate(expr2.right, context);
1462
1471
  return (0, import_ts_pattern5.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", () => {
1463
1472
  const _right = right ?? [];
1464
- (0, import_tiny_invariant4.default)(Array.isArray(_right), 'expected array for "in" operator');
1473
+ (0, import_common_helpers4.invariant)(Array.isArray(_right), 'expected array for "in" operator');
1465
1474
  return _right.includes(left);
1466
1475
  }).exhaustive();
1467
1476
  }
1468
1477
  evaluateCollectionPredicate(expr2, context) {
1469
1478
  const op = expr2.op;
1470
- (0, import_tiny_invariant4.default)(op === "?" || op === "!" || op === "^", 'expected "?" or "!" or "^" operator');
1479
+ (0, import_common_helpers4.invariant)(op === "?" || op === "!" || op === "^", 'expected "?" or "!" or "^" operator');
1471
1480
  const left = this.evaluate(expr2.left, context);
1472
1481
  if (!left) {
1473
1482
  return false;
1474
1483
  }
1475
- (0, import_tiny_invariant4.default)(Array.isArray(left), "expected array");
1484
+ (0, import_common_helpers4.invariant)(Array.isArray(left), "expected array");
1476
1485
  return (0, import_ts_pattern5.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1477
1486
  ...context,
1478
1487
  thisValue: item
@@ -1489,11 +1498,11 @@ var ExpressionEvaluator = class {
1489
1498
  // src/plugins/policy/utils.ts
1490
1499
  var import_kysely5 = require("kysely");
1491
1500
  function trueNode(dialect) {
1492
- return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean"));
1501
+ return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean", false));
1493
1502
  }
1494
1503
  __name(trueNode, "trueNode");
1495
1504
  function falseNode(dialect) {
1496
- return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean"));
1505
+ return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean", false));
1497
1506
  }
1498
1507
  __name(falseNode, "falseNode");
1499
1508
  function isTrueNode(node) {
@@ -1694,20 +1703,20 @@ var ExpressionTransformer = class {
1694
1703
  return import_kysely6.BinaryOperationNode.create(left, this.transformOperator(op), right);
1695
1704
  }
1696
1705
  transformCollectionPredicate(expr2, context) {
1697
- (0, import_tiny_invariant5.default)(expr2.op === "?" || expr2.op === "!" || expr2.op === "^", 'expected "?" or "!" or "^" operator');
1706
+ (0, import_common_helpers5.invariant)(expr2.op === "?" || expr2.op === "!" || expr2.op === "^", 'expected "?" or "!" or "^" operator');
1698
1707
  if (this.isAuthCall(expr2.left) || this.isAuthMember(expr2.left)) {
1699
1708
  const value = new ExpressionEvaluator().evaluate(expr2, {
1700
1709
  auth: this.auth
1701
1710
  });
1702
1711
  return this.transformValue(value, "Boolean");
1703
1712
  }
1704
- (0, import_tiny_invariant5.default)(ExpressionUtils.isField(expr2.left) || ExpressionUtils.isMember(expr2.left), "left operand must be field or member access");
1713
+ (0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.left) || ExpressionUtils.isMember(expr2.left), "left operand must be field or member access");
1705
1714
  let newContextModel;
1706
1715
  if (ExpressionUtils.isField(expr2.left)) {
1707
1716
  const fieldDef = requireField(this.schema, context.model, expr2.left.field);
1708
1717
  newContextModel = fieldDef.type;
1709
1718
  } else {
1710
- (0, import_tiny_invariant5.default)(ExpressionUtils.isField(expr2.left.receiver));
1719
+ (0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.left.receiver));
1711
1720
  const fieldDef = requireField(this.schema, context.model, expr2.left.receiver.field);
1712
1721
  newContextModel = fieldDef.type;
1713
1722
  for (const member of expr2.left.members) {
@@ -1751,10 +1760,10 @@ var ExpressionTransformer = class {
1751
1760
  }
1752
1761
  }
1753
1762
  transformValue(value, type) {
1754
- return import_kysely6.ValueNode.create(this.dialect.transformPrimitive(value, type) ?? null);
1763
+ return import_kysely6.ValueNode.create(this.dialect.transformPrimitive(value, type, false) ?? null);
1755
1764
  }
1756
1765
  _unary(expr2, context) {
1757
- (0, import_tiny_invariant5.default)(expr2.op === "!", 'only "!" operator is supported');
1766
+ (0, import_common_helpers5.invariant)(expr2.op === "!", 'only "!" operator is supported');
1758
1767
  return import_kysely6.BinaryOperationNode.create(this.transform(expr2.operand, context), this.transformOperator("!="), trueNode(this.dialect));
1759
1768
  }
1760
1769
  transformOperator(op) {
@@ -1797,10 +1806,10 @@ var ExpressionTransformer = class {
1797
1806
  if (this.isAuthCall(expr2.receiver)) {
1798
1807
  return this.valueMemberAccess(this.auth, expr2, this.authType);
1799
1808
  }
1800
- (0, import_tiny_invariant5.default)(ExpressionUtils.isField(expr2.receiver), "expect receiver to be field expression");
1809
+ (0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.receiver), "expect receiver to be field expression");
1801
1810
  const { memberFilter, memberSelect, ...restContext } = context;
1802
1811
  const receiver = this.transform(expr2.receiver, restContext);
1803
- (0, import_tiny_invariant5.default)(import_kysely6.SelectQueryNode.is(receiver), "expected receiver to be select query");
1812
+ (0, import_common_helpers5.invariant)(import_kysely6.SelectQueryNode.is(receiver), "expected receiver to be select query");
1804
1813
  const receiverField = requireField(this.schema, context.model, expr2.receiver.field);
1805
1814
  const memberFields = [];
1806
1815
  let currType = receiverField.type;
@@ -1824,7 +1833,7 @@ var ExpressionTransformer = class {
1824
1833
  thisEntity: void 0
1825
1834
  });
1826
1835
  if (currNode) {
1827
- (0, import_tiny_invariant5.default)(import_kysely6.SelectQueryNode.is(currNode), "expected select query node");
1836
+ (0, import_common_helpers5.invariant)(import_kysely6.SelectQueryNode.is(currNode), "expected select query node");
1828
1837
  currNode = {
1829
1838
  ...relation,
1830
1839
  selections: [
@@ -1841,8 +1850,8 @@ var ExpressionTransformer = class {
1841
1850
  };
1842
1851
  }
1843
1852
  } else {
1844
- (0, import_tiny_invariant5.default)(i === expr2.members.length - 1, "plain field access must be the last segment");
1845
- (0, import_tiny_invariant5.default)(!currNode, "plain field access must be the last segment");
1853
+ (0, import_common_helpers5.invariant)(i === expr2.members.length - 1, "plain field access must be the last segment");
1854
+ (0, import_common_helpers5.invariant)(!currNode, "plain field access must be the last segment");
1846
1855
  currNode = import_kysely6.ColumnNode.create(member);
1847
1856
  }
1848
1857
  }
@@ -1994,7 +2003,7 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
1994
2003
  get kysely() {
1995
2004
  return this.client.$qb;
1996
2005
  }
1997
- async handle(node, proceed, transaction) {
2006
+ async handle(node, proceed) {
1998
2007
  if (!this.isCrudQueryNode(node)) {
1999
2008
  throw new RejectedByPolicyError(void 0, "non-CRUD queries are not allowed");
2000
2009
  }
@@ -2014,27 +2023,20 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2014
2023
  if (!mutationRequiresTransaction && !node.returning) {
2015
2024
  return proceed(this.transformNode(node));
2016
2025
  }
2017
- let readBackError = false;
2018
- const result = await transaction(async (txProceed) => {
2019
- if (import_kysely7.InsertQueryNode.is(node)) {
2020
- await this.enforcePreCreatePolicy(node, txProceed);
2021
- }
2022
- const transformedNode = this.transformNode(node);
2023
- const result2 = await txProceed(transformedNode);
2024
- if (!this.onlyReturningId(node)) {
2025
- const readBackResult = await this.processReadBack(node, result2, txProceed);
2026
- if (readBackResult.rows.length !== result2.rows.length) {
2027
- readBackError = true;
2028
- }
2029
- return readBackResult;
2030
- } else {
2031
- return result2;
2026
+ if (import_kysely7.InsertQueryNode.is(node)) {
2027
+ await this.enforcePreCreatePolicy(node, proceed);
2028
+ }
2029
+ const transformedNode = this.transformNode(node);
2030
+ const result = await proceed(transformedNode);
2031
+ if (!this.onlyReturningId(node)) {
2032
+ const readBackResult = await this.processReadBack(node, result, proceed);
2033
+ if (readBackResult.rows.length !== result.rows.length) {
2034
+ throw new RejectedByPolicyError(mutationModel, "result is not allowed to be read back");
2032
2035
  }
2033
- });
2034
- if (readBackError) {
2035
- throw new RejectedByPolicyError(mutationModel, "result is not allowed to be read back");
2036
+ return readBackResult;
2037
+ } else {
2038
+ return result;
2036
2039
  }
2037
- return result;
2038
2040
  }
2039
2041
  onlyReturningId(node) {
2040
2042
  if (!node.returning) {
@@ -2087,19 +2089,19 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2087
2089
  }
2088
2090
  }
2089
2091
  unwrapCreateValueRow(data, model, fields) {
2090
- (0, import_tiny_invariant6.default)(data.length === fields.length, "data length must match fields length");
2092
+ (0, import_common_helpers6.invariant)(data.length === fields.length, "data length must match fields length");
2091
2093
  const result = [];
2092
2094
  for (let i = 0; i < data.length; i++) {
2093
2095
  const item = data[i];
2094
2096
  const fieldDef = requireField(this.client.$schema, model, fields[i]);
2095
2097
  if (typeof item === "object" && item && "kind" in item) {
2096
- (0, import_tiny_invariant6.default)(item.kind === "ValueNode", "expecting a ValueNode");
2098
+ (0, import_common_helpers6.invariant)(item.kind === "ValueNode", "expecting a ValueNode");
2097
2099
  result.push({
2098
- node: import_kysely7.ValueNode.create(this.dialect.transformPrimitive(item.value, fieldDef.type)),
2100
+ node: import_kysely7.ValueNode.create(this.dialect.transformPrimitive(item.value, fieldDef.type, !!fieldDef.array)),
2099
2101
  raw: item.value
2100
2102
  });
2101
2103
  } else {
2102
- const value = this.dialect.transformPrimitive(item, fieldDef.type);
2104
+ const value = this.dialect.transformPrimitive(item, fieldDef.type, !!fieldDef.array);
2103
2105
  if (Array.isArray(value)) {
2104
2106
  result.push({
2105
2107
  node: import_kysely7.RawNode.createWithSql(this.dialect.buildArrayLiteralSQL(value)),
@@ -2301,8 +2303,8 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2301
2303
  const modelDef = requireModel(this.client.$schema, modelName);
2302
2304
  const result = [];
2303
2305
  const extractOperations = /* @__PURE__ */ __name((expr2) => {
2304
- (0, import_tiny_invariant6.default)(ExpressionUtils.isLiteral(expr2), "expecting a literal");
2305
- (0, import_tiny_invariant6.default)(typeof expr2.value === "string", "expecting a string literal");
2306
+ (0, import_common_helpers6.invariant)(ExpressionUtils.isLiteral(expr2), "expecting a literal");
2307
+ (0, import_common_helpers6.invariant)(typeof expr2.value === "string", "expecting a string literal");
2306
2308
  return expr2.value.split(",").filter((v) => !!v).map((v) => v.trim());
2307
2309
  }, "extractOperations");
2308
2310
  if (modelDef.attributes) {
@@ -2330,9 +2332,18 @@ var PolicyPlugin = class {
2330
2332
  get description() {
2331
2333
  return "Enforces access policies defined in the schema.";
2332
2334
  }
2333
- onKyselyQuery({ query, client, proceed, transaction }) {
2335
+ onKyselyQuery({
2336
+ query,
2337
+ client,
2338
+ proceed
2339
+ /*, transaction*/
2340
+ }) {
2334
2341
  const handler = new PolicyHandler(client);
2335
- return handler.handle(query, proceed, transaction);
2342
+ return handler.handle(
2343
+ query,
2344
+ proceed
2345
+ /*, transaction*/
2346
+ );
2336
2347
  }
2337
2348
  };
2338
2349
  // Annotate the CommonJS export names for ESM import in node: