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

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-XFKcwhq7.d.cts} +970 -785
  2. package/dist/{contract-DguafRNB.d.ts → contract-XFKcwhq7.d.ts} +970 -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 +1774 -892
  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 +1724 -847
  14. package/dist/index.js.map +1 -1
  15. package/dist/plugins/{policy.cjs → policy/index.cjs} +463 -266
  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} +435 -228
  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 = buildFieldRef(this.schema, fieldDef.originModel ?? model, key, this.options, 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,20 +765,18 @@ 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, import_kysely.sql.ref(`${modelAlias}.${k}`), 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}"`);
779
+ (0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
636
780
  result = result.orderBy((eb) => eb.fn.count(import_kysely.sql.ref(k)), import_kysely.sql.raw(this.negateSort(v, negated)));
637
781
  }
638
782
  continue;
@@ -654,10 +798,10 @@ var BaseCrudDialect = class {
654
798
  throw new QueryError(`invalid orderBy value for field "${field}"`);
655
799
  }
656
800
  if ("_count" in value) {
657
- (0, import_tiny_invariant.default)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
801
+ (0, import_common_helpers.invariant)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
658
802
  const sort = this.negateSort(value._count, negated);
659
803
  result = result.orderBy((eb) => {
660
- let subQuery = eb.selectFrom(relationModel);
804
+ let subQuery = this.buildSelectModel(eb, relationModel);
661
805
  const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, relationModel);
662
806
  subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely.sql.ref(left), "=", import_kysely.sql.ref(right)))));
663
807
  subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
@@ -676,14 +820,90 @@ var BaseCrudDialect = class {
676
820
  });
677
821
  return result;
678
822
  }
