@zenstackhq/runtime 3.0.0-alpha.2 → 3.0.0-alpha.21

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 (43) hide show
  1. package/dist/{contract-DguafRNB.d.cts → contract-D8U59Syb.d.cts} +971 -785
  2. package/dist/{contract-DguafRNB.d.ts → contract-D8U59Syb.d.ts} +971 -785
  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 +1787 -903
  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 +1758 -879
  14. package/dist/index.js.map +1 -1
  15. package/dist/plugins/{policy.cjs → policy/index.cjs} +472 -271
  16. package/dist/plugins/policy/index.cjs.map +1 -0
  17. package/dist/plugins/{policy.d.ts → policy/index.d.cts} +2 -4
  18. package/dist/plugins/{policy.d.cts → policy/index.d.ts} +2 -4
  19. package/dist/plugins/{policy.js → policy/index.js} +447 -236
  20. package/dist/plugins/policy/index.js.map +1 -0
  21. package/dist/plugins/policy/plugin.zmodel +33 -0
  22. package/dist/schema.cjs.map +1 -1
  23. package/dist/schema.js.map +1 -1
  24. package/package.json +27 -49
  25. package/dist/client.cjs +0 -6094
  26. package/dist/client.cjs.map +0 -1
  27. package/dist/client.d.cts +0 -19
  28. package/dist/client.d.ts +0 -19
  29. package/dist/client.js +0 -6060
  30. package/dist/client.js.map +0 -1
  31. package/dist/plugins/policy.cjs.map +0 -1
  32. package/dist/plugins/policy.js.map +0 -1
  33. package/dist/utils/pg-utils.cjs.map +0 -1
  34. package/dist/utils/pg-utils.d.cts +0 -8
  35. package/dist/utils/pg-utils.d.ts +0 -8
  36. package/dist/utils/pg-utils.js +0 -16
  37. package/dist/utils/pg-utils.js.map +0 -1
  38. package/dist/utils/sqlite-utils.cjs +0 -55
  39. package/dist/utils/sqlite-utils.cjs.map +0 -1
  40. package/dist/utils/sqlite-utils.d.cts +0 -8
  41. package/dist/utils/sqlite-utils.d.ts +0 -8
  42. package/dist/utils/sqlite-utils.js +0 -22
  43. 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,34 +39,130 @@ 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
- var import_ts_pattern7 = require("ts-pattern");
44
+ var import_ts_pattern8 = require("ts-pattern");
55
45
 
56
46
  // src/client/crud/dialects/index.ts
57
- var import_ts_pattern4 = require("ts-pattern");
47
+ var import_ts_pattern5 = 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
- var import_ts_pattern2 = require("ts-pattern");
52
+ var import_ts_pattern3 = require("ts-pattern");
53
+
54
+ // src/client/constants.ts
55
+ var DELEGATE_JOINED_FIELD_PREFIX = "$delegate$";
56
+ var LOGICAL_COMBINATORS = [
57
+ "AND",
58
+ "OR",
59
+ "NOT"
60
+ ];
61
+ var AGGREGATE_OPERATORS = [
62
+ "_count",
63
+ "_sum",
64
+ "_avg",
65
+ "_min",
66
+ "_max"
67
+ ];
68
+
69
+ // src/client/query-utils.ts
70
+ var import_ts_pattern = require("ts-pattern");
71
+
72
+ // src/schema/expression.ts
73
+ var ExpressionUtils = {
74
+ literal: /* @__PURE__ */ __name((value) => {
75
+ return {
76
+ kind: "literal",
77
+ value
78
+ };
79
+ }, "literal"),
80
+ array: /* @__PURE__ */ __name((items) => {
81
+ return {
82
+ kind: "array",
83
+ items
84
+ };
85
+ }, "array"),
86
+ call: /* @__PURE__ */ __name((functionName, args) => {
87
+ return {
88
+ kind: "call",
89
+ function: functionName,
90
+ args
91
+ };
92
+ }, "call"),
93
+ binary: /* @__PURE__ */ __name((left, op, right) => {
94
+ return {
95
+ kind: "binary",
96
+ op,
97
+ left,
98
+ right
99
+ };
100
+ }, "binary"),
101
+ unary: /* @__PURE__ */ __name((op, operand) => {
102
+ return {
103
+ kind: "unary",
104
+ op,
105
+ operand
106
+ };
107
+ }, "unary"),
108
+ field: /* @__PURE__ */ __name((field) => {
109
+ return {
110
+ kind: "field",
111
+ field
112
+ };
113
+ }, "field"),
114
+ member: /* @__PURE__ */ __name((receiver, members) => {
115
+ return {
116
+ kind: "member",
117
+ receiver,
118
+ members
119
+ };
120
+ }, "member"),
121
+ _this: /* @__PURE__ */ __name(() => {
122
+ return {
123
+ kind: "this"
124
+ };
125
+ }, "_this"),
126
+ _null: /* @__PURE__ */ __name(() => {
127
+ return {
128
+ kind: "null"
129
+ };
130
+ }, "_null"),
131
+ and: /* @__PURE__ */ __name((expr2, ...expressions) => {
132
+ return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "&&", exp), expr2);
133
+ }, "and"),
134
+ or: /* @__PURE__ */ __name((expr2, ...expressions) => {
135
+ return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
136
+ }, "or"),
137
+ is: /* @__PURE__ */ __name((value, kind) => {
138
+ return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
139
+ }, "is"),
140
+ isLiteral: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "literal"), "isLiteral"),
141
+ isArray: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "array"), "isArray"),
142
+ isCall: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "call"), "isCall"),
143
+ isNull: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "null"), "isNull"),
144
+ isThis: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "this"), "isThis"),
145
+ isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
146
+ isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
147
+ isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
148
+ isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
149
+ };
63
150
 
64
151
  // src/client/errors.ts
65
152
  var QueryError = class extends Error {
66
153
  static {
67
154
  __name(this, "QueryError");
68
155
  }
69
- constructor(message) {
70
- super(message);
156
+ constructor(message, cause) {
157
+ super(message, {
158
+ cause
159
+ });
71
160
  }
72
161
  };
73
162
  var InternalError = class extends Error {
74
163
  static {
75
164
  __name(this, "InternalError");
76
165
  }
77
- constructor(message) {
78
- super(message);
79
- }
80
166
  };
81
167
 
82
168
  // src/client/query-utils.ts
@@ -87,7 +173,7 @@ __name(getModel, "getModel");
87
173
  function requireModel(schema, model) {
88
174
  const matchedName = Object.keys(schema.models).find((k) => k.toLowerCase() === model.toLowerCase());
89
175
  if (!matchedName) {
90
- throw new QueryError(`Model "${model}" not found`);
176
+ throw new QueryError(`Model "${model}" not found in schema`);
91
177
  }
92
178
  return schema.models[matchedName];
93
179
  }
@@ -150,6 +236,16 @@ function getRelationForeignKeyFieldPairs(schema, model, relationField) {
150
236
  }
151
237
  }
152
238
  __name(getRelationForeignKeyFieldPairs, "getRelationForeignKeyFieldPairs");
239
+ function isRelationField(schema, model, field) {
240
+ const fieldDef = getField(schema, model, field);
241
+ return !!fieldDef?.relation;
242
+ }
243
+ __name(isRelationField, "isRelationField");
244
+ function isInheritedField(schema, model, field) {
245
+ const fieldDef = getField(schema, model, field);
246
+ return !!fieldDef?.originModel;
247
+ }
248
+ __name(isInheritedField, "isInheritedField");
153
249
  function getUniqueFields(schema, model) {
154
250
  const modelDef = requireModel(schema, model);
155
251
  const result = [];
@@ -186,7 +282,7 @@ function buildFieldRef(schema, model, field, options, eb, modelAlias) {
186
282
  computer = computedFields?.[model]?.[field];
187
283
  }
188
284
  if (!computer) {
189
- throw new QueryError(`Computed field "${field}" implementation not provided`);
285
+ throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
190
286
  }
191
287
  return computer(eb);
192
288
  }
@@ -263,11 +359,28 @@ function flattenCompoundUniqueFilters(schema, model, filter) {
263
359
  return result;
264
360
  }
265
361
  __name(flattenCompoundUniqueFilters, "flattenCompoundUniqueFilters");