823
+ buildSelectAllFields(model, query, omit) {
824
+ const modelDef = requireModel(this.schema, model);
825
+ let result = query;
826
+ for (const field of Object.keys(modelDef.fields)) {
827
+ if (isRelationField(this.schema, model, field)) {
828
+ continue;
829
+ }
830
+ if (omit?.[field] === true) {
831
+ continue;
832
+ }
833
+ result = this.buildSelectField(result, model, model, field);
834
+ }
835
+ const descendants = getDelegateDescendantModels(this.schema, model);
836
+ for (const subModel of descendants) {
837
+ result = this.buildDelegateJoin(model, subModel.name, result);
838
+ result = result.select((eb) => {
839
+ const jsonObject = {};
840
+ for (const field of Object.keys(subModel.fields)) {
841
+ if (isRelationField(this.schema, subModel.name, field) || isInheritedField(this.schema, subModel.name, field)) {
842
+ continue;
843
+ }
844
+ jsonObject[field] = eb.ref(`${subModel.name}.${field}`);
845
+ }
846
+ return this.buildJsonObject(eb, jsonObject).as(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`);
847
+ });
848
+ }
849
+ return result;
850
+ }
851
+ buildSelectField(query, model, modelAlias, field) {
852
+ const fieldDef = requireField(this.schema, model, field);
853
+ if (fieldDef.computed) {
854
+ return query.select((eb) => buildFieldRef(this.schema, model, field, this.options, eb).as(field));
855
+ } else if (!fieldDef.originModel) {
856
+ return query.select(import_kysely.sql.ref(`${modelAlias}.${field}`).as(field));
857
+ } else {
858
+ return this.buildSelectField(query, fieldDef.originModel, fieldDef.originModel, field);
859
+ }
860
+ }
861
+ buildDelegateJoin(thisModel, otherModel, query) {
862
+ const idFields = getIdFields(this.schema, thisModel);
863
+ query = query.leftJoin(otherModel, (qb) => {
864
+ for (const idField of idFields) {
865
+ qb = qb.onRef(`${thisModel}.${idField}`, "=", `${otherModel}.${idField}`);
866
+ }
867
+ return qb;
868
+ });
869
+ return query;
870
+ }
871
+ buildCountJson(model, eb, parentAlias, payload) {
872
+ const modelDef = requireModel(this.schema, model);
873
+ const toManyRelations = Object.entries(modelDef.fields).filter(([, field]) => field.relation && field.array);
874
+ const selections = payload === true ? {
875
+ select: toManyRelations.reduce((acc, [field]) => {
876
+ acc[field] = true;
877
+ return acc;
878
+ }, {})
879
+ } : payload;
880
+ const jsonObject = {};
881
+ for (const [field, value] of Object.entries(selections.select)) {
882
+ const fieldDef = requireField(this.schema, model, field);
883
+ const fieldModel = fieldDef.type;
884
+ const joinPairs = buildJoinPairs(this.schema, model, parentAlias, field, fieldModel);
885
+ let fieldCountQuery = eb.selectFrom(fieldModel).select(eb.fn.countAll().as(`_count$${field}`));
886
+ for (const [left, right] of joinPairs) {
887
+ fieldCountQuery = fieldCountQuery.whereRef(left, "=", right);
888
+ }
889
+ if (value && typeof value === "object" && "where" in value && value.where && typeof value.where === "object") {
890
+ const filter = this.buildFilter(eb, fieldModel, fieldModel, value.where);
891
+ fieldCountQuery = fieldCountQuery.where(filter);
892
+ }
893
+ jsonObject[field] = fieldCountQuery;
894
+ }
895
+ return this.buildJsonObject(eb, jsonObject);
896
+ }
897
+ // #endregion
898
+ // #region utils
679
899
  negateSort(sort, negated) {
680
900
  return negated ? sort === "asc" ? "desc" : "asc" : sort;
681
901
  }
682
902
  true(eb) {
683
- return eb.lit(this.transformPrimitive(true, "Boolean"));
903
+ return eb.lit(this.transformPrimitive(true, "Boolean", false));
684
904
  }
685
905
  false(eb) {
686
- return eb.lit(this.transformPrimitive(false, "Boolean"));
906
+ return eb.lit(this.transformPrimitive(false, "Boolean", false));
687
907
  }
688
908
  isTrue(expression) {
689
909
  const node = expression.toOperationNode();
@@ -732,14 +952,18 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
732
952
  get provider() {
733
953
  return "postgresql";
734
954
  }
735
- transformPrimitive(value, type) {
955
+ transformPrimitive(value, type, forArrayField) {
736
956
  if (value === void 0) {
737
957
  return value;
738
958
  }
739
959
  if (Array.isArray(value)) {
740
- return value.map((v) => this.transformPrimitive(v, type));
960
+ if (type === "Json" && !forArrayField) {
961
+ return JSON.stringify(value);
962
+ } else {
963
+ return value.map((v) => this.transformPrimitive(v, type, false));
964
+ }
741
965
  } else {
742
- return (0, import_ts_pattern2.match)(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).otherwise(() => value);
966
+ 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
967
  }
744
968
  }
745
969
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
@@ -753,7 +977,8 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
753
977
  const joinTableName = `${parentName}$${relationField}`;
754
978
  let result = eb.selectFrom(`${relationModel} as ${joinTableName}`);
755
979
  result = eb.selectFrom(() => {
756
- let subQuery = eb.selectFrom(`${relationModel}`).selectAll();
980
+ let subQuery = this.buildSelectModel(eb, relationModel);
981
+ subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
757
982
  if (payload && typeof payload === "object") {
758
983
  if (payload.where) {
759
984
  subQuery = subQuery.where((eb2) => this.buildFilter(eb2, relationModel, relationModel, payload.where));
@@ -772,8 +997,8 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
772
997
  if (m2m) {
773
998
  const parentIds = getIdFields(this.schema, model);
774
999
  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");
1000
+ (0, import_common_helpers2.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1001
+ (0, import_common_helpers2.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
777
1002
  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
1003
  } else {
779
1004
  const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, relationModel);
@@ -797,34 +1022,57 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
797
1022
  });
798
1023
  return qb;
799
1024
  }
800
- buildRelationObjectArgs(relationModel, relationField, eb, payload, parentName) {
1025
+ buildRelationObjectArgs(relationModel, relationField, eb, payload, parentAlias) {
801
1026
  const relationModelDef = requireModel(this.schema, relationModel);
802
1027
  const objArgs = [];
1028
+ const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
1029
+ if (descendantModels.length > 0) {
1030
+ objArgs.push(...descendantModels.map((subModel) => [
1031
+ import_kysely2.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1032
+ eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
1033
+ ]).flatMap((v) => v));
1034
+ }
803
1035
  if (payload === true || !payload.select) {
804
1036
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
805
1037
  import_kysely2.sql.lit(field),
806
1038
  buildFieldRef(this.schema, relationModel, field, this.options, eb)
807
1039
  ]).flatMap((v) => v));
808
1040
  } 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));
1041
+ objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
1042
+ if (field === "_count") {
1043
+ const subJson = this.buildCountJson(relationModel, eb, `${parentAlias}$${relationField}`, value);
1044
+ return [
1045
+ import_kysely2.sql.lit(field),
1046
+ subJson
1047
+ ];
1048
+ } else {
1049
+ const fieldDef = requireField(this.schema, relationModel, field);
1050
+ const fieldValue = fieldDef.relation ? eb.ref(`${parentAlias}$${relationField}$${field}.$j`) : buildFieldRef(this.schema, relationModel, field, this.options, eb);
1051
+ return [
1052
+ import_kysely2.sql.lit(field),
1053
+ fieldValue
1054
+ ];
1055
+ }
1056
+ }).flatMap((v) => v));
813
1057
  }
814
1058
  if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
815
1059
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field]) => [
816
1060
  import_kysely2.sql.lit(field),
817
- eb.ref(`${parentName}$${relationField}$${field}.$j`)
1061
+ // reference the synthesized JSON field
1062
+ eb.ref(`${parentAlias}$${relationField}$${field}.$j`)
818
1063
  ]).flatMap((v) => v));
819
1064
  }
820
1065
  return objArgs;
821
1066
  }
822
- buildRelationJoins(model, relationField, qb, payload, parentName) {
1067
+ buildRelationJoins(relationModel, relationField, qb, payload, parentName) {
823
1068
  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
- });
1069
+ if (typeof payload === "object") {
1070
+ const selectInclude = payload.include ?? payload.select;
1071
+ if (selectInclude && typeof selectInclude === "object") {
1072
+ Object.entries(selectInclude).filter(([, value]) => value).filter(([field]) => isRelationField(this.schema, relationModel, field)).forEach(([field, value]) => {
1073
+ result = this.buildRelationJSON(relationModel, result, field, `${parentName}$${relationField}`, value);
1074
+ });
1075
+ }
828
1076
  }
829
1077
  return result;
830
1078
  }
@@ -864,12 +1112,15 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
864
1112
  return `ARRAY[${values.map((v) => typeof v === "string" ? `'${v}'` : v)}]`;
865
1113
  }
866
1114
  }
1115
+ get supportInsertWithDefault() {
1116
+ return true;
1117
+ }
867
1118
  };
868
1119
 
869
1120
  // src/client/crud/dialects/sqlite.ts
1121
+ var import_common_helpers3 = require("@zenstackhq/common-helpers");
870
1122
  var import_kysely3 = require("kysely");
871
- var import_tiny_invariant3 = __toESM(require("tiny-invariant"), 1);
872
- var import_ts_pattern3 = require("ts-pattern");
1123
+ var import_ts_pattern4 = require("ts-pattern");
873
1124
  var SqliteCrudDialect = class extends BaseCrudDialect {
874
1125
  static {
875
1126
  __name(this, "SqliteCrudDialect");
@@ -877,26 +1128,31 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
877
1128
  get provider() {
878
1129
  return "sqlite";
879
1130
  }
880
- transformPrimitive(value, type) {
1131
+ transformPrimitive(value, type, _forArrayField) {
881
1132
  if (value === void 0) {
882
1133
  return value;
883
1134
  }
884
1135
  if (Array.isArray(value)) {
885
- return value.map((v) => this.transformPrimitive(v, type));
1136
+ return value.map((v) => this.transformPrimitive(v, type, false));
886
1137
  } 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);
1138
+ if (this.schema.typeDefs && type in this.schema.typeDefs) {
1139
+ return JSON.stringify(value);
1140
+ } else {
1141
+ 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);
1142
+ }
888
1143
  }
889
1144
  }
890
1145
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
891
1146
  return query.select((eb) => this.buildRelationJSON(model, eb, relationField, parentAlias, payload).as(relationField));
892
1147
  }
893
- buildRelationJSON(model, eb, relationField, parentName, payload) {
1148
+ buildRelationJSON(model, eb, relationField, parentAlias, payload) {
894
1149
  const relationFieldDef = requireField(this.schema, model, relationField);
895
1150
  const relationModel = relationFieldDef.type;
896
1151
  const relationModelDef = requireModel(this.schema, relationModel);
897
- const subQueryName = `${parentName}$${relationField}`;
1152
+ const subQueryName = `${parentAlias}$${relationField}`;
898
1153
  let tbl = eb.selectFrom(() => {
899
- let subQuery = eb.selectFrom(relationModel).selectAll();
1154
+ let subQuery = this.buildSelectModel(eb, relationModel);
1155
+ subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
900
1156
  if (payload && typeof payload === "object") {
901
1157
  if (payload.where) {
902
1158
  subQuery = subQuery.where((eb2) => this.buildFilter(eb2, relationModel, relationModel, payload.where));
@@ -915,16 +1171,16 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
915
1171
  if (m2m) {
916
1172
  const parentIds = getIdFields(this.schema, model);
917
1173
  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}`)));
1174
+ (0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1175
+ (0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1176
+ 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
1177
  } else {
922
1178
  const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
923
1179
  keyPairs.forEach(({ fk, pk }) => {
924
1180
  if (ownedByModel) {
925
- subQuery = subQuery.whereRef(`${relationModel}.${pk}`, "=", `${parentName}.${fk}`);
1181
+ subQuery = subQuery.whereRef(`${relationModel}.${pk}`, "=", `${parentAlias}.${fk}`);
926
1182
  } else {
927
- subQuery = subQuery.whereRef(`${relationModel}.${fk}`, "=", `${parentName}.${pk}`);
1183
+ subQuery = subQuery.whereRef(`${relationModel}.${fk}`, "=", `${parentAlias}.${pk}`);
928
1184
  }
929
1185
  });
930
1186
  }
@@ -932,6 +1188,13 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
932
1188
  });
933
1189
  tbl = tbl.select(() => {
934
1190
  const objArgs = [];
1191
+ const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
1192
+ if (descendantModels.length > 0) {
1193
+ objArgs.push(...descendantModels.map((subModel) => [
1194
+ import_kysely3.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1195
+ eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
1196
+ ]).flatMap((v) => v));
1197
+ }
935
1198
  if (payload === true || !payload.select) {
936
1199
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
937
1200
  import_kysely3.sql.lit(field),
@@ -939,24 +1202,32 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
939
1202
  ]).flatMap((v) => v));
940
1203
  } else if (payload.select) {
941
1204
  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);