362
+ function getDelegateDescendantModels(schema, model, collected = /* @__PURE__ */ new Set()) {
363
+ const subModels = Object.values(schema.models).filter((m) => m.baseModel === model);
364
+ subModels.forEach((def) => {
365
+ if (!collected.has(def)) {
366
+ collected.add(def);
367
+ getDelegateDescendantModels(schema, def.name, collected);
368
+ }
369
+ });
370
+ return [
371
+ ...collected
372
+ ];
373
+ }
374
+ __name(getDelegateDescendantModels, "getDelegateDescendantModels");
375
+ function aggregate(eb, expr2, op) {
376
+ return (0, import_ts_pattern.match)(op).with("_count", () => eb.fn.count(expr2)).with("_sum", () => eb.fn.sum(expr2)).with("_avg", () => eb.fn.avg(expr2)).with("_min", () => eb.fn.min(expr2)).with("_max", () => eb.fn.max(expr2)).exhaustive();
377
+ }
378
+ __name(aggregate, "aggregate");
266
379
 
267
380
  // src/client/crud/dialects/base.ts
381
+ var import_common_helpers = require("@zenstackhq/common-helpers");
268
382
  var import_kysely = require("kysely");
269
- var import_tiny_invariant = __toESM(require("tiny-invariant"), 1);
270
- var import_ts_pattern = require("ts-pattern");
383
+ var import_ts_pattern2 = require("ts-pattern");
271
384
 
272
385
  // src/utils/enumerate.ts
273
386
  function enumerate(x) {
@@ -284,7 +397,6 @@ function enumerate(x) {
284
397
  __name(enumerate, "enumerate");
285
398
 
286
399
  // src/client/crud/dialects/base.ts
287
- var import_is_plain_object = require("is-plain-object");
288
400
  var BaseCrudDialect = class {
289
401
  static {
290
402
  __name(this, "BaseCrudDialect");
@@ -295,9 +407,20 @@ var BaseCrudDialect = class {
295
407
  this.schema = schema;
296
408
  this.options = options;
297
409
  }
298
- transformPrimitive(value, _type) {
410
+ transformPrimitive(value, _type, _forArrayField) {
299
411
  return value;
300
412
  }
413
+ // #region common query builders
414
+ buildSelectModel(eb, model) {
415
+ const modelDef = requireModel(this.schema, model);
416
+ let result = eb.selectFrom(model);
417
+ let joinBase = modelDef.baseModel;
418
+ while (joinBase) {
419
+ result = this.buildDelegateJoin(model, joinBase, result);
420
+ joinBase = requireModel(this.schema, joinBase).baseModel;
421
+ }
422
+ return result;
423
+ }
301
424
  buildFilter(eb, model, modelAlias, where) {
302
425
  if (where === true || where === void 0) {
303
426
  return this.true(eb);
@@ -314,17 +437,20 @@ var BaseCrudDialect = class {
314
437
  if (key.startsWith("$")) {
315
438
  continue;
316
439
  }
317
- if (key === "AND" || key === "OR" || key === "NOT") {
440
+ if (this.isLogicalCombinator(key)) {
318
441
  result = this.and(eb, result, this.buildCompositeFilter(eb, model, modelAlias, key, payload));
319
442
  continue;
320
443
  }
321
444
  const fieldDef = requireField(this.schema, model, key);
322
445
  if (fieldDef.relation) {
323
446
  result = this.and(eb, result, this.buildRelationFilter(eb, model, modelAlias, key, fieldDef, payload));
324
- } else if (fieldDef.array) {
325
- result = this.and(eb, result, this.buildArrayFilter(eb, model, modelAlias, key, fieldDef, payload));
326
447
  } else {
327
- result = this.and(eb, result, this.buildPrimitiveFilter(eb, model, modelAlias, key, fieldDef, payload));
448
+ const fieldRef = this.fieldRef(fieldDef.originModel ?? model, key, eb, fieldDef.originModel ?? modelAlias);
449
+ if (fieldDef.array) {
450
+ result = this.and(eb, result, this.buildArrayFilter(eb, fieldRef, fieldDef, payload));
451
+ } else {
452
+ result = this.and(eb, result, this.buildPrimitiveFilter(eb, fieldRef, fieldDef, payload));
453
+ }
328
454
  }
329
455
  }
330
456
  if ("$expr" in _where && typeof _where["$expr"] === "function") {
@@ -332,8 +458,11 @@ var BaseCrudDialect = class {
332
458
  }
333
459
  return result;
334
460
  }
461
+ isLogicalCombinator(key) {
462
+ return LOGICAL_COMBINATORS.includes(key);
463
+ }
335
464
  buildCompositeFilter(eb, model, modelAlias, key, payload) {
336
- return (0, import_ts_pattern.match)(key).with("AND", () => this.and(eb, ...enumerate(payload).map((subPayload) => this.buildFilter(eb, model, modelAlias, subPayload)))).with("OR", () => this.or(eb, ...enumerate(payload).map((subPayload) => this.buildFilter(eb, model, modelAlias, subPayload)))).with("NOT", () => eb.not(this.buildCompositeFilter(eb, model, modelAlias, "AND", payload))).exhaustive();
465
+ return (0, import_ts_pattern2.match)(key).with("AND", () => this.and(eb, ...enumerate(payload).map((subPayload) => this.buildFilter(eb, model, modelAlias, subPayload)))).with("OR", () => this.or(eb, ...enumerate(payload).map((subPayload) => this.buildFilter(eb, model, modelAlias, subPayload)))).with("NOT", () => eb.not(this.buildCompositeFilter(eb, model, modelAlias, "AND", payload))).exhaustive();
337
466
  }
338
467
  buildRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
339
468
  if (!fieldDef.array) {
@@ -342,19 +471,26 @@ var BaseCrudDialect = class {
342
471
  return this.buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload);
343
472
  }
344
473
  }
345
- buildToOneRelationFilter(eb, model, table, field, fieldDef, payload) {
474
+ buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
346
475
  if (payload === null) {
347
476
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, model, field);
348
- if (ownedByModel) {
349
- return this.and(eb, ...keyPairs.map(({ fk }) => eb(import_kysely.sql.ref(`${table}.${fk}`), "is", null)));
477
+ if (ownedByModel && !fieldDef.originModel) {
478
+ return this.and(eb, ...keyPairs.map(({ fk }) => eb(import_kysely.sql.ref(`${modelAlias}.${fk}`), "is", null)));
350
479
  } else {
351
- return this.buildToOneRelationFilter(eb, model, table, field, fieldDef, {
480
+ return this.buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, {
352
481
  is: null
353
482
  });
354
483
  }
355
484
  }
356
- const joinAlias = `${table}$${field}`;
357
- const joinPairs = buildJoinPairs(this.schema, model, table, field, joinAlias);
485
+ const joinAlias = `${modelAlias}$${field}`;
486
+ const joinPairs = buildJoinPairs(
487
+ this.schema,
488
+ model,
489
+ // if field is from a base, use the base model to join
490
+ fieldDef.originModel ?? modelAlias,
491
+ field,
492
+ joinAlias
493
+ );
358
494
  const filterResultField = `${field}$filter`;
359
495
  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));
360
496
  const conditions = [];
@@ -415,30 +551,29 @@ var BaseCrudDialect = class {
415
551
  }
416
552
  switch (key) {
417
553
  case "some": {
418
- result = this.and(eb, result, eb(eb.selectFrom(relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationModel, subPayload)), ">", 0));
554
+ result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationModel, subPayload)), ">", 0));
419
555
  break;
420
556
  }
421
557
  case "every": {
422
- result = this.and(eb, result, eb(eb.selectFrom(relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("count")).where(buildPkFkWhereRefs(eb)).where((eb1) => eb1.not(this.buildFilter(eb1, relationModel, relationModel, subPayload))), "=", 0));
558
+ result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => eb1.not(this.buildFilter(eb1, relationModel, relationModel, subPayload))), "=", 0));
423
559
  break;
424
560
  }
425
561
  case "none": {
426
- result = this.and(eb, result, eb(eb.selectFrom(relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationModel, subPayload)), "=", 0));
562
+ result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationModel, subPayload)), "=", 0));
427
563
  break;
428
564
  }
429
565
  }
430
566
  }
431
567
  return result;
432
568
  }
433
- buildArrayFilter(eb, model, modelAlias, field, fieldDef, payload) {
569
+ buildArrayFilter(eb, fieldRef, fieldDef, payload) {
434
570
  const clauses = [];
435
571
  const fieldType = fieldDef.type;
436
- const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb, modelAlias);
437
572
  for (const [key, _value] of Object.entries(payload)) {
438
573
  if (_value === void 0) {
439
574
  continue;
440
575
  }
441
- const value = this.transformPrimitive(_value, fieldType);
576
+ const value = this.transformPrimitive(_value, fieldType, !!fieldDef.array);
442
577
  switch (key) {
443
578
  case "equals": {
444
579
  clauses.push(this.buildLiteralFilter(eb, fieldRef, fieldType, eb.val(value)));
@@ -469,20 +604,24 @@ var BaseCrudDialect = class {
469
604
  }
470
605
  return this.and(eb, ...clauses);
471
606
  }
472
- buildPrimitiveFilter(eb, model, modelAlias, field, fieldDef, payload) {
607
+ buildPrimitiveFilter(eb, fieldRef, fieldDef, payload) {
473
608
  if (payload === null) {
474
- return eb(import_kysely.sql.ref(`${modelAlias}.${field}`), "is", null);
609
+ return eb(fieldRef, "is", null);
475
610
  }
476
611
  if (isEnum(this.schema, fieldDef.type)) {
477
- return this.buildEnumFilter(eb, modelAlias, field, fieldDef, payload);
612
+ return this.buildEnumFilter(eb, fieldRef, fieldDef, payload);
478
613
  }
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();
614
+ return (0, import_ts_pattern2.match)(fieldDef.type).with("String", () => this.buildStringFilter(eb, fieldRef, payload)).with(import_ts_pattern2.P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.buildNumberFilter(eb, fieldRef, type, payload)).with("Boolean", () => this.buildBooleanFilter(eb, fieldRef, payload)).with("DateTime", () => this.buildDateTimeFilter(eb, fieldRef, payload)).with("Bytes", () => this.buildBytesFilter(eb, fieldRef, payload)).with("Json", () => {
615
+ throw new InternalError("JSON filters are not supported yet");
616
+ }).with("Unsupported", () => {
617
+ throw new QueryError(`Unsupported field cannot be used in filters`);
618
+ }).exhaustive();
480
619
  }
481
620
  buildLiteralFilter(eb, lhs, type, rhs) {
482
- return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type) : rhs);
621
+ return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type, false) : rhs);
483
622
  }