1205
+ if (field === "_count") {
1206
+ const subJson = this.buildCountJson(relationModel, eb, `${parentAlias}$${relationField}`, value);
945
1207
  return [
946
1208
  import_kysely3.sql.lit(field),
947
1209
  subJson
948
1210
  ];
949
1211
  } else {
950
- return [
951
- import_kysely3.sql.lit(field),
952
- buildFieldRef(this.schema, relationModel, field, this.options, eb)
953
- ];
1212
+ const fieldDef = requireField(this.schema, relationModel, field);
1213
+ if (fieldDef.relation) {
1214
+ const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
1215
+ return [
1216
+ import_kysely3.sql.lit(field),
1217
+ subJson
1218
+ ];
1219
+ } else {
1220
+ return [
1221
+ import_kysely3.sql.lit(field),
1222
+ buildFieldRef(this.schema, relationModel, field, this.options, eb)
1223
+ ];
1224
+ }
954
1225
  }
955
1226
  }).flatMap((v) => v));
956
1227
  }
957
1228
  if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
958
1229
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field, value]) => {
959
- const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentName}$${relationField}`, value);
1230
+ const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
960
1231
  return [
961
1232
  import_kysely3.sql.lit(field),
962
1233
  subJson
@@ -1006,93 +1277,17 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1006
1277
  buildArrayLiteralSQL(_values) {
1007
1278
  throw new Error("SQLite does not support array literals");
1008
1279
  }
1280
+ get supportInsertWithDefault() {
1281
+ return false;
1282
+ }
1009
1283
  };
1010
1284
 
1011
1285
  // src/client/crud/dialects/index.ts
1012
1286
  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();
1287
+ return (0, import_ts_pattern5.match)(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
1014
1288
  }
1015
1289
  __name(getCrudDialect, "getCrudDialect");
1016
1290
 
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
1291
  // src/utils/default-operation-node-visitor.ts
1097
1292
  var import_kysely4 = require("kysely");
1098
1293
  var DefaultOperationNodeVisitor = class extends import_kysely4.OperationNodeVisitor {
@@ -1412,19 +1607,19 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
1412
1607
  };
1413
1608
 
1414
1609
  // src/plugins/policy/expression-transformer.ts
1610
+ var import_common_helpers5 = require("@zenstackhq/common-helpers");
1415
1611
  var import_kysely6 = require("kysely");
1416
- var import_tiny_invariant5 = __toESM(require("tiny-invariant"), 1);
1417
- var import_ts_pattern6 = require("ts-pattern");
1612
+ var import_ts_pattern7 = require("ts-pattern");
1418
1613
 
1419
1614
  // src/plugins/policy/expression-evaluator.ts
1420
- var import_tiny_invariant4 = __toESM(require("tiny-invariant"), 1);
1421
- var import_ts_pattern5 = require("ts-pattern");
1615
+ var import_common_helpers4 = require("@zenstackhq/common-helpers");
1616
+ var import_ts_pattern6 = require("ts-pattern");
1422
1617
  var ExpressionEvaluator = class {
1423
1618
  static {
1424
1619
  __name(this, "ExpressionEvaluator");
1425
1620
  }
1426
1621
  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();
1622
+ 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
1623
  return result ?? null;
1429
1624
  }
1430
1625
  evaluateCall(expr2, context) {
@@ -1435,7 +1630,7 @@ var ExpressionEvaluator = class {
1435
1630
  }
1436
1631
  }
1437
1632
  evaluateUnary(expr2, context) {
1438
- return (0, import_ts_pattern5.match)(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1633
+ return (0, import_ts_pattern6.match)(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1439
1634
  }
1440
1635
  evaluateMember(expr2, context) {
1441
1636
  let val = this.evaluate(expr2.receiver, context);
@@ -1459,21 +1654,21 @@ var ExpressionEvaluator = class {
1459
1654
  }
1460
1655
  const left = this.evaluate(expr2.left, context);
1461
1656
  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", () => {
1657
+ 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
1658
  const _right = right ?? [];
1464
- (0, import_tiny_invariant4.default)(Array.isArray(_right), 'expected array for "in" operator');
1659
+ (0, import_common_helpers4.invariant)(Array.isArray(_right), 'expected array for "in" operator');
1465
1660
  return _right.includes(left);
1466
1661
  }).exhaustive();
1467
1662
  }
1468
1663
  evaluateCollectionPredicate(expr2, context) {
1469
1664
  const op = expr2.op;
1470
- (0, import_tiny_invariant4.default)(op === "?" || op === "!" || op === "^", 'expected "?" or "!" or "^" operator');
1665
+ (0, import_common_helpers4.invariant)(op === "?" || op === "!" || op === "^", 'expected "?" or "!" or "^" operator');
1471
1666
  const left = this.evaluate(expr2.left, context);
1472
1667
  if (!left) {
1473
1668
  return false;
1474
1669
  }
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, {
1670
+ (0, import_common_helpers4.invariant)(Array.isArray(left), "expected array");
1671
+ return (0, import_ts_pattern6.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1477
1672
  ...context,
1478
1673
  thisValue: item
1479
1674
  }))).with("!", () => left.every((item) => this.evaluate(expr2.right, {
@@ -1489,11 +1684,11 @@ var ExpressionEvaluator = class {
1489
1684
  // src/plugins/policy/utils.ts
1490
1685
  var import_kysely5 = require("kysely");
1491
1686
  function trueNode(dialect) {
1492
- return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean"));
1687
+ return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean", false));
1493
1688
  }
1494
1689
  __name(trueNode, "trueNode");
1495
1690
  function falseNode(dialect) {
1496
- return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean"));
1691
+ return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean", false));
1497
1692
  }
1498
1693
  __name(falseNode, "falseNode");
1499
1694
  function isTrueNode(node) {
@@ -1694,20 +1889,20 @@ var ExpressionTransformer = class {
1694
1889
  return import_kysely6.BinaryOperationNode.create(left, this.transformOperator(op), right);
1695
1890
  }
1696
1891
  transformCollectionPredicate(expr2, context) {
1697
- (0, import_tiny_invariant5.default)(expr2.op === "?" || expr2.op === "!" || expr2.op === "^", 'expected "?" or "!" or "^" operator');
1892
+ (0, import_common_helpers5.invariant)(expr2.op === "?" || expr2.op === "!" || expr2.op === "^", 'expected "?" or "!" or "^" operator');
1698
1893
  if (this.isAuthCall(expr2.left) || this.isAuthMember(expr2.left)) {
1699
1894
  const value = new ExpressionEvaluator().evaluate(expr2, {
1700
1895
  auth: this.auth
1701
1896
  });
1702
1897
  return this.transformValue(value, "Boolean");
1703
1898
  }
1704
- (0, import_tiny_invariant5.default)(ExpressionUtils.isField(expr2.left) || ExpressionUtils.isMember(expr2.left), "left operand must be field or member access");
1899
+ (0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.left) || ExpressionUtils.isMember(expr2.left), "left operand must be field or member access");
1705
1900
  let newContextModel;
1706
1901
  if (ExpressionUtils.isField(expr2.left)) {
1707
1902
  const fieldDef = requireField(this.schema, context.model, expr2.left.field);
1708
1903
  newContextModel = fieldDef.type;
1709
1904
  } else {
1710
- (0, import_tiny_invariant5.default)(ExpressionUtils.isField(expr2.left.receiver));
1905
+ (0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.left.receiver));
1711
1906
  const fieldDef = requireField(this.schema, context.model, expr2.left.receiver.field);
1712
1907
  newContextModel = fieldDef.type;
1713
1908
  for (const member of expr2.left.members) {
@@ -1727,7 +1922,7 @@ var ExpressionTransformer = class {
1727
1922
  const count = import_kysely6.FunctionNode.create("count", [
1728
1923
  import_kysely6.ValueNode.createImmediate(1)
1729
1924
  ]);
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();
1925
+ 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
1926
  return this.transform(expr2.left, {
1732
1927
  ...context,
1733
1928
  memberSelect: import_kysely6.SelectionNode.create(import_kysely6.AliasNode.create(predicateResult, import_kysely6.IdentifierNode.create("$t"))),
@@ -1751,14 +1946,14 @@ var ExpressionTransformer = class {
1751
1946
  }
1752
1947
  }
1753
1948
  transformValue(value, type) {
1754
- return import_kysely6.ValueNode.create(this.dialect.transformPrimitive(value, type) ?? null);
1949
+ return import_kysely6.ValueNode.create(this.dialect.transformPrimitive(value, type, false) ?? null);
1755
1950
  }
1756
1951
  _unary(expr2, context) {
1757
- (0, import_tiny_invariant5.default)(expr2.op === "!", 'only "!" operator is supported');
1952
+ (0, import_common_helpers5.invariant)(expr2.op === "!", 'only "!" operator is supported');
1758
1953
  return import_kysely6.BinaryOperationNode.create(this.transform(expr2.operand, context), this.transformOperator("!="), trueNode(this.dialect));
1759
1954
  }
1760
1955
  transformOperator(op) {
1761
- const mappedOp = (0, import_ts_pattern6.match)(op).with("==", () => "=").otherwise(() => op);
1956
+ const mappedOp = (0, import_ts_pattern7.match)(op).with("==", () => "=").otherwise(() => op);
1762
1957
  return import_kysely6.OperatorNode.create(mappedOp);
1763
1958
  }
1764
1959
  _call(expr2, context) {
@@ -1797,10 +1992,10 @@ var ExpressionTransformer = class {
1797
1992
  if (this.isAuthCall(expr2.receiver)) {
1798
1993
  return this.valueMemberAccess(this.auth, expr2, this.authType);
1799
1994
  }
1800
- (0, import_tiny_invariant5.default)(ExpressionUtils.isField(expr2.receiver), "expect receiver to be field expression");
1995
+ (0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.receiver), "expect receiver to be field expression");
1801
1996
  const { memberFilter, memberSelect, ...restContext } = context;
1802
1997
  const receiver = this.transform(expr2.receiver, restContext);
1803
- (0, import_tiny_invariant5.default)(import_kysely6.SelectQueryNode.is(receiver), "expected receiver to be select query");
1998
+ (0, import_common_helpers5.invariant)(import_kysely6.SelectQueryNode.is(receiver), "expected receiver to be select query");
1804
1999
  const receiverField = requireField(this.schema, context.model, expr2.receiver.field);
1805
2000
  const memberFields = [];
1806
2001
  let currType = receiverField.type;
@@ -1824,7 +2019,7 @@ var ExpressionTransformer = class {
1824
2019
  thisEntity: void 0
1825
2020
  });
1826
2021
  if (currNode) {
1827
- (0, import_tiny_invariant5.default)(import_kysely6.SelectQueryNode.is(currNode), "expected select query node");
2022
+ (0, import_common_helpers5.invariant)(import_kysely6.SelectQueryNode.is(currNode), "expected select query node");
1828
2023
  currNode = {
1829
2024
  ...relation,
1830
2025
  selections: [
@@ -1841,8 +2036,8 @@ var ExpressionTransformer = class {
1841
2036
  };
1842
2037
  }
1843
2038
  } 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");
2039
+ (0, import_common_helpers5.invariant)(i === expr2.members.length - 1, "plain field access must be the last segment");
2040
+ (0, import_common_helpers5.invariant)(!currNode, "plain field access must be the last segment");
1846
2041
  currNode = import_kysely6.ColumnNode.create(member);
1847
2042
  }
1848
2043
  }
@@ -1994,7 +2189,7 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
1994
2189
  get kysely() {
1995
2190
  return this.client.$qb;
1996
2191
  }
1997
- async handle(node, proceed, transaction) {
2192
+ async handle(node, proceed) {
1998
2193
  if (!this.isCrudQueryNode(node)) {
1999
2194
  throw new RejectedByPolicyError(void 0, "non-CRUD queries are not allowed");
2000
2195
  }
@@ -2014,27 +2209,20 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2014
2209
  if (!mutationRequiresTransaction && !node.returning) {
2015
2210
  return proceed(this.transformNode(node));
2016
2211
  }
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;
2212
+ if (import_kysely7.InsertQueryNode.is(node)) {
2213
+ await this.enforcePreCreatePolicy(node, proceed);
2214
+ }
2215
+ const transformedNode = this.transformNode(node);
2216
+ const result = await proceed(transformedNode);
2217
+ if (!this.onlyReturningId(node)) {
2218
+ const readBackResult = await this.processReadBack(node, result, proceed);
2219
+ if (readBackResult.rows.length !== result.rows.length) {
2220
+ throw new RejectedByPolicyError(mutationModel, "result is not allowed to be read back");
2032
2221
  }
2033
- });
2034
- if (readBackError) {
2035
- throw new RejectedByPolicyError(mutationModel, "result is not allowed to be read back");
2222
+ return readBackResult;
2223
+ } else {
2224
+ return result;
2036
2225
  }
2037
- return result;
2038
2226
  }
2039
2227
  onlyReturningId(node) {
2040
2228
  if (!node.returning) {
@@ -2087,19 +2275,19 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2087
2275
  }
2088
2276
  }
2089
2277
  unwrapCreateValueRow(data, model, fields) {
2090
- (0, import_tiny_invariant6.default)(data.length === fields.length, "data length must match fields length");
2278
+ (0, import_common_helpers6.invariant)(data.length === fields.length, "data length must match fields length");
2091
2279
  const result = [];
2092
2280
  for (let i = 0; i < data.length; i++) {
2093
2281
  const item = data[i];
2094
2282
  const fieldDef = requireField(this.client.$schema, model, fields[i]);
2095
2283
  if (typeof item === "object" && item && "kind" in item) {
2096
- (0, import_tiny_invariant6.default)(item.kind === "ValueNode", "expecting a ValueNode");
2284
+ (0, import_common_helpers6.invariant)(item.kind === "ValueNode", "expecting a ValueNode");
2097
2285
  result.push({
2098
- node: import_kysely7.ValueNode.create(this.dialect.transformPrimitive(item.value, fieldDef.type)),
2286
+ node: import_kysely7.ValueNode.create(this.dialect.transformPrimitive(item.value, fieldDef.type, !!fieldDef.array)),
2099
2287
  raw: item.value
2100
2288
  });
2101
2289
  } else {
2102
- const value = this.dialect.transformPrimitive(item, fieldDef.type);
2290
+ const value = this.dialect.transformPrimitive(item, fieldDef.type, !!fieldDef.array);
2103
2291
  if (Array.isArray(value)) {
2104
2292
  result.push({
2105
2293
  node: import_kysely7.RawNode.createWithSql(this.dialect.buildArrayLiteralSQL(value)),
@@ -2168,7 +2356,7 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2168
2356
  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
2357
  }
2170
2358
  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) => {
2359
+ 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
2360
  if (node2.from.froms.length !== 1) {
2173
2361
  throw new InternalError("Only one from table is supported for delete");
2174
2362
  }
@@ -2301,8 +2489,8 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2301
2489
  const modelDef = requireModel(this.client.$schema, modelName);
2302
2490
  const result = [];
2303
2491
  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");
2492
+ (0, import_common_helpers6.invariant)(ExpressionUtils.isLiteral(expr2), "expecting a literal");
2493
+ (0, import_common_helpers6.invariant)(typeof expr2.value === "string", "expecting a string literal");
2306
2494
  return expr2.value.split(",").filter((v) => !!v).map((v) => v.trim());
2307
2495
  }, "extractOperations");
2308
2496
  if (modelDef.attributes) {
@@ -2330,9 +2518,18 @@ var PolicyPlugin = class {
2330
2518
  get description() {
2331
2519
  return "Enforces access policies defined in the schema.";
2332
2520
  }
2333
- onKyselyQuery({ query, client, proceed, transaction }) {
2521
+ onKyselyQuery({
2522
+ query,
2523
+ client,
2524
+ proceed
2525
+ /*, transaction*/
2526
+ }) {
2334
2527
  const handler = new PolicyHandler(client);
2335
- return handler.handle(query, proceed, transaction);
2528
+ return handler.handle(
2529
+ query,
2530
+ proceed
2531
+ /*, transaction*/
2532
+ );
2336
2533
  }
2337
2534
  };
2338
2535
  // Annotate the CommonJS export names for ESM import in node:
@@ -2340,4 +2537,4 @@ var PolicyPlugin = class {
2340
2537
  PolicyPlugin,
2341
2538
  RejectedByPolicyError
2342
2539
  });
2343
- //# sourceMappingURL=policy.cjs.map
2540
+ //# sourceMappingURL=index.cjs.map