484
- buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0) {
485
- if (payload === null || !(0, import_is_plain_object.isPlainObject)(payload)) {
623
+ buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0, excludeKeys = []) {
624
+ if (payload === null || !(0, import_common_helpers.isPlainObject)(payload)) {
486
625
  return {
487
626
  conditions: [
488
627
  this.buildLiteralFilter(eb, lhs, type, payload)
@@ -496,22 +635,29 @@ var BaseCrudDialect = class {
496
635
  if (onlyForKeys && !onlyForKeys.includes(op)) {
497
636
  continue;
498
637
  }
638
+ if (excludeKeys.includes(op)) {
639
+ continue;
640
+ }
499
641
  const rhs = Array.isArray(value) ? value.map(getRhs) : getRhs(value);
500
- 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");
642
+ const condition = (0, import_ts_pattern2.match)(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
643
+ (0, import_common_helpers.invariant)(Array.isArray(rhs), "right hand side must be an array");
502
644
  if (rhs.length === 0) {
503
645
  return this.false(eb);
504
646
  } else {
505
647
  return eb(lhs, "in", rhs);
506
648
  }
507
649
  }).with("notIn", () => {
508
- (0, import_tiny_invariant.default)(Array.isArray(rhs), "right hand side must be an array");
650
+ (0, import_common_helpers.invariant)(Array.isArray(rhs), "right hand side must be an array");
509
651
  if (rhs.length === 0) {
510
652
  return this.true(eb);
511
653
  } else {
512
654
  return eb.not(eb(lhs, "in", rhs));
513
655
  }
514
- }).with("lt", () => eb(lhs, "<", rhs)).with("lte", () => eb(lhs, "<=", rhs)).with("gt", () => eb(lhs, ">", rhs)).with("gte", () => eb(lhs, ">=", rhs)).with("not", () => eb.not(recurse(value))).otherwise(() => {
656
+ }).with("lt", () => eb(lhs, "<", rhs)).with("lte", () => eb(lhs, "<=", rhs)).with("gt", () => eb(lhs, ">", rhs)).with("gte", () => eb(lhs, ">=", rhs)).with("not", () => eb.not(recurse(value))).with(import_ts_pattern2.P.union(...AGGREGATE_OPERATORS), (op2) => {
657
+ const innerResult = this.buildStandardFilter(eb, type, value, aggregate(eb, lhs, op2), getRhs, recurse, throwIfInvalid);
658
+ consumedKeys.push(...innerResult.consumedKeys);
659
+ return this.and(eb, ...innerResult.conditions);
660
+ }).otherwise(() => {
515
661
  if (throwIfInvalid) {
516
662
  throw new QueryError(`Invalid filter key: ${op}`);
517
663
  } else {
@@ -528,24 +674,21 @@ var BaseCrudDialect = class {
528
674
  consumedKeys
529
675
  };
530
676
  }
531
- buildStringFilter(eb, table, field, payload) {
532
- const fieldDef = getField(this.schema, table, field);
533
- let fieldRef = fieldDef?.computed ? import_kysely.sql.ref(field) : import_kysely.sql.ref(`${table}.${field}`);
534
- let insensitive = false;
535
- if (payload && typeof payload === "object" && "mode" in payload && payload.mode === "insensitive") {
536
- insensitive = true;
537
- fieldRef = eb.fn("lower", [
538
- fieldRef
539
- ]);
677
+ buildStringFilter(eb, fieldRef, payload) {
678
+ let mode;
679
+ if (payload && typeof payload === "object" && "mode" in payload) {
680
+ mode = payload.mode;
540
681
  }
541
- const { conditions, consumedKeys } = this.buildStandardFilter(eb, "String", payload, fieldRef, (value) => this.prepStringCasing(eb, value, insensitive), (value) => this.buildStringFilter(eb, table, field, value));
682
+ const { conditions, consumedKeys } = this.buildStandardFilter(eb, "String", payload, mode === "insensitive" ? eb.fn("lower", [
683
+ fieldRef
684
+ ]) : fieldRef, (value) => this.prepStringCasing(eb, value, mode), (value) => this.buildStringFilter(eb, fieldRef, value));
542
685
  if (payload && typeof payload === "object") {
543
686
  for (const [key, value] of Object.entries(payload)) {
544
687
  if (key === "mode" || consumedKeys.includes(key)) {
545
688
  continue;
546
689
  }
547
- const condition = (0, import_ts_pattern.match)(key).with("contains", () => insensitive ? eb(fieldRef, "ilike", import_kysely.sql.lit(`%${value}%`)) : eb(fieldRef, "like", import_kysely.sql.lit(`%${value}%`))).with("startsWith", () => insensitive ? eb(fieldRef, "ilike", import_kysely.sql.lit(`${value}%`)) : eb(fieldRef, "like", import_kysely.sql.lit(`${value}%`))).with("endsWith", () => insensitive ? eb(fieldRef, "ilike", import_kysely.sql.lit(`%${value}`)) : eb(fieldRef, "like", import_kysely.sql.lit(`%${value}`))).otherwise(() => {
548
- throw new Error(`Invalid string filter key: ${key}`);
690
+ 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(() => {
691
+ throw new QueryError(`Invalid string filter key: ${key}`);
549
692
  });
550
693
  if (condition) {
551
694
  conditions.push(condition);
@@ -554,34 +697,37 @@ var BaseCrudDialect = class {
554
697
  }
555
698
  return this.and(eb, ...conditions);
556
699
  }
557
- prepStringCasing(eb, value, toLower = true) {
700
+ prepStringCasing(eb, value, mode) {
701
+ if (!mode || mode === "default") {
702
+ return value === null ? value : import_kysely.sql.val(value);
703
+ }
558
704
  if (typeof value === "string") {
559
- return toLower ? eb.fn("lower", [
560
- import_kysely.sql.lit(value)
561
- ]) : import_kysely.sql.lit(value);
705
+ return eb.fn("lower", [
706
+ import_kysely.sql.val(value)
707
+ ]);
562
708
  } else if (Array.isArray(value)) {
563
- return value.map((v) => this.prepStringCasing(eb, v, toLower));
709
+ return value.map((v) => this.prepStringCasing(eb, v, mode));
564
710
  } else {
565
- return value === null ? null : import_kysely.sql.lit(value);
711
+ return value === null ? null : import_kysely.sql.val(value);
566
712
  }
567
713
  }
568
- 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));
714
+ buildNumberFilter(eb, fieldRef, type, payload) {
715
+ const { conditions } = this.buildStandardFilter(eb, type, payload, fieldRef, (value) => this.transformPrimitive(value, type, false), (value) => this.buildNumberFilter(eb, fieldRef, type, value));
570
716
  return this.and(eb, ...conditions);
571
717
  }
572
- 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, [
718
+ buildBooleanFilter(eb, fieldRef, payload) {
719
+ const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, fieldRef, (value) => this.transformPrimitive(value, "Boolean", false), (value) => this.buildBooleanFilter(eb, fieldRef, value), true, [
574
720
  "equals",
575
721
  "not"
576
722
  ]);
577
723
  return this.and(eb, ...conditions);
578
724
  }
579
- 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);
725
+ buildDateTimeFilter(eb, fieldRef, payload) {
726
+ const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, fieldRef, (value) => this.transformPrimitive(value, "DateTime", false), (value) => this.buildDateTimeFilter(eb, fieldRef, value), true);
581
727
  return this.and(eb, ...conditions);
582
728
  }
583
- 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, [
729
+ buildBytesFilter(eb, fieldRef, payload) {
730
+ const conditions = this.buildStandardFilter(eb, "Bytes", payload, fieldRef, (value) => this.transformPrimitive(value, "Bytes", false), (value) => this.buildBytesFilter(eb, fieldRef, value), true, [
585
731
  "equals",
586
732
  "in",
587
733
  "notIn",
@@ -589,8 +735,8 @@ var BaseCrudDialect = class {
589
735
  ]);
590
736
  return this.and(eb, ...conditions.conditions);
591
737
  }
592
- buildEnumFilter(eb, table, field, fieldDef, payload) {
593
- const conditions = this.buildStandardFilter(eb, "String", payload, import_kysely.sql.ref(`${table}.${field}`), (value) => value, (value) => this.buildEnumFilter(eb, table, field, fieldDef, value), true, [
738
+ buildEnumFilter(eb, fieldRef, fieldDef, payload) {
739
+ const conditions = this.buildStandardFilter(eb, "String", payload, fieldRef, (value) => value, (value) => this.buildEnumFilter(eb, fieldRef, fieldDef, value), true, [
594
740
  "equals",
595
741
  "in",
596
742
  "notIn",
@@ -619,21 +765,19 @@ var BaseCrudDialect = class {
619
765
  "_min",
620
766
  "_max"
621
767
  ].includes(field)) {
622
- (0, import_tiny_invariant.default)(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
768
+ (0, import_common_helpers.invariant)(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
623
769
  for (const [k, v] of Object.entries(value)) {
624
- (0, import_tiny_invariant.default)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
625
- result = result.orderBy((eb) => eb.fn(field.slice(1), [
626
- import_kysely.sql.ref(k)
627
- ]), import_kysely.sql.raw(this.negateSort(v, negated)));
770
+ (0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
771
+ result = result.orderBy((eb) => aggregate(eb, this.fieldRef(model, k, eb, modelAlias), field), import_kysely.sql.raw(this.negateSort(v, negated)));
628
772
  }
629
773
  continue;
630
774
  }
631
775
  switch (field) {
632
776
  case "_count": {
633
- (0, import_tiny_invariant.default)(value && typeof value === "object", 'invalid orderBy value for field "_count"');
777
+ (0, import_common_helpers.invariant)(value && typeof value === "object", 'invalid orderBy value for field "_count"');
634
778
  for (const [k, v] of Object.entries(value)) {
635
- (0, import_tiny_invariant.default)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
636
- result = result.orderBy((eb) => eb.fn.count(import_kysely.sql.ref(k)), import_kysely.sql.raw(this.negateSort(v, negated)));
779
+ (0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
780
+ result = result.orderBy((eb) => eb.fn.count(this.fieldRef(model, k, eb, modelAlias)), import_kysely.sql.raw(this.negateSort(v, negated)));
637
781
  }
638
782
  continue;
639
783
  }
@@ -642,10 +786,11 @@ var BaseCrudDialect = class {
642
786
  }
643
787
  const fieldDef = requireField(this.schema, model, field);
644
788
  if (!fieldDef.relation) {
789
+ const fieldRef = this.fieldRef(model, field, (0, import_kysely.expressionBuilder)(), modelAlias);
645
790
  if (value === "asc" || value === "desc") {
646
- result = result.orderBy(import_kysely.sql.ref(`${modelAlias}.${field}`), this.negateSort(value, negated));
791
+ result = result.orderBy(fieldRef, this.negateSort(value, negated));
647
792
  } else if (value && typeof value === "object" && "nulls" in value && "sort" in value && (value.sort === "asc" || value.sort === "desc") && (value.nulls === "first" || value.nulls === "last")) {
648
- result = result.orderBy(import_kysely.sql.ref(`${modelAlias}.${field}`), import_kysely.sql.raw(`${this.negateSort(value.sort, negated)} nulls ${value.nulls}`));
793
+ result = result.orderBy(fieldRef, import_kysely.sql.raw(`${this.negateSort(value.sort, negated)} nulls ${value.nulls}`));
649
794
  }
650
795
  } else {
651
796
  const relationModel = fieldDef.type;
@@ -654,10 +799,10 @@ var BaseCrudDialect = class {
654
799
  throw new QueryError(`invalid orderBy value for field "${field}"`);
655
800
  }
656
801
  if ("_count" in value) {
657
- (0, import_tiny_invariant.default)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
802
+ (0, import_common_helpers.invariant)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
658
803
  const sort = this.negateSort(value._count, negated);
659
804
  result = result.orderBy((eb) => {
660
- let subQuery = eb.selectFrom(relationModel);
805
+ let subQuery = this.buildSelectModel(eb, relationModel);
661
806
  const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, relationModel);
662
807
  subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely.sql.ref(left), "=", import_kysely.sql.ref(right)))));
663
808
  subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
@@ -676,14 +821,90 @@ var BaseCrudDialect = class {
676
821
  });
677
822
  return result;
678
823
  }
824
+ buildSelectAllFields(model, query, omit) {
825
+ const modelDef = requireModel(this.schema, model);
826
+ let result = query;
827
+ for (const field of Object.keys(modelDef.fields)) {
828
+ if (isRelationField(this.schema, model, field)) {
829
+ continue;
830
+ }
831
+ if (omit?.[field] === true) {
832
+ continue;
833
+ }
834
+ result = this.buildSelectField(result, model, model, field);
835
+ }
836
+ const descendants = getDelegateDescendantModels(this.schema, model);
837
+ for (const subModel of descendants) {
838
+ result = this.buildDelegateJoin(model, subModel.name, result);
839
+ result = result.select((eb) => {
840
+ const jsonObject = {};
841
+ for (const field of Object.keys(subModel.fields)) {
842
+ if (isRelationField(this.schema, subModel.name, field) || isInheritedField(this.schema, subModel.name, field)) {
843
+ continue;
844
+ }
845
+ jsonObject[field] = eb.ref(`${subModel.name}.${field}`);
846
+ }
847
+ return this.buildJsonObject(eb, jsonObject).as(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`);
848
+ });
849
+ }
850
+ return result;
851
+ }
852
+ buildSelectField(query, model, modelAlias, field) {
853
+ const fieldDef = requireField(this.schema, model, field);
854
+ if (fieldDef.computed) {
855
+ return query.select((eb) => this.fieldRef(model, field, eb, modelAlias).as(field));
856
+ } else if (!fieldDef.originModel) {
857
+ return query.select(import_kysely.sql.ref(`${modelAlias}.${field}`).as(field));
858
+ } else {
859
+ return this.buildSelectField(query, fieldDef.originModel, fieldDef.originModel, field);
860
+ }
861
+ }
862
+ buildDelegateJoin(thisModel, otherModel, query) {
863
+ const idFields = getIdFields(this.schema, thisModel);
864
+ query = query.leftJoin(otherModel, (qb) => {
865
+ for (const idField of idFields) {
866
+ qb = qb.onRef(`${thisModel}.${idField}`, "=", `${otherModel}.${idField}`);
867
+ }
868
+ return qb;
869
+ });
870
+ return query;
871
+ }
872
+ buildCountJson(model, eb, parentAlias, payload) {
873
+ const modelDef = requireModel(this.schema, model);
874
+ const toManyRelations = Object.entries(modelDef.fields).filter(([, field]) => field.relation && field.array);
875
+ const selections = payload === true ? {
876
+ select: toManyRelations.reduce((acc, [field]) => {
877
+ acc[field] = true;
878
+ return acc;
879
+ }, {})
880
+ } : payload;
881
+ const jsonObject = {};
882
+ for (const [field, value] of Object.entries(selections.select)) {
883
+ const fieldDef = requireField(this.schema, model, field);
884
+ const fieldModel = fieldDef.type;
885
+ const joinPairs = buildJoinPairs(this.schema, model, parentAlias, field, fieldModel);
886
+ let fieldCountQuery = eb.selectFrom(fieldModel).select(eb.fn.countAll().as(`_count$${field}`));
887
+ for (const [left, right] of joinPairs) {
888
+ fieldCountQuery = fieldCountQuery.whereRef(left, "=", right);
889
+ }
890
+ if (value && typeof value === "object" && "where" in value && value.where && typeof value.where === "object") {
891
+ const filter = this.buildFilter(eb, fieldModel, fieldModel, value.where);
892
+ fieldCountQuery = fieldCountQuery.where(filter);
893
+ }
894
+ jsonObject[field] = fieldCountQuery;
895
+ }
896
+ return this.buildJsonObject(eb, jsonObject);
897
+ }
898
+ // #endregion
899
+ // #region utils
679
900
  negateSort(sort, negated) {
680
901
  return negated ? sort === "asc" ? "desc" : "asc" : sort;
681
902
  }
682
903
  true(eb) {
683
- return eb.lit(this.transformPrimitive(true, "Boolean"));
904
+ return eb.lit(this.transformPrimitive(true, "Boolean", false));
684
905
  }
685
906
  false(eb) {
686
- return eb.lit(this.transformPrimitive(false, "Boolean"));
907
+ return eb.lit(this.transformPrimitive(false, "Boolean", false));
687
908
  }
688
909
  isTrue(expression) {
689
910
  const node = expression.toOperationNode();
@@ -722,6 +943,9 @@ var BaseCrudDialect = class {
722
943
  not(eb, ...args) {
723
944
  return eb.not(this.and(eb, ...args));
724
945
  }
946
+ fieldRef(model, field, eb, modelAlias) {
947
+ return buildFieldRef(this.schema, model, field, this.options, eb, modelAlias);
948
+ }
725
949
  };
726
950
 
727
951
  // src/client/crud/dialects/postgresql.ts
@@ -732,14 +956,18 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
732
956
  get provider() {
733
957
  return "postgresql";
734
958
  }
735
- transformPrimitive(value, type) {
959
+ transformPrimitive(value, type, forArrayField) {
736
960
  if (value === void 0) {
737
961
  return value;
738
962
  }
739
963
  if (Array.isArray(value)) {
740
- return value.map((v) => this.transformPrimitive(v, type));
964
+ if (type === "Json" && !forArrayField) {
965
+ return JSON.stringify(value);
966
+ } else {
967
+ return value.map((v) => this.transformPrimitive(v, type, false));
968
+ }
741
969
  } else {
742
- return (0, import_ts_pattern2.match)(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).otherwise(() => value);
970
+ return (0, import_ts_pattern3.match)(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).with("Decimal", () => value !== null ? value.toString() : value).otherwise(() => value);
743
971
  }
744
972
  }
745
973
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
@@ -753,7 +981,8 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
753
981
  const joinTableName = `${parentName}$${relationField}`;
754
982
  let result = eb.selectFrom(`${relationModel} as ${joinTableName}`);
755
983
  result = eb.selectFrom(() => {
756
- let subQuery = eb.selectFrom(`${relationModel}`).selectAll();
984
+ let subQuery = this.buildSelectModel(eb, relationModel);
985
+ subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
757
986
  if (payload && typeof payload === "object") {
758
987
  if (payload.where) {
759
988
  subQuery = subQuery.where((eb2) => this.buildFilter(eb2, relationModel, relationModel, payload.where));
@@ -772,8 +1001,8 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
772
1001
  if (m2m) {
773
1002
  const parentIds = getIdFields(this.schema, model);
774
1003
  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");
1004
+ (0, import_common_helpers2.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1005
+ (0, import_common_helpers2.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
777
1006
  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
1007
  } else {
779
1008
  const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, relationModel);
@@ -797,34 +1026,57 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
797
1026
  });
798
1027
  return qb;
799
1028
  }
800
- buildRelationObjectArgs(relationModel, relationField, eb, payload, parentName) {
1029
+ buildRelationObjectArgs(relationModel, relationField, eb, payload, parentAlias) {
801
1030
  const relationModelDef = requireModel(this.schema, relationModel);
802
1031
  const objArgs = [];
1032
+ const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
1033
+ if (descendantModels.length > 0) {
1034
+ objArgs.push(...descendantModels.map((subModel) => [
1035
+ import_kysely2.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1036
+ eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
1037
+ ]).flatMap((v) => v));
1038
+ }
803
1039
  if (payload === true || !payload.select) {
804
1040
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
805
1041
  import_kysely2.sql.lit(field),
806
- buildFieldRef(this.schema, relationModel, field, this.options, eb)
1042
+ this.fieldRef(relationModel, field, eb)
807
1043
  ]).flatMap((v) => v));
808
1044
  } 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));
1045
+ objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
1046
+ if (field === "_count") {
1047
+ const subJson = this.buildCountJson(relationModel, eb, `${parentAlias}$${relationField}`, value);
1048
+ return [
1049
+ import_kysely2.sql.lit(field),
1050
+ subJson
1051
+ ];
1052
+ } else {
1053
+ const fieldDef = requireField(this.schema, relationModel, field);
1054
+ const fieldValue = fieldDef.relation ? eb.ref(`${parentAlias}$${relationField}$${field}.$j`) : this.fieldRef(relationModel, field, eb);
1055
+ return [
1056
+ import_kysely2.sql.lit(field),
1057
+ fieldValue
1058
+ ];
1059
+ }
1060
+ }).flatMap((v) => v));
813
1061
  }
814
1062
  if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
815
1063
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field]) => [
816
1064
  import_kysely2.sql.lit(field),
817
- eb.ref(`${parentName}$${relationField}$${field}.$j`)
1065
+ // reference the synthesized JSON field
1066
+ eb.ref(`${parentAlias}$${relationField}$${field}.$j`)
818
1067
  ]).flatMap((v) => v));
819
1068
  }
820
1069
  return objArgs;
821
1070
  }
822
- buildRelationJoins(model, relationField, qb, payload, parentName) {
1071
+ buildRelationJoins(relationModel, relationField, qb, payload, parentName) {
823
1072
  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
- });
1073
+ if (typeof payload === "object") {
1074
+ const selectInclude = payload.include ?? payload.select;
1075
+ if (selectInclude && typeof selectInclude === "object") {
1076
+ Object.entries(selectInclude).filter(([, value]) => value).filter(([field]) => isRelationField(this.schema, relationModel, field)).forEach(([field, value]) => {
1077
+ result = this.buildRelationJSON(relationModel, result, field, `${parentName}$${relationField}`, value);
1078
+ });
1079
+ }
828
1080
  }
829
1081
  return result;
830
1082
  }
@@ -864,12 +1116,15 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
864
1116
  return `ARRAY[${values.map((v) => typeof v === "string" ? `'${v}'` : v)}]`;
865
1117
  }
866
1118
  }
1119
+ get supportInsertWithDefault() {
1120
+ return true;
1121
+ }
867
1122
  };
868
1123
 
869
1124
  // src/client/crud/dialects/sqlite.ts
1125
+ var import_common_helpers3 = require("@zenstackhq/common-helpers");
870
1126
  var import_kysely3 = require("kysely");
871
- var import_tiny_invariant3 = __toESM(require("tiny-invariant"), 1);
872
- var import_ts_pattern3 = require("ts-pattern");
1127
+ var import_ts_pattern4 = require("ts-pattern");
873
1128
  var SqliteCrudDialect = class extends BaseCrudDialect {
874
1129
  static {
875
1130
  __name(this, "SqliteCrudDialect");
@@ -877,26 +1132,31 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
877
1132
  get provider() {
878
1133
  return "sqlite";
879
1134
  }
880
- transformPrimitive(value, type) {
1135
+ transformPrimitive(value, type, _forArrayField) {
881
1136
  if (value === void 0) {
882
1137
  return value;
883
1138
  }
884
1139
  if (Array.isArray(value)) {
885
- return value.map((v) => this.transformPrimitive(v, type));
1140
+ return value.map((v) => this.transformPrimitive(v, type, false));
886
1141
  } 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);
1142
+ if (this.schema.typeDefs && type in this.schema.typeDefs) {
1143
+ return JSON.stringify(value);
1144
+ } else {
1145
+ return (0, import_ts_pattern4.match)(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => value instanceof Date ? value.toISOString() : value).with("Decimal", () => value.toString()).with("Bytes", () => Buffer.from(value)).with("Json", () => JSON.stringify(value)).otherwise(() => value);
1146
+ }
888
1147
  }
889
1148
  }
890
1149
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
891
1150
  return query.select((eb) => this.buildRelationJSON(model, eb, relationField, parentAlias, payload).as(relationField));
892
1151
  }
893
- buildRelationJSON(model, eb, relationField, parentName, payload) {
1152
+ buildRelationJSON(model, eb, relationField, parentAlias, payload) {
894
1153
  const relationFieldDef = requireField(this.schema, model, relationField);
895
1154
  const relationModel = relationFieldDef.type;
896
1155
  const relationModelDef = requireModel(this.schema, relationModel);
897
- const subQueryName = `${parentName}$${relationField}`;
1156
+ const subQueryName = `${parentAlias}$${relationField}`;
898
1157
  let tbl = eb.selectFrom(() => {
899
- let subQuery = eb.selectFrom(relationModel).selectAll();
1158
+ let subQuery = this.buildSelectModel(eb, relationModel);
1159
+ subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
900
1160
  if (payload && typeof payload === "object") {
901
1161
  if (payload.where) {
902
1162
  subQuery = subQuery.where((eb2) => this.buildFilter(eb2, relationModel, relationModel, payload.where));
@@ -915,16 +1175,16 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
915
1175
  if (m2m) {
916
1176
  const parentIds = getIdFields(this.schema, model);
917
1177
  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");
920
- 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}`)));
1178
+ (0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1179
+ (0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1180
+ subQuery = subQuery.where(eb(eb.ref(`${relationModel}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
921
1181
  } else {
922
1182
  const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
923
1183
  keyPairs.forEach(({ fk, pk }) => {
924
1184
  if (ownedByModel) {
925
- subQuery = subQuery.whereRef(`${relationModel}.${pk}`, "=", `${parentName}.${fk}`);
1185
+ subQuery = subQuery.whereRef(`${relationModel}.${pk}`, "=", `${parentAlias}.${fk}`);
926
1186
  } else {
927
- subQuery = subQuery.whereRef(`${relationModel}.${fk}`, "=", `${parentName}.${pk}`);
1187
+ subQuery = subQuery.whereRef(`${relationModel}.${fk}`, "=", `${parentAlias}.${pk}`);
928
1188
  }
929
1189
  });
930
1190
  }
@@ -932,31 +1192,46 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
932
1192
  });
933
1193
  tbl = tbl.select(() => {
934
1194
  const objArgs = [];
1195
+ const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
1196
+ if (descendantModels.length > 0) {
1197
+ objArgs.push(...descendantModels.map((subModel) => [
1198
+ import_kysely3.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1199
+ eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
1200
+ ]).flatMap((v) => v));
1201
+ }
935
1202
  if (payload === true || !payload.select) {
936
1203
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
937
1204
  import_kysely3.sql.lit(field),
938
- buildFieldRef(this.schema, relationModel, field, this.options, eb)
1205
+ this.fieldRef(relationModel, field, eb)
939
1206
  ]).flatMap((v) => v));
940
1207
  } else if (payload.select) {
941
1208
  objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
942
- const fieldDef = requireField(this.schema, relationModel, field);
943
- if (fieldDef.relation) {
944
- const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentName}$${relationField}`, value);
1209
+ if (field === "_count") {
1210
+ const subJson = this.buildCountJson(relationModel, eb, `${parentAlias}$${relationField}`, value);
945
1211
  return [
946
1212
  import_kysely3.sql.lit(field),
947
1213
  subJson
948
1214
  ];
949
1215
  } else {
950
- return [
951
- import_kysely3.sql.lit(field),
952
- buildFieldRef(this.schema, relationModel, field, this.options, eb)
953
- ];
1216
+ const fieldDef = requireField(this.schema, relationModel, field);
1217
+ if (fieldDef.relation) {
1218
+ const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
1219
+ return [
1220
+ import_kysely3.sql.lit(field),
1221
+ subJson
1222
+ ];
1223
+ } else {
1224
+ return [
1225
+ import_kysely3.sql.lit(field),
1226
+ this.fieldRef(relationModel, field, eb)
1227
+ ];
1228
+ }
954
1229
  }
955
1230
  }).flatMap((v) => v));
956
1231
  }
957
1232
  if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
958
1233
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field, value]) => {
959
- const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentName}$${relationField}`, value);
1234
+ const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
960
1235
  return [
961
1236
  import_kysely3.sql.lit(field),
962
1237
  subJson
@@ -1006,93 +1281,17 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1006
1281
  buildArrayLiteralSQL(_values) {
1007
1282
  throw new Error("SQLite does not support array literals");
1008
1283
  }
1284
+ get supportInsertWithDefault() {
1285
+ return false;
1286
+ }
1009
1287
  };
1010
1288
 
1011
1289
  // src/client/crud/dialects/index.ts
1012
1290
  function getCrudDialect(schema, options) {
1013
- return (0, import_ts_pattern4.match)(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
1291
+ return (0, import_ts_pattern5.match)(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
1014
1292
  }
1015
1293
  __name(getCrudDialect, "getCrudDialect");
1016
1294
 
1017
- // src/schema/expression.ts
1018
- var ExpressionUtils = {
1019
- literal: /* @__PURE__ */ __name((value) => {
1020
- return {
1021
- kind: "literal",
1022
- value
1023
- };
1024
- }, "literal"),
1025
- array: /* @__PURE__ */ __name((items) => {
1026
- return {
1027
- kind: "array",
1028
- items
1029
- };
1030
- }, "array"),
1031
- call: /* @__PURE__ */ __name((functionName, args) => {
1032
- return {
1033
- kind: "call",
1034
- function: functionName,
1035
- args
1036
- };
1037
- }, "call"),
1038
- binary: /* @__PURE__ */ __name((left, op, right) => {
1039
- return {
1040
- kind: "binary",
1041
- op,
1042
- left,
1043
- right
1044
- };
1045
- }, "binary"),
1046
- unary: /* @__PURE__ */ __name((op, operand) => {
1047
- return {
1048
- kind: "unary",
1049
- op,
1050
- operand
1051
- };
1052
- }, "unary"),
1053
- field: /* @__PURE__ */ __name((field) => {
1054
- return {
1055
- kind: "field",
1056
- field
1057
- };
1058
- }, "field"),
1059
- member: /* @__PURE__ */ __name((receiver, members) => {
1060
- return {
1061
- kind: "member",
1062
- receiver,
1063
- members
1064
- };
1065
- }, "member"),
1066
- _this: /* @__PURE__ */ __name(() => {
1067
- return {
1068
- kind: "this"
1069
- };
1070
- }, "_this"),
1071
- _null: /* @__PURE__ */ __name(() => {
1072
- return {
1073
- kind: "null"
1074
- };
1075
- }, "_null"),
1076
- and: /* @__PURE__ */ __name((expr2, ...expressions) => {
1077
- return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "&&", exp), expr2);
1078
- }, "and"),
1079
- or: /* @__PURE__ */ __name((expr2, ...expressions) => {
1080
- return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
1081
- }, "or"),
1082
- is: /* @__PURE__ */ __name((value, kind) => {
1083
- return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
1084
- }, "is"),
1085
- isLiteral: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "literal"), "isLiteral"),
1086
- isArray: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "array"), "isArray"),
1087
- isCall: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "call"), "isCall"),
1088
- isNull: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "null"), "isNull"),
1089
- isThis: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "this"), "isThis"),
1090
- isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
1091
- isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
1092
- isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
1093
- isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
1094
- };
1095
-
1096
1295
  // src/utils/default-operation-node-visitor.ts
1097
1296
  var import_kysely4 = require("kysely");
1098
1297
  var DefaultOperationNodeVisitor = class extends import_kysely4.OperationNodeVisitor {
@@ -1412,19 +1611,19 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
1412
1611
  };
1413
1612
 
1414
1613
  // src/plugins/policy/expression-transformer.ts
1614
+ var import_common_helpers5 = require("@zenstackhq/common-helpers");
1415
1615
  var import_kysely6 = require("kysely");
1416
- var import_tiny_invariant5 = __toESM(require("tiny-invariant"), 1);
1417
- var import_ts_pattern6 = require("ts-pattern");
1616
+ var import_ts_pattern7 = require("ts-pattern");
1418
1617
 
1419
1618
  // src/plugins/policy/expression-evaluator.ts
1420
- var import_tiny_invariant4 = __toESM(require("tiny-invariant"), 1);
1421
- var import_ts_pattern5 = require("ts-pattern");
1619
+ var import_common_helpers4 = require("@zenstackhq/common-helpers");
1620
+ var import_ts_pattern6 = require("ts-pattern");
1422
1621
  var ExpressionEvaluator = class {
1423
1622
  static {
1424
1623
  __name(this, "ExpressionEvaluator");
1425
1624
  }
1426
1625
  evaluate(expression, context) {
1427
- const result = (0, import_ts_pattern5.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();
1626
+ 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();
1428
1627
  return result ?? null;
1429
1628
  }
1430
1629
  evaluateCall(expr2, context) {
@@ -1435,7 +1634,7 @@ var ExpressionEvaluator = class {
1435
1634
  }
1436
1635
  }
1437
1636
  evaluateUnary(expr2, context) {
1438
- return (0, import_ts_pattern5.match)(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1637
+ return (0, import_ts_pattern6.match)(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1439
1638
  }
1440
1639
  evaluateMember(expr2, context) {
1441
1640
  let val = this.evaluate(expr2.receiver, context);
@@ -1459,21 +1658,21 @@ var ExpressionEvaluator = class {
1459
1658
  }
1460
1659
  const left = this.evaluate(expr2.left, context);
1461
1660
  const right = this.evaluate(expr2.right, context);
1462
- 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", () => {
1661
+ 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", () => {
1463
1662
  const _right = right ?? [];
1464
- (0, import_tiny_invariant4.default)(Array.isArray(_right), 'expected array for "in" operator');
1663
+ (0, import_common_helpers4.invariant)(Array.isArray(_right), 'expected array for "in" operator');
1465
1664
  return _right.includes(left);
1466
1665
  }).exhaustive();
1467
1666
  }
1468
1667
  evaluateCollectionPredicate(expr2, context) {
1469
1668
  const op = expr2.op;
1470
- (0, import_tiny_invariant4.default)(op === "?" || op === "!" || op === "^", 'expected "?" or "!" or "^" operator');
1669
+ (0, import_common_helpers4.invariant)(op === "?" || op === "!" || op === "^", 'expected "?" or "!" or "^" operator');
1471
1670
  const left = this.evaluate(expr2.left, context);
1472
1671
  if (!left) {
1473
1672
  return false;
1474
1673
  }
1475
- (0, import_tiny_invariant4.default)(Array.isArray(left), "expected array");
1476
- return (0, import_ts_pattern5.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1674
+ (0, import_common_helpers4.invariant)(Array.isArray(left), "expected array");
1675
+ return (0, import_ts_pattern6.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1477
1676
  ...context,
1478
1677
  thisValue: item
1479
1678
  }))).with("!", () => left.every((item) => this.evaluate(expr2.right, {
@@ -1489,11 +1688,11 @@ var ExpressionEvaluator = class {
1489
1688
  // src/plugins/policy/utils.ts
1490
1689
  var import_kysely5 = require("kysely");
1491
1690
  function trueNode(dialect) {
1492
- return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean"));
1691
+ return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean", false));
1493
1692
  }
1494
1693
  __name(trueNode, "trueNode");
1495
1694
  function falseNode(dialect) {
1496
- return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean"));
1695
+ return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean", false));
1497
1696
  }
1498
1697
  __name(falseNode, "falseNode");
1499
1698
  function isTrueNode(node) {
@@ -1694,20 +1893,20 @@ var ExpressionTransformer = class {
1694
1893
  return import_kysely6.BinaryOperationNode.create(left, this.transformOperator(op), right);
1695
1894
  }
1696
1895
  transformCollectionPredicate(expr2, context) {
1697
- (0, import_tiny_invariant5.default)(expr2.op === "?" || expr2.op === "!" || expr2.op === "^", 'expected "?" or "!" or "^" operator');
1896
+ (0, import_common_helpers5.invariant)(expr2.op === "?" || expr2.op === "!" || expr2.op === "^", 'expected "?" or "!" or "^" operator');
1698
1897
  if (this.isAuthCall(expr2.left) || this.isAuthMember(expr2.left)) {
1699
1898
  const value = new ExpressionEvaluator().evaluate(expr2, {
1700
1899
  auth: this.auth
1701
1900
  });
1702
1901
  return this.transformValue(value, "Boolean");
1703
1902
  }
1704
- (0, import_tiny_invariant5.default)(ExpressionUtils.isField(expr2.left) || ExpressionUtils.isMember(expr2.left), "left operand must be field or member access");
1903
+ (0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.left) || ExpressionUtils.isMember(expr2.left), "left operand must be field or member access");
1705
1904
  let newContextModel;
1706
1905
  if (ExpressionUtils.isField(expr2.left)) {
1707
1906
  const fieldDef = requireField(this.schema, context.model, expr2.left.field);
1708
1907
  newContextModel = fieldDef.type;
1709
1908
  } else {
1710
- (0, import_tiny_invariant5.default)(ExpressionUtils.isField(expr2.left.receiver));
1909
+ (0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.left.receiver));
1711
1910
  const fieldDef = requireField(this.schema, context.model, expr2.left.receiver.field);
1712
1911
  newContextModel = fieldDef.type;
1713
1912
  for (const member of expr2.left.members) {
@@ -1727,7 +1926,7 @@ var ExpressionTransformer = class {
1727
1926
  const count = import_kysely6.FunctionNode.create("count", [
1728
1927
  import_kysely6.ValueNode.createImmediate(1)
1729
1928
  ]);
1730
- const predicateResult = (0, import_ts_pattern6.match)(expr2.op).with("?", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create(">"), import_kysely6.ValueNode.createImmediate(0))).with("!", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create("="), import_kysely6.ValueNode.createImmediate(0))).with("^", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create("="), import_kysely6.ValueNode.createImmediate(0))).exhaustive();
1929
+ const predicateResult = (0, import_ts_pattern7.match)(expr2.op).with("?", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create(">"), import_kysely6.ValueNode.createImmediate(0))).with("!", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create("="), import_kysely6.ValueNode.createImmediate(0))).with("^", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create("="), import_kysely6.ValueNode.createImmediate(0))).exhaustive();
1731
1930
  return this.transform(expr2.left, {
1732
1931
  ...context,
1733
1932
  memberSelect: import_kysely6.SelectionNode.create(import_kysely6.AliasNode.create(predicateResult, import_kysely6.IdentifierNode.create("$t"))),
@@ -1751,14 +1950,14 @@ var ExpressionTransformer = class {
1751
1950
  }
1752
1951
  }
1753
1952
  transformValue(value, type) {
1754
- return import_kysely6.ValueNode.create(this.dialect.transformPrimitive(value, type) ?? null);
1953
+ return import_kysely6.ValueNode.create(this.dialect.transformPrimitive(value, type, false) ?? null);
1755
1954
  }
1756
1955
  _unary(expr2, context) {
1757
- (0, import_tiny_invariant5.default)(expr2.op === "!", 'only "!" operator is supported');
1956
+ (0, import_common_helpers5.invariant)(expr2.op === "!", 'only "!" operator is supported');
1758
1957
  return import_kysely6.BinaryOperationNode.create(this.transform(expr2.operand, context), this.transformOperator("!="), trueNode(this.dialect));
1759
1958
  }
1760
1959
  transformOperator(op) {
1761
- const mappedOp = (0, import_ts_pattern6.match)(op).with("==", () => "=").otherwise(() => op);
1960
+ const mappedOp = (0, import_ts_pattern7.match)(op).with("==", () => "=").otherwise(() => op);
1762
1961
  return import_kysely6.OperatorNode.create(mappedOp);
1763
1962
  }
1764
1963
  _call(expr2, context) {
@@ -1797,10 +1996,10 @@ var ExpressionTransformer = class {
1797
1996
  if (this.isAuthCall(expr2.receiver)) {
1798
1997
  return this.valueMemberAccess(this.auth, expr2, this.authType);
1799
1998
  }
1800
- (0, import_tiny_invariant5.default)(ExpressionUtils.isField(expr2.receiver), "expect receiver to be field expression");
1999
+ (0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.receiver), "expect receiver to be field expression");
1801
2000
  const { memberFilter, memberSelect, ...restContext } = context;
1802
2001
  const receiver = this.transform(expr2.receiver, restContext);
1803
- (0, import_tiny_invariant5.default)(import_kysely6.SelectQueryNode.is(receiver), "expected receiver to be select query");
2002
+ (0, import_common_helpers5.invariant)(import_kysely6.SelectQueryNode.is(receiver), "expected receiver to be select query");
1804
2003
  const receiverField = requireField(this.schema, context.model, expr2.receiver.field);
1805
2004
  const memberFields = [];
1806
2005
  let currType = receiverField.type;
@@ -1824,7 +2023,7 @@ var ExpressionTransformer = class {
1824
2023
  thisEntity: void 0
1825
2024
  });
1826
2025
  if (currNode) {
1827
- (0, import_tiny_invariant5.default)(import_kysely6.SelectQueryNode.is(currNode), "expected select query node");
2026
+ (0, import_common_helpers5.invariant)(import_kysely6.SelectQueryNode.is(currNode), "expected select query node");
1828
2027
  currNode = {
1829
2028
  ...relation,
1830
2029
  selections: [
@@ -1841,8 +2040,8 @@ var ExpressionTransformer = class {
1841
2040
  };
1842
2041
  }
1843
2042
  } 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");
2043
+ (0, import_common_helpers5.invariant)(i === expr2.members.length - 1, "plain field access must be the last segment");
2044
+ (0, import_common_helpers5.invariant)(!currNode, "plain field access must be the last segment");
1846
2045
  currNode = import_kysely6.ColumnNode.create(member);
1847
2046
  }
1848
2047
  }
@@ -1994,7 +2193,7 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
1994
2193
  get kysely() {
1995
2194
  return this.client.$qb;
1996
2195
  }
1997
- async handle(node, proceed, transaction) {
2196
+ async handle(node, proceed) {
1998
2197
  if (!this.isCrudQueryNode(node)) {
1999
2198
  throw new RejectedByPolicyError(void 0, "non-CRUD queries are not allowed");
2000
2199
  }
@@ -2014,27 +2213,20 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2014
2213
  if (!mutationRequiresTransaction && !node.returning) {
2015
2214
  return proceed(this.transformNode(node));
2016
2215
  }
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;
2216
+ if (import_kysely7.InsertQueryNode.is(node)) {
2217
+ await this.enforcePreCreatePolicy(node, proceed);
2218
+ }
2219
+ const transformedNode = this.transformNode(node);
2220
+ const result = await proceed(transformedNode);
2221
+ if (!this.onlyReturningId(node)) {
2222
+ const readBackResult = await this.processReadBack(node, result, proceed);
2223
+ if (readBackResult.rows.length !== result.rows.length) {
2224
+ throw new RejectedByPolicyError(mutationModel, "result is not allowed to be read back");
2032
2225
  }
2033
- });
2034
- if (readBackError) {
2035
- throw new RejectedByPolicyError(mutationModel, "result is not allowed to be read back");
2226
+ return readBackResult;
2227
+ } else {
2228
+ return result;
2036
2229
  }
2037
- return result;
2038
2230
  }
2039
2231
  onlyReturningId(node) {
2040
2232
  if (!node.returning) {
@@ -2087,19 +2279,19 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2087
2279
  }
2088
2280
  }
2089
2281
  unwrapCreateValueRow(data, model, fields) {
2090
- (0, import_tiny_invariant6.default)(data.length === fields.length, "data length must match fields length");
2282
+ (0, import_common_helpers6.invariant)(data.length === fields.length, "data length must match fields length");
2091
2283
  const result = [];
2092
2284
  for (let i = 0; i < data.length; i++) {
2093
2285
  const item = data[i];
2094
2286
  const fieldDef = requireField(this.client.$schema, model, fields[i]);
2095
2287
  if (typeof item === "object" && item && "kind" in item) {
2096
- (0, import_tiny_invariant6.default)(item.kind === "ValueNode", "expecting a ValueNode");
2288
+ (0, import_common_helpers6.invariant)(item.kind === "ValueNode", "expecting a ValueNode");
2097
2289
  result.push({
2098
- node: import_kysely7.ValueNode.create(this.dialect.transformPrimitive(item.value, fieldDef.type)),
2290
+ node: import_kysely7.ValueNode.create(this.dialect.transformPrimitive(item.value, fieldDef.type, !!fieldDef.array)),
2099
2291
  raw: item.value
2100
2292
  });
2101
2293
  } else {
2102
- const value = this.dialect.transformPrimitive(item, fieldDef.type);
2294
+ const value = this.dialect.transformPrimitive(item, fieldDef.type, !!fieldDef.array);
2103
2295
  if (Array.isArray(value)) {
2104
2296
  result.push({
2105
2297
  node: import_kysely7.RawNode.createWithSql(this.dialect.buildArrayLiteralSQL(value)),
@@ -2168,7 +2360,7 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2168
2360
  return disjunction(this.dialect, rows.map((row) => conjunction(this.dialect, idFields.map((field) => import_kysely7.BinaryOperationNode.create(import_kysely7.ColumnNode.create(field), import_kysely7.OperatorNode.create("="), import_kysely7.ValueNode.create(row[field]))))));
2169
2361
  }
2170
2362
  getMutationModel(node) {
2171
- const r = (0, import_ts_pattern7.match)(node).when(import_kysely7.InsertQueryNode.is, (node2) => getTableName(node2.into)).when(import_kysely7.UpdateQueryNode.is, (node2) => getTableName(node2.table)).when(import_kysely7.DeleteQueryNode.is, (node2) => {
2363
+ const r = (0, import_ts_pattern8.match)(node).when(import_kysely7.InsertQueryNode.is, (node2) => getTableName(node2.into)).when(import_kysely7.UpdateQueryNode.is, (node2) => getTableName(node2.table)).when(import_kysely7.DeleteQueryNode.is, (node2) => {
2172
2364
  if (node2.from.froms.length !== 1) {
2173
2365
  throw new InternalError("Only one from table is supported for delete");
2174
2366
  }
@@ -2301,8 +2493,8 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2301
2493
  const modelDef = requireModel(this.client.$schema, modelName);
2302
2494
  const result = [];
2303
2495
  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");
2496
+ (0, import_common_helpers6.invariant)(ExpressionUtils.isLiteral(expr2), "expecting a literal");
2497
+ (0, import_common_helpers6.invariant)(typeof expr2.value === "string", "expecting a string literal");
2306
2498
  return expr2.value.split(",").filter((v) => !!v).map((v) => v.trim());
2307
2499
  }, "extractOperations");
2308
2500
  if (modelDef.attributes) {
@@ -2330,9 +2522,18 @@ var PolicyPlugin = class {
2330
2522
  get description() {
2331
2523
  return "Enforces access policies defined in the schema.";
2332
2524
  }
2333
- onKyselyQuery({ query, client, proceed, transaction }) {
2525
+ onKyselyQuery({
2526
+ query,
2527
+ client,
2528
+ proceed
2529
+ /*, transaction*/
2530
+ }) {
2334
2531
  const handler = new PolicyHandler(client);
2335
- return handler.handle(query, proceed, transaction);
2532
+ return handler.handle(
2533
+ query,
2534
+ proceed
2535
+ /*, transaction*/
2536
+ );
2336
2537
  }
2337
2538
  };
2338
2539
  // Annotate the CommonJS export names for ESM import in node:
@@ -2340,4 +2541,4 @@ var PolicyPlugin = class {
2340
2541
  PolicyPlugin,
2341
2542
  RejectedByPolicyError
2342
2543
  });
2343
- //# sourceMappingURL=policy.cjs.map
2544
+ //# sourceMappingURL=index.cjs.map