@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
package/dist/index.cjs CHANGED
@@ -31,34 +31,143 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  // src/index.ts
32
32
  var src_exports = {};
33
33
  __export(src_exports, {
34
- ZenStackClient: () => ZenStackClient
34
+ InputValidationError: () => InputValidationError,
35
+ InternalError: () => InternalError,
36
+ NotFoundError: () => NotFoundError,
37
+ QueryError: () => QueryError,
38
+ ZenStackClient: () => ZenStackClient,
39
+ definePlugin: () => definePlugin
35
40
  });
36
41
  module.exports = __toCommonJS(src_exports);
37
42
 
38
43
  // src/client/client-impl.ts
44
+ var import_common_helpers13 = require("@zenstackhq/common-helpers");
39
45
  var import_kysely16 = require("kysely");
40
- var import_ts_pattern19 = require("ts-pattern");
41
46
 
42
47
  // src/client/crud/operations/aggregate.ts
43
48
  var import_kysely9 = require("kysely");
44
- var import_ts_pattern9 = require("ts-pattern");
49
+ var import_ts_pattern10 = require("ts-pattern");
50
+
51
+ // src/client/query-utils.ts
52
+ var import_ts_pattern = require("ts-pattern");
53
+
54
+ // src/schema/expression.ts
55
+ var ExpressionUtils = {
56
+ literal: /* @__PURE__ */ __name((value) => {
57
+ return {
58
+ kind: "literal",
59
+ value
60
+ };
61
+ }, "literal"),
62
+ array: /* @__PURE__ */ __name((items) => {
63
+ return {
64
+ kind: "array",
65
+ items
66
+ };
67
+ }, "array"),
68
+ call: /* @__PURE__ */ __name((functionName, args) => {
69
+ return {
70
+ kind: "call",
71
+ function: functionName,
72
+ args
73
+ };
74
+ }, "call"),
75
+ binary: /* @__PURE__ */ __name((left, op, right) => {
76
+ return {
77
+ kind: "binary",
78
+ op,
79
+ left,
80
+ right
81
+ };
82
+ }, "binary"),
83
+ unary: /* @__PURE__ */ __name((op, operand) => {
84
+ return {
85
+ kind: "unary",
86
+ op,
87
+ operand
88
+ };
89
+ }, "unary"),
90
+ field: /* @__PURE__ */ __name((field) => {
91
+ return {
92
+ kind: "field",
93
+ field
94
+ };
95
+ }, "field"),
96
+ member: /* @__PURE__ */ __name((receiver, members) => {
97
+ return {
98
+ kind: "member",
99
+ receiver,
100
+ members
101
+ };
102
+ }, "member"),
103
+ _this: /* @__PURE__ */ __name(() => {
104
+ return {
105
+ kind: "this"
106
+ };
107
+ }, "_this"),
108
+ _null: /* @__PURE__ */ __name(() => {
109
+ return {
110
+ kind: "null"
111
+ };
112
+ }, "_null"),
113
+ and: /* @__PURE__ */ __name((expr2, ...expressions) => {
114
+ return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "&&", exp), expr2);
115
+ }, "and"),
116
+ or: /* @__PURE__ */ __name((expr2, ...expressions) => {
117
+ return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
118
+ }, "or"),
119
+ is: /* @__PURE__ */ __name((value, kind) => {
120
+ return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
121
+ }, "is"),
122
+ isLiteral: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "literal"), "isLiteral"),
123
+ isArray: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "array"), "isArray"),
124
+ isCall: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "call"), "isCall"),
125
+ isNull: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "null"), "isNull"),
126
+ isThis: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "this"), "isThis"),
127
+ isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
128
+ isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
129
+ isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
130
+ isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
131
+ };
132
+
133
+ // src/utils/object-utils.ts
134
+ function extractFields(obj, fields) {
135
+ return Object.fromEntries(Object.entries(obj).filter(([key]) => fields.includes(key)));
136
+ }
137
+ __name(extractFields, "extractFields");
138
+ function fieldsToSelectObject(fields) {
139
+ return Object.fromEntries(fields.map((f) => [
140
+ f,
141
+ true
142
+ ]));
143
+ }
144
+ __name(fieldsToSelectObject, "fieldsToSelectObject");
45
145
 
46
146
  // src/client/errors.ts
147
+ var InputValidationError = class extends Error {
148
+ static {
149
+ __name(this, "InputValidationError");
150
+ }
151
+ constructor(message, cause) {
152
+ super(message, {
153
+ cause
154
+ });
155
+ }
156
+ };
47
157
  var QueryError = class extends Error {
48
158
  static {
49
159
  __name(this, "QueryError");
50
160
  }
51
- constructor(message) {
52
- super(message);
161
+ constructor(message, cause) {
162
+ super(message, {
163
+ cause
164
+ });
53
165
  }
54
166
  };
55
167
  var InternalError = class extends Error {
56
168
  static {
57
169
  __name(this, "InternalError");
58
170
  }
59
- constructor(message) {
60
- super(message);
61
- }
62
171
  };
63
172
  var NotFoundError = class extends Error {
64
173
  static {
@@ -77,7 +186,7 @@ __name(getModel, "getModel");
77
186
  function requireModel(schema, model) {
78
187
  const matchedName = Object.keys(schema.models).find((k) => k.toLowerCase() === model.toLowerCase());
79
188
  if (!matchedName) {
80
- throw new QueryError(`Model "${model}" not found`);
189
+ throw new QueryError(`Model "${model}" not found in schema`);
81
190
  }
82
191
  return schema.models[matchedName];
83
192
  }
@@ -141,20 +250,25 @@ function getRelationForeignKeyFieldPairs(schema, model, relationField) {
141
250
  }
142
251
  __name(getRelationForeignKeyFieldPairs, "getRelationForeignKeyFieldPairs");
143
252
  function isScalarField(schema, model, field) {
144
- const fieldDef = requireField(schema, model, field);
145
- return !fieldDef.relation && !fieldDef.foreignKeyFor;
253
+ const fieldDef = getField(schema, model, field);
254
+ return !fieldDef?.relation && !fieldDef?.foreignKeyFor;
146
255
  }
147
256
  __name(isScalarField, "isScalarField");
148
257
  function isForeignKeyField(schema, model, field) {
149
- const fieldDef = requireField(schema, model, field);
150
- return !!fieldDef.foreignKeyFor;
258
+ const fieldDef = getField(schema, model, field);
259
+ return !!fieldDef?.foreignKeyFor;
151
260
  }
152
261
  __name(isForeignKeyField, "isForeignKeyField");
153
262
  function isRelationField(schema, model, field) {
154
- const fieldDef = requireField(schema, model, field);
155
- return !!fieldDef.relation;
263
+ const fieldDef = getField(schema, model, field);
264
+ return !!fieldDef?.relation;
156
265
  }
157
266
  __name(isRelationField, "isRelationField");
267
+ function isInheritedField(schema, model, field) {
268
+ const fieldDef = getField(schema, model, field);
269
+ return !!fieldDef?.originModel;
270
+ }
271
+ __name(isInheritedField, "isInheritedField");
158
272
  function getUniqueFields(schema, model) {
159
273
  const modelDef = requireModel(schema, model);
160
274
  const result = [];
@@ -202,7 +316,7 @@ function buildFieldRef(schema, model, field, options, eb, modelAlias) {
202
316
  computer = computedFields?.[model]?.[field];
203
317
  }
204
318
  if (!computer) {
205
- throw new QueryError(`Computed field "${field}" implementation not provided`);
319
+ throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
206
320
  }
207
321
  return computer(eb);
208
322
  }
@@ -307,13 +421,49 @@ function safeJSONStringify(value) {
307
421
  });
308
422
  }
309
423
  __name(safeJSONStringify, "safeJSONStringify");
424
+ function extractIdFields(entity, schema, model) {
425
+ const idFields = getIdFields(schema, model);
426
+ return extractFields(entity, idFields);
427
+ }
428
+ __name(extractIdFields, "extractIdFields");
429
+ function getDiscriminatorField(schema, model) {
430
+ const modelDef = requireModel(schema, model);
431
+ const delegateAttr = modelDef.attributes?.find((attr) => attr.name === "@@delegate");
432
+ if (!delegateAttr) {
433
+ return void 0;
434
+ }
435
+ const discriminator = delegateAttr.args?.find((arg) => arg.name === "discriminator");
436
+ if (!discriminator || !ExpressionUtils.isField(discriminator.value)) {
437
+ throw new InternalError(`Discriminator field not defined for model "${model}"`);
438
+ }
439
+ return discriminator.value.field;
440
+ }
441
+ __name(getDiscriminatorField, "getDiscriminatorField");
442
+ function getDelegateDescendantModels(schema, model, collected = /* @__PURE__ */ new Set()) {
443
+ const subModels = Object.values(schema.models).filter((m) => m.baseModel === model);
444
+ subModels.forEach((def) => {
445
+ if (!collected.has(def)) {
446
+ collected.add(def);
447
+ getDelegateDescendantModels(schema, def.name, collected);
448
+ }
449
+ });
450
+ return [
451
+ ...collected
452
+ ];
453
+ }
454
+ __name(getDelegateDescendantModels, "getDelegateDescendantModels");
455
+ function aggregate(eb, expr2, op) {
456
+ 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();
457
+ }
458
+ __name(aggregate, "aggregate");
310
459
 
311
460
  // src/client/crud/operations/base.ts
312
461
  var import_cuid2 = require("@paralleldrive/cuid2");
462
+ var import_common_helpers8 = require("@zenstackhq/common-helpers");
313
463
  var import_kysely8 = require("kysely");
314
464
  var import_nanoid = require("nanoid");
315
- var import_tiny_invariant7 = __toESM(require("tiny-invariant"), 1);
316
- var import_ts_pattern8 = require("ts-pattern");
465
+ var import_node_util = require("util");
466
+ var import_ts_pattern9 = require("ts-pattern");
317
467
  var import_ulid = require("ulid");
318
468
  var uuid = __toESM(require("uuid"), 1);
319
469
 
@@ -330,22 +480,44 @@ var RejectedByPolicyError = class extends Error {
330
480
  };
331
481
 
332
482
  // src/plugins/policy/policy-handler.ts
483
+ var import_common_helpers6 = require("@zenstackhq/common-helpers");
333
484
  var import_kysely7 = require("kysely");
334
- var import_tiny_invariant6 = __toESM(require("tiny-invariant"), 1);
335
- var import_ts_pattern7 = require("ts-pattern");
485
+ var import_ts_pattern8 = require("ts-pattern");
336
486
 
337
487
  // src/client/crud/dialects/index.ts
338
- var import_ts_pattern4 = require("ts-pattern");
488
+ var import_ts_pattern5 = require("ts-pattern");
339
489
 
340
490
  // src/client/crud/dialects/postgresql.ts
491
+ var import_common_helpers2 = require("@zenstackhq/common-helpers");
341
492
  var import_kysely2 = require("kysely");
342
- var import_tiny_invariant2 = __toESM(require("tiny-invariant"), 1);
343
- var import_ts_pattern2 = require("ts-pattern");
493
+ var import_ts_pattern3 = require("ts-pattern");
494
+
495
+ // src/client/constants.ts
496
+ var CONTEXT_COMMENT_PREFIX = "-- $$context:";
497
+ var NUMERIC_FIELD_TYPES = [
498
+ "Int",
499
+ "Float",
500
+ "BigInt",
501
+ "Decimal"
502
+ ];
503
+ var DELEGATE_JOINED_FIELD_PREFIX = "$delegate$";
504
+ var LOGICAL_COMBINATORS = [
505
+ "AND",
506
+ "OR",
507
+ "NOT"
508
+ ];
509
+ var AGGREGATE_OPERATORS = [
510
+ "_count",
511
+ "_sum",
512
+ "_avg",
513
+ "_min",
514
+ "_max"
515
+ ];
344
516
 
345
517
  // src/client/crud/dialects/base.ts
518
+ var import_common_helpers = require("@zenstackhq/common-helpers");
346
519
  var import_kysely = require("kysely");
347
- var import_tiny_invariant = __toESM(require("tiny-invariant"), 1);
348
- var import_ts_pattern = require("ts-pattern");
520
+ var import_ts_pattern2 = require("ts-pattern");
349
521
 
350
522
  // src/utils/enumerate.ts
351
523
  function enumerate(x) {
@@ -362,7 +534,6 @@ function enumerate(x) {
362
534
  __name(enumerate, "enumerate");
363
535
 
364
536
  // src/client/crud/dialects/base.ts
365
- var import_is_plain_object = require("is-plain-object");
366
537
  var BaseCrudDialect = class {
367
538
  static {
368
539
  __name(this, "BaseCrudDialect");
@@ -373,9 +544,20 @@ var BaseCrudDialect = class {
373
544
  this.schema = schema;
374
545
  this.options = options;
375
546
  }
376
- transformPrimitive(value, _type) {
547
+ transformPrimitive(value, _type, _forArrayField) {
377
548
  return value;
378
549
  }
550
+ // #region common query builders
551
+ buildSelectModel(eb, model) {
552
+ const modelDef = requireModel(this.schema, model);
553
+ let result = eb.selectFrom(model);
554
+ let joinBase = modelDef.baseModel;
555
+ while (joinBase) {
556
+ result = this.buildDelegateJoin(model, joinBase, result);
557
+ joinBase = requireModel(this.schema, joinBase).baseModel;
558
+ }
559
+ return result;
560
+ }
379
561
  buildFilter(eb, model, modelAlias, where) {
380
562
  if (where === true || where === void 0) {
381
563
  return this.true(eb);
@@ -392,17 +574,20 @@ var BaseCrudDialect = class {
392
574
  if (key.startsWith("$")) {
393
575
  continue;
394
576
  }
395
- if (key === "AND" || key === "OR" || key === "NOT") {
577
+ if (this.isLogicalCombinator(key)) {
396
578
  result = this.and(eb, result, this.buildCompositeFilter(eb, model, modelAlias, key, payload));
397
579
  continue;
398
580
  }
399
581
  const fieldDef = requireField(this.schema, model, key);
400
582
  if (fieldDef.relation) {
401
583
  result = this.and(eb, result, this.buildRelationFilter(eb, model, modelAlias, key, fieldDef, payload));
402
- } else if (fieldDef.array) {
403
- result = this.and(eb, result, this.buildArrayFilter(eb, model, modelAlias, key, fieldDef, payload));
404
584
  } else {
405
- result = this.and(eb, result, this.buildPrimitiveFilter(eb, model, modelAlias, key, fieldDef, payload));
585
+ const fieldRef = this.fieldRef(fieldDef.originModel ?? model, key, eb, fieldDef.originModel ?? modelAlias);
586
+ if (fieldDef.array) {
587
+ result = this.and(eb, result, this.buildArrayFilter(eb, fieldRef, fieldDef, payload));
588
+ } else {
589
+ result = this.and(eb, result, this.buildPrimitiveFilter(eb, fieldRef, fieldDef, payload));
590
+ }
406
591
  }
407
592
  }
408
593
  if ("$expr" in _where && typeof _where["$expr"] === "function") {
@@ -410,8 +595,11 @@ var BaseCrudDialect = class {
410
595
  }
411
596
  return result;
412
597
  }
598
+ isLogicalCombinator(key) {
599
+ return LOGICAL_COMBINATORS.includes(key);
600
+ }
413
601
  buildCompositeFilter(eb, model, modelAlias, key, payload) {
414
- 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();
602
+ 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();
415
603
  }
416
604
  buildRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
417
605
  if (!fieldDef.array) {
@@ -420,19 +608,26 @@ var BaseCrudDialect = class {
420
608
  return this.buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload);
421
609
  }
422
610
  }
423
- buildToOneRelationFilter(eb, model, table, field, fieldDef, payload) {
611
+ buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
424
612
  if (payload === null) {
425
613
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, model, field);
426
- if (ownedByModel) {
427
- return this.and(eb, ...keyPairs.map(({ fk }) => eb(import_kysely.sql.ref(`${table}.${fk}`), "is", null)));
614
+ if (ownedByModel && !fieldDef.originModel) {
615
+ return this.and(eb, ...keyPairs.map(({ fk }) => eb(import_kysely.sql.ref(`${modelAlias}.${fk}`), "is", null)));
428
616
  } else {
429
- return this.buildToOneRelationFilter(eb, model, table, field, fieldDef, {
617
+ return this.buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, {
430
618
  is: null
431
619
  });
432
620
  }
433
621
  }
434
- const joinAlias = `${table}$${field}`;
435
- const joinPairs = buildJoinPairs(this.schema, model, table, field, joinAlias);
622
+ const joinAlias = `${modelAlias}$${field}`;
623
+ const joinPairs = buildJoinPairs(
624
+ this.schema,
625
+ model,
626
+ // if field is from a base, use the base model to join
627
+ fieldDef.originModel ?? modelAlias,
628
+ field,
629
+ joinAlias
630
+ );
436
631
  const filterResultField = `${field}$filter`;
437
632
  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));
438
633
  const conditions = [];
@@ -493,30 +688,29 @@ var BaseCrudDialect = class {
493
688
  }
494
689
  switch (key) {
495
690
  case "some": {
496
- 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));
691
+ 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));
497
692
  break;
498
693
  }
499
694
  case "every": {
500
- 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));
695
+ 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));
501
696
  break;
502
697
  }
503
698
  case "none": {
504
- 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));
699
+ 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));
505
700
  break;
506
701
  }
507
702
  }
508
703
  }
509
704
  return result;
510
705
  }
511
- buildArrayFilter(eb, model, modelAlias, field, fieldDef, payload) {
706
+ buildArrayFilter(eb, fieldRef, fieldDef, payload) {
512
707
  const clauses = [];
513
708
  const fieldType = fieldDef.type;
514
- const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb, modelAlias);
515
709
  for (const [key, _value] of Object.entries(payload)) {
516
710
  if (_value === void 0) {
517
711
  continue;
518
712
  }
519
- const value = this.transformPrimitive(_value, fieldType);
713
+ const value = this.transformPrimitive(_value, fieldType, !!fieldDef.array);
520
714
  switch (key) {
521
715
  case "equals": {
522
716
  clauses.push(this.buildLiteralFilter(eb, fieldRef, fieldType, eb.val(value)));
@@ -547,20 +741,24 @@ var BaseCrudDialect = class {
547
741
  }
548
742
  return this.and(eb, ...clauses);
549
743
  }
550
- buildPrimitiveFilter(eb, model, modelAlias, field, fieldDef, payload) {
744
+ buildPrimitiveFilter(eb, fieldRef, fieldDef, payload) {
551
745
  if (payload === null) {
552
- return eb(import_kysely.sql.ref(`${modelAlias}.${field}`), "is", null);
746
+ return eb(fieldRef, "is", null);
553
747
  }
554
748
  if (isEnum(this.schema, fieldDef.type)) {
555
- return this.buildEnumFilter(eb, modelAlias, field, fieldDef, payload);
749
+ return this.buildEnumFilter(eb, fieldRef, fieldDef, payload);
556
750
  }
557
- 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();
751
+ 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", () => {
752
+ throw new InternalError("JSON filters are not supported yet");
753
+ }).with("Unsupported", () => {
754
+ throw new QueryError(`Unsupported field cannot be used in filters`);
755
+ }).exhaustive();
558
756
  }
559
757
  buildLiteralFilter(eb, lhs, type, rhs) {
560
- return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type) : rhs);
758
+ return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type, false) : rhs);
561
759
  }
562
- buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0) {
563
- if (payload === null || !(0, import_is_plain_object.isPlainObject)(payload)) {
760
+ buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0, excludeKeys = []) {
761
+ if (payload === null || !(0, import_common_helpers.isPlainObject)(payload)) {
564
762
  return {
565
763
  conditions: [
566
764
  this.buildLiteralFilter(eb, lhs, type, payload)
@@ -574,22 +772,29 @@ var BaseCrudDialect = class {
574
772
  if (onlyForKeys && !onlyForKeys.includes(op)) {
575
773
  continue;
576
774
  }
775
+ if (excludeKeys.includes(op)) {
776
+ continue;
777
+ }
577
778
  const rhs = Array.isArray(value) ? value.map(getRhs) : getRhs(value);
578
- const condition = (0, import_ts_pattern.match)(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
579
- (0, import_tiny_invariant.default)(Array.isArray(rhs), "right hand side must be an array");
779
+ const condition = (0, import_ts_pattern2.match)(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
780
+ (0, import_common_helpers.invariant)(Array.isArray(rhs), "right hand side must be an array");
580
781
  if (rhs.length === 0) {
581
782
  return this.false(eb);
582
783
  } else {
583
784
  return eb(lhs, "in", rhs);
584
785
  }
585
786
  }).with("notIn", () => {
586
- (0, import_tiny_invariant.default)(Array.isArray(rhs), "right hand side must be an array");
787
+ (0, import_common_helpers.invariant)(Array.isArray(rhs), "right hand side must be an array");
587
788
  if (rhs.length === 0) {
588
789
  return this.true(eb);
589
790
  } else {
590
791
  return eb.not(eb(lhs, "in", rhs));
591
792
  }
592
- }).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(() => {
793
+ }).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) => {
794
+ const innerResult = this.buildStandardFilter(eb, type, value, aggregate(eb, lhs, op2), getRhs, recurse, throwIfInvalid);
795
+ consumedKeys.push(...innerResult.consumedKeys);
796
+ return this.and(eb, ...innerResult.conditions);
797
+ }).otherwise(() => {
593
798
  if (throwIfInvalid) {
594
799
  throw new QueryError(`Invalid filter key: ${op}`);
595
800
  } else {
@@ -606,24 +811,21 @@ var BaseCrudDialect = class {
606
811
  consumedKeys
607
812
  };
608
813
  }
609
- buildStringFilter(eb, table, field, payload) {
610
- const fieldDef = getField(this.schema, table, field);
611
- let fieldRef = fieldDef?.computed ? import_kysely.sql.ref(field) : import_kysely.sql.ref(`${table}.${field}`);
612
- let insensitive = false;
613
- if (payload && typeof payload === "object" && "mode" in payload && payload.mode === "insensitive") {
614
- insensitive = true;
615
- fieldRef = eb.fn("lower", [
616
- fieldRef
617
- ]);
814
+ buildStringFilter(eb, fieldRef, payload) {
815
+ let mode;
816
+ if (payload && typeof payload === "object" && "mode" in payload) {
817
+ mode = payload.mode;
618
818
  }
619
- const { conditions, consumedKeys } = this.buildStandardFilter(eb, "String", payload, fieldRef, (value) => this.prepStringCasing(eb, value, insensitive), (value) => this.buildStringFilter(eb, table, field, value));
819
+ const { conditions, consumedKeys } = this.buildStandardFilter(eb, "String", payload, mode === "insensitive" ? eb.fn("lower", [
820
+ fieldRef
821
+ ]) : fieldRef, (value) => this.prepStringCasing(eb, value, mode), (value) => this.buildStringFilter(eb, fieldRef, value));
620
822
  if (payload && typeof payload === "object") {
621
823
  for (const [key, value] of Object.entries(payload)) {
622
824
  if (key === "mode" || consumedKeys.includes(key)) {
623
825
  continue;
624
826
  }
625
- 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(() => {
626
- throw new Error(`Invalid string filter key: ${key}`);
827
+ 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(() => {
828
+ throw new QueryError(`Invalid string filter key: ${key}`);
627
829
  });
628
830
  if (condition) {
629
831
  conditions.push(condition);
@@ -632,34 +834,37 @@ var BaseCrudDialect = class {
632
834
  }
633
835
  return this.and(eb, ...conditions);
634
836
  }
635
- prepStringCasing(eb, value, toLower = true) {
837
+ prepStringCasing(eb, value, mode) {
838
+ if (!mode || mode === "default") {
839
+ return value === null ? value : import_kysely.sql.val(value);
840
+ }
636
841
  if (typeof value === "string") {
637
- return toLower ? eb.fn("lower", [
638
- import_kysely.sql.lit(value)
639
- ]) : import_kysely.sql.lit(value);
842
+ return eb.fn("lower", [
843
+ import_kysely.sql.val(value)
844
+ ]);
640
845
  } else if (Array.isArray(value)) {
641
- return value.map((v) => this.prepStringCasing(eb, v, toLower));
846
+ return value.map((v) => this.prepStringCasing(eb, v, mode));
642
847
  } else {
643
- return value === null ? null : import_kysely.sql.lit(value);
848
+ return value === null ? null : import_kysely.sql.val(value);
644
849
  }
645
850
  }
646
- buildNumberFilter(eb, model, table, field, type, payload) {
647
- 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));
851
+ buildNumberFilter(eb, fieldRef, type, payload) {
852
+ const { conditions } = this.buildStandardFilter(eb, type, payload, fieldRef, (value) => this.transformPrimitive(value, type, false), (value) => this.buildNumberFilter(eb, fieldRef, type, value));
648
853
  return this.and(eb, ...conditions);
649
854
  }
650
- buildBooleanFilter(eb, table, field, payload) {
651
- 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, [
855
+ buildBooleanFilter(eb, fieldRef, payload) {
856
+ const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, fieldRef, (value) => this.transformPrimitive(value, "Boolean", false), (value) => this.buildBooleanFilter(eb, fieldRef, value), true, [
652
857
  "equals",
653
858
  "not"
654
859
  ]);
655
860
  return this.and(eb, ...conditions);
656
861
  }
657
- buildDateTimeFilter(eb, table, field, payload) {
658
- 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);
862
+ buildDateTimeFilter(eb, fieldRef, payload) {
863
+ const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, fieldRef, (value) => this.transformPrimitive(value, "DateTime", false), (value) => this.buildDateTimeFilter(eb, fieldRef, value), true);
659
864
  return this.and(eb, ...conditions);
660
865
  }
661
- buildBytesFilter(eb, table, field, payload) {
662
- 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, [
866
+ buildBytesFilter(eb, fieldRef, payload) {
867
+ const conditions = this.buildStandardFilter(eb, "Bytes", payload, fieldRef, (value) => this.transformPrimitive(value, "Bytes", false), (value) => this.buildBytesFilter(eb, fieldRef, value), true, [
663
868
  "equals",
664
869
  "in",
665
870
  "notIn",
@@ -667,8 +872,8 @@ var BaseCrudDialect = class {
667
872
  ]);
668
873
  return this.and(eb, ...conditions.conditions);
669
874
  }
670
- buildEnumFilter(eb, table, field, fieldDef, payload) {
671
- const conditions = this.buildStandardFilter(eb, "String", payload, import_kysely.sql.ref(`${table}.${field}`), (value) => value, (value) => this.buildEnumFilter(eb, table, field, fieldDef, value), true, [
875
+ buildEnumFilter(eb, fieldRef, fieldDef, payload) {
876
+ const conditions = this.buildStandardFilter(eb, "String", payload, fieldRef, (value) => value, (value) => this.buildEnumFilter(eb, fieldRef, fieldDef, value), true, [
672
877
  "equals",
673
878
  "in",
674
879
  "notIn",
@@ -697,21 +902,19 @@ var BaseCrudDialect = class {
697
902
  "_min",
698
903
  "_max"
699
904
  ].includes(field)) {
700
- (0, import_tiny_invariant.default)(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
905
+ (0, import_common_helpers.invariant)(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
701
906
  for (const [k, v] of Object.entries(value)) {
702
- (0, import_tiny_invariant.default)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
703
- result = result.orderBy((eb) => eb.fn(field.slice(1), [
704
- import_kysely.sql.ref(k)
705
- ]), import_kysely.sql.raw(this.negateSort(v, negated)));
907
+ (0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
908
+ result = result.orderBy((eb) => aggregate(eb, this.fieldRef(model, k, eb, modelAlias), field), import_kysely.sql.raw(this.negateSort(v, negated)));
706
909
  }
707
910
  continue;
708
911
  }
709
912
  switch (field) {
710
913
  case "_count": {
711
- (0, import_tiny_invariant.default)(value && typeof value === "object", 'invalid orderBy value for field "_count"');
914
+ (0, import_common_helpers.invariant)(value && typeof value === "object", 'invalid orderBy value for field "_count"');
712
915
  for (const [k, v] of Object.entries(value)) {
713
- (0, import_tiny_invariant.default)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
714
- result = result.orderBy((eb) => eb.fn.count(import_kysely.sql.ref(k)), import_kysely.sql.raw(this.negateSort(v, negated)));
916
+ (0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
917
+ result = result.orderBy((eb) => eb.fn.count(this.fieldRef(model, k, eb, modelAlias)), import_kysely.sql.raw(this.negateSort(v, negated)));
715
918
  }
716
919
  continue;
717
920
  }
@@ -720,10 +923,11 @@ var BaseCrudDialect = class {
720
923
  }
721
924
  const fieldDef = requireField(this.schema, model, field);
722
925
  if (!fieldDef.relation) {
926
+ const fieldRef = this.fieldRef(model, field, (0, import_kysely.expressionBuilder)(), modelAlias);
723
927
  if (value === "asc" || value === "desc") {
724
- result = result.orderBy(import_kysely.sql.ref(`${modelAlias}.${field}`), this.negateSort(value, negated));
928
+ result = result.orderBy(fieldRef, this.negateSort(value, negated));
725
929
  } else if (value && typeof value === "object" && "nulls" in value && "sort" in value && (value.sort === "asc" || value.sort === "desc") && (value.nulls === "first" || value.nulls === "last")) {
726
- result = result.orderBy(import_kysely.sql.ref(`${modelAlias}.${field}`), import_kysely.sql.raw(`${this.negateSort(value.sort, negated)} nulls ${value.nulls}`));
930
+ result = result.orderBy(fieldRef, import_kysely.sql.raw(`${this.negateSort(value.sort, negated)} nulls ${value.nulls}`));
727
931
  }
728
932
  } else {
729
933
  const relationModel = fieldDef.type;
@@ -732,10 +936,10 @@ var BaseCrudDialect = class {
732
936
  throw new QueryError(`invalid orderBy value for field "${field}"`);
733
937
  }
734
938
  if ("_count" in value) {
735
- (0, import_tiny_invariant.default)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
939
+ (0, import_common_helpers.invariant)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
736
940
  const sort = this.negateSort(value._count, negated);
737
941
  result = result.orderBy((eb) => {
738
- let subQuery = eb.selectFrom(relationModel);
942
+ let subQuery = this.buildSelectModel(eb, relationModel);
739
943
  const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, relationModel);
740
944
  subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely.sql.ref(left), "=", import_kysely.sql.ref(right)))));
741
945
  subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
@@ -754,14 +958,90 @@ var BaseCrudDialect = class {
754
958
  });
755
959
  return result;
756
960
  }
961
+ buildSelectAllFields(model, query, omit) {
962
+ const modelDef = requireModel(this.schema, model);
963
+ let result = query;
964
+ for (const field of Object.keys(modelDef.fields)) {
965
+ if (isRelationField(this.schema, model, field)) {
966
+ continue;
967
+ }
968
+ if (omit?.[field] === true) {
969
+ continue;
970
+ }
971
+ result = this.buildSelectField(result, model, model, field);
972
+ }
973
+ const descendants = getDelegateDescendantModels(this.schema, model);
974
+ for (const subModel of descendants) {
975
+ result = this.buildDelegateJoin(model, subModel.name, result);
976
+ result = result.select((eb) => {
977
+ const jsonObject = {};
978
+ for (const field of Object.keys(subModel.fields)) {
979
+ if (isRelationField(this.schema, subModel.name, field) || isInheritedField(this.schema, subModel.name, field)) {
980
+ continue;
981
+ }
982
+ jsonObject[field] = eb.ref(`${subModel.name}.${field}`);
983
+ }
984
+ return this.buildJsonObject(eb, jsonObject).as(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`);
985
+ });
986
+ }
987
+ return result;
988
+ }
989
+ buildSelectField(query, model, modelAlias, field) {
990
+ const fieldDef = requireField(this.schema, model, field);
991
+ if (fieldDef.computed) {
992
+ return query.select((eb) => this.fieldRef(model, field, eb, modelAlias).as(field));
993
+ } else if (!fieldDef.originModel) {
994
+ return query.select(import_kysely.sql.ref(`${modelAlias}.${field}`).as(field));
995
+ } else {
996
+ return this.buildSelectField(query, fieldDef.originModel, fieldDef.originModel, field);
997
+ }
998
+ }
999
+ buildDelegateJoin(thisModel, otherModel, query) {
1000
+ const idFields = getIdFields(this.schema, thisModel);
1001
+ query = query.leftJoin(otherModel, (qb) => {
1002
+ for (const idField of idFields) {
1003
+ qb = qb.onRef(`${thisModel}.${idField}`, "=", `${otherModel}.${idField}`);
1004
+ }
1005
+ return qb;
1006
+ });
1007
+ return query;
1008
+ }
1009
+ buildCountJson(model, eb, parentAlias, payload) {
1010
+ const modelDef = requireModel(this.schema, model);
1011
+ const toManyRelations = Object.entries(modelDef.fields).filter(([, field]) => field.relation && field.array);
1012
+ const selections = payload === true ? {
1013
+ select: toManyRelations.reduce((acc, [field]) => {
1014
+ acc[field] = true;
1015
+ return acc;
1016
+ }, {})
1017
+ } : payload;
1018
+ const jsonObject = {};
1019
+ for (const [field, value] of Object.entries(selections.select)) {
1020
+ const fieldDef = requireField(this.schema, model, field);
1021
+ const fieldModel = fieldDef.type;
1022
+ const joinPairs = buildJoinPairs(this.schema, model, parentAlias, field, fieldModel);
1023
+ let fieldCountQuery = eb.selectFrom(fieldModel).select(eb.fn.countAll().as(`_count$${field}`));
1024
+ for (const [left, right] of joinPairs) {
1025
+ fieldCountQuery = fieldCountQuery.whereRef(left, "=", right);
1026
+ }
1027
+ if (value && typeof value === "object" && "where" in value && value.where && typeof value.where === "object") {
1028
+ const filter = this.buildFilter(eb, fieldModel, fieldModel, value.where);
1029
+ fieldCountQuery = fieldCountQuery.where(filter);
1030
+ }
1031
+ jsonObject[field] = fieldCountQuery;
1032
+ }
1033
+ return this.buildJsonObject(eb, jsonObject);
1034
+ }
1035
+ // #endregion
1036
+ // #region utils
757
1037
  negateSort(sort, negated) {
758
1038
  return negated ? sort === "asc" ? "desc" : "asc" : sort;
759
1039
  }
760
1040
  true(eb) {
761
- return eb.lit(this.transformPrimitive(true, "Boolean"));
1041
+ return eb.lit(this.transformPrimitive(true, "Boolean", false));
762
1042
  }
763
1043
  false(eb) {
764
- return eb.lit(this.transformPrimitive(false, "Boolean"));
1044
+ return eb.lit(this.transformPrimitive(false, "Boolean", false));
765
1045
  }
766
1046
  isTrue(expression) {
767
1047
  const node = expression.toOperationNode();
@@ -800,6 +1080,9 @@ var BaseCrudDialect = class {
800
1080
  not(eb, ...args) {
801
1081
  return eb.not(this.and(eb, ...args));
802
1082
  }
1083
+ fieldRef(model, field, eb, modelAlias) {
1084
+ return buildFieldRef(this.schema, model, field, this.options, eb, modelAlias);
1085
+ }
803
1086
  };
804
1087
 
805
1088
  // src/client/crud/dialects/postgresql.ts
@@ -810,14 +1093,18 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
810
1093
  get provider() {
811
1094
  return "postgresql";
812
1095
  }
813
- transformPrimitive(value, type) {
1096
+ transformPrimitive(value, type, forArrayField) {
814
1097
  if (value === void 0) {
815
1098
  return value;
816
1099
  }
817
1100
  if (Array.isArray(value)) {
818
- return value.map((v) => this.transformPrimitive(v, type));
1101
+ if (type === "Json" && !forArrayField) {
1102
+ return JSON.stringify(value);
1103
+ } else {
1104
+ return value.map((v) => this.transformPrimitive(v, type, false));
1105
+ }
819
1106
  } else {
820
- return (0, import_ts_pattern2.match)(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).otherwise(() => value);
1107
+ 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);
821
1108
  }
822
1109
  }
823
1110
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
@@ -831,7 +1118,8 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
831
1118
  const joinTableName = `${parentName}$${relationField}`;
832
1119
  let result = eb.selectFrom(`${relationModel} as ${joinTableName}`);
833
1120
  result = eb.selectFrom(() => {
834
- let subQuery = eb.selectFrom(`${relationModel}`).selectAll();
1121
+ let subQuery = this.buildSelectModel(eb, relationModel);
1122
+ subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
835
1123
  if (payload && typeof payload === "object") {
836
1124
  if (payload.where) {
837
1125
  subQuery = subQuery.where((eb2) => this.buildFilter(eb2, relationModel, relationModel, payload.where));
@@ -850,8 +1138,8 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
850
1138
  if (m2m) {
851
1139
  const parentIds = getIdFields(this.schema, model);
852
1140
  const relationIds = getIdFields(this.schema, relationModel);
853
- (0, import_tiny_invariant2.default)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
854
- (0, import_tiny_invariant2.default)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1141
+ (0, import_common_helpers2.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1142
+ (0, import_common_helpers2.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
855
1143
  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}`)));
856
1144
  } else {
857
1145
  const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, relationModel);
@@ -875,34 +1163,57 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
875
1163
  });
876
1164
  return qb;
877
1165
  }
878
- buildRelationObjectArgs(relationModel, relationField, eb, payload, parentName) {
1166
+ buildRelationObjectArgs(relationModel, relationField, eb, payload, parentAlias) {
879
1167
  const relationModelDef = requireModel(this.schema, relationModel);
880
1168
  const objArgs = [];
1169
+ const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
1170
+ if (descendantModels.length > 0) {
1171
+ objArgs.push(...descendantModels.map((subModel) => [
1172
+ import_kysely2.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1173
+ eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
1174
+ ]).flatMap((v) => v));
1175
+ }
881
1176
  if (payload === true || !payload.select) {
882
1177
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
883
1178
  import_kysely2.sql.lit(field),
884
- buildFieldRef(this.schema, relationModel, field, this.options, eb)
1179
+ this.fieldRef(relationModel, field, eb)
885
1180
  ]).flatMap((v) => v));
886
1181
  } else if (payload.select) {
887
- objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field]) => [
888
- import_kysely2.sql.lit(field),
889
- buildFieldRef(this.schema, relationModel, field, this.options, eb)
890
- ]).flatMap((v) => v));
1182
+ objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
1183
+ if (field === "_count") {
1184
+ const subJson = this.buildCountJson(relationModel, eb, `${parentAlias}$${relationField}`, value);
1185
+ return [
1186
+ import_kysely2.sql.lit(field),
1187
+ subJson
1188
+ ];
1189
+ } else {
1190
+ const fieldDef = requireField(this.schema, relationModel, field);
1191
+ const fieldValue = fieldDef.relation ? eb.ref(`${parentAlias}$${relationField}$${field}.$j`) : this.fieldRef(relationModel, field, eb);
1192
+ return [
1193
+ import_kysely2.sql.lit(field),
1194
+ fieldValue
1195
+ ];
1196
+ }
1197
+ }).flatMap((v) => v));
891
1198
  }
892
1199
  if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
893
1200
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field]) => [
894
1201
  import_kysely2.sql.lit(field),
895
- eb.ref(`${parentName}$${relationField}$${field}.$j`)
1202
+ // reference the synthesized JSON field
1203
+ eb.ref(`${parentAlias}$${relationField}$${field}.$j`)
896
1204
  ]).flatMap((v) => v));
897
1205
  }
898
1206
  return objArgs;
899
1207
  }
900
- buildRelationJoins(model, relationField, qb, payload, parentName) {
1208
+ buildRelationJoins(relationModel, relationField, qb, payload, parentName) {
901
1209
  let result = qb;
902
- if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
903
- Object.entries(payload.include).filter(([, value]) => value).forEach(([field, value]) => {
904
- result = this.buildRelationJSON(model, result, field, `${parentName}$${relationField}`, value);
905
- });
1210
+ if (typeof payload === "object") {
1211
+ const selectInclude = payload.include ?? payload.select;
1212
+ if (selectInclude && typeof selectInclude === "object") {
1213
+ Object.entries(selectInclude).filter(([, value]) => value).filter(([field]) => isRelationField(this.schema, relationModel, field)).forEach(([field, value]) => {
1214
+ result = this.buildRelationJSON(relationModel, result, field, `${parentName}$${relationField}`, value);
1215
+ });
1216
+ }
906
1217
  }
907
1218
  return result;
908
1219
  }
@@ -942,12 +1253,15 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
942
1253
  return `ARRAY[${values.map((v) => typeof v === "string" ? `'${v}'` : v)}]`;
943
1254
  }
944
1255
  }
1256
+ get supportInsertWithDefault() {
1257
+ return true;
1258
+ }
945
1259
  };
946
1260
 
947
1261
  // src/client/crud/dialects/sqlite.ts
1262
+ var import_common_helpers3 = require("@zenstackhq/common-helpers");
948
1263
  var import_kysely3 = require("kysely");
949
- var import_tiny_invariant3 = __toESM(require("tiny-invariant"), 1);
950
- var import_ts_pattern3 = require("ts-pattern");
1264
+ var import_ts_pattern4 = require("ts-pattern");
951
1265
  var SqliteCrudDialect = class extends BaseCrudDialect {
952
1266
  static {
953
1267
  __name(this, "SqliteCrudDialect");
@@ -955,26 +1269,31 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
955
1269
  get provider() {
956
1270
  return "sqlite";
957
1271
  }
958
- transformPrimitive(value, type) {
1272
+ transformPrimitive(value, type, _forArrayField) {
959
1273
  if (value === void 0) {
960
1274
  return value;
961
1275
  }
962
1276
  if (Array.isArray(value)) {
963
- return value.map((v) => this.transformPrimitive(v, type));
1277
+ return value.map((v) => this.transformPrimitive(v, type, false));
964
1278
  } else {
965
- 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);
1279
+ if (this.schema.typeDefs && type in this.schema.typeDefs) {
1280
+ return JSON.stringify(value);
1281
+ } else {
1282
+ 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);
1283
+ }
966
1284
  }
967
1285
  }
968
1286
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
969
1287
  return query.select((eb) => this.buildRelationJSON(model, eb, relationField, parentAlias, payload).as(relationField));
970
1288
  }
971
- buildRelationJSON(model, eb, relationField, parentName, payload) {
1289
+ buildRelationJSON(model, eb, relationField, parentAlias, payload) {
972
1290
  const relationFieldDef = requireField(this.schema, model, relationField);
973
1291
  const relationModel = relationFieldDef.type;
974
1292
  const relationModelDef = requireModel(this.schema, relationModel);
975
- const subQueryName = `${parentName}$${relationField}`;
1293
+ const subQueryName = `${parentAlias}$${relationField}`;
976
1294
  let tbl = eb.selectFrom(() => {
977
- let subQuery = eb.selectFrom(relationModel).selectAll();
1295
+ let subQuery = this.buildSelectModel(eb, relationModel);
1296
+ subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
978
1297
  if (payload && typeof payload === "object") {
979
1298
  if (payload.where) {
980
1299
  subQuery = subQuery.where((eb2) => this.buildFilter(eb2, relationModel, relationModel, payload.where));
@@ -993,16 +1312,16 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
993
1312
  if (m2m) {
994
1313
  const parentIds = getIdFields(this.schema, model);
995
1314
  const relationIds = getIdFields(this.schema, relationModel);
996
- (0, import_tiny_invariant3.default)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
997
- (0, import_tiny_invariant3.default)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
998
- 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}`)));
1315
+ (0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1316
+ (0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1317
+ 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}`)));
999
1318
  } else {
1000
1319
  const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
1001
1320
  keyPairs.forEach(({ fk, pk }) => {
1002
1321
  if (ownedByModel) {
1003
- subQuery = subQuery.whereRef(`${relationModel}.${pk}`, "=", `${parentName}.${fk}`);
1322
+ subQuery = subQuery.whereRef(`${relationModel}.${pk}`, "=", `${parentAlias}.${fk}`);
1004
1323
  } else {
1005
- subQuery = subQuery.whereRef(`${relationModel}.${fk}`, "=", `${parentName}.${pk}`);
1324
+ subQuery = subQuery.whereRef(`${relationModel}.${fk}`, "=", `${parentAlias}.${pk}`);
1006
1325
  }
1007
1326
  });
1008
1327
  }
@@ -1010,167 +1329,106 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1010
1329
  });
1011
1330
  tbl = tbl.select(() => {
1012
1331
  const objArgs = [];
1332
+ const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
1333
+ if (descendantModels.length > 0) {
1334
+ objArgs.push(...descendantModels.map((subModel) => [
1335
+ import_kysely3.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1336
+ eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
1337
+ ]).flatMap((v) => v));
1338
+ }
1013
1339
  if (payload === true || !payload.select) {
1014
1340
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
1015
1341
  import_kysely3.sql.lit(field),
1016
- buildFieldRef(this.schema, relationModel, field, this.options, eb)
1342
+ this.fieldRef(relationModel, field, eb)
1017
1343
  ]).flatMap((v) => v));
1018
1344
  } else if (payload.select) {
1019
1345
  objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
1020
- const fieldDef = requireField(this.schema, relationModel, field);
1021
- if (fieldDef.relation) {
1022
- const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentName}$${relationField}`, value);
1346
+ if (field === "_count") {
1347
+ const subJson = this.buildCountJson(relationModel, eb, `${parentAlias}$${relationField}`, value);
1023
1348
  return [
1024
1349
  import_kysely3.sql.lit(field),
1025
1350
  subJson
1026
1351
  ];
1027
1352
  } else {
1028
- return [
1029
- import_kysely3.sql.lit(field),
1030
- buildFieldRef(this.schema, relationModel, field, this.options, eb)
1031
- ];
1353
+ const fieldDef = requireField(this.schema, relationModel, field);
1354
+ if (fieldDef.relation) {
1355
+ const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
1356
+ return [
1357
+ import_kysely3.sql.lit(field),
1358
+ subJson
1359
+ ];
1360
+ } else {
1361
+ return [
1362
+ import_kysely3.sql.lit(field),
1363
+ this.fieldRef(relationModel, field, eb)
1364
+ ];
1365
+ }
1032
1366
  }
1033
1367
  }).flatMap((v) => v));
1034
1368
  }
1035
1369
  if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
1036
1370
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field, value]) => {
1037
- const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentName}$${relationField}`, value);
1371
+ const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
1038
1372
  return [
1039
1373
  import_kysely3.sql.lit(field),
1040
1374
  subJson
1041
1375
  ];
1042
1376
  }).flatMap((v) => v));
1043
- }
1044
- if (relationFieldDef.array) {
1045
- return eb.fn.coalesce(import_kysely3.sql`json_group_array(json_object(${import_kysely3.sql.join(objArgs)}))`, import_kysely3.sql`json_array()`).as("$j");
1046
- } else {
1047
- return import_kysely3.sql`json_object(${import_kysely3.sql.join(objArgs)})`.as("data");
1048
- }
1049
- });
1050
- return tbl;
1051
- }
1052
- buildSkipTake(query, skip, take) {
1053
- if (take !== void 0) {
1054
- query = query.limit(take);
1055
- }
1056
- if (skip !== void 0) {
1057
- query = query.offset(skip);
1058
- if (take === void 0) {
1059
- query = query.limit(-1);
1060
- }
1061
- }
1062
- return query;
1063
- }
1064
- buildJsonObject(eb, value) {
1065
- return eb.fn("json_object", Object.entries(value).flatMap(([key, value2]) => [
1066
- import_kysely3.sql.lit(key),
1067
- value2
1068
- ]));
1069
- }
1070
- get supportsUpdateWithLimit() {
1071
- return false;
1072
- }
1073
- get supportsDeleteWithLimit() {
1074
- return false;
1075
- }
1076
- get supportsDistinctOn() {
1077
- return false;
1078
- }
1079
- buildArrayLength(eb, array) {
1080
- return eb.fn("json_array_length", [
1081
- array
1082
- ]);
1083
- }
1084
- buildArrayLiteralSQL(_values) {
1085
- throw new Error("SQLite does not support array literals");
1086
- }
1087
- };
1088
-
1089
- // src/client/crud/dialects/index.ts
1090
- function getCrudDialect(schema, options) {
1091
- return (0, import_ts_pattern4.match)(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
1092
- }
1093
- __name(getCrudDialect, "getCrudDialect");
1094
-
1095
- // src/schema/expression.ts
1096
- var ExpressionUtils = {
1097
- literal: /* @__PURE__ */ __name((value) => {
1098
- return {
1099
- kind: "literal",
1100
- value
1101
- };
1102
- }, "literal"),
1103
- array: /* @__PURE__ */ __name((items) => {
1104
- return {
1105
- kind: "array",
1106
- items
1107
- };
1108
- }, "array"),
1109
- call: /* @__PURE__ */ __name((functionName, args) => {
1110
- return {
1111
- kind: "call",
1112
- function: functionName,
1113
- args
1114
- };
1115
- }, "call"),
1116
- binary: /* @__PURE__ */ __name((left, op, right) => {
1117
- return {
1118
- kind: "binary",
1119
- op,
1120
- left,
1121
- right
1122
- };
1123
- }, "binary"),
1124
- unary: /* @__PURE__ */ __name((op, operand) => {
1125
- return {
1126
- kind: "unary",
1127
- op,
1128
- operand
1129
- };
1130
- }, "unary"),
1131
- field: /* @__PURE__ */ __name((field) => {
1132
- return {
1133
- kind: "field",
1134
- field
1135
- };
1136
- }, "field"),
1137
- member: /* @__PURE__ */ __name((receiver, members) => {
1138
- return {
1139
- kind: "member",
1140
- receiver,
1141
- members
1142
- };
1143
- }, "member"),
1144
- _this: /* @__PURE__ */ __name(() => {
1145
- return {
1146
- kind: "this"
1147
- };
1148
- }, "_this"),
1149
- _null: /* @__PURE__ */ __name(() => {
1150
- return {
1151
- kind: "null"
1152
- };
1153
- }, "_null"),
1154
- and: /* @__PURE__ */ __name((expr2, ...expressions) => {
1155
- return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "&&", exp), expr2);
1156
- }, "and"),
1157
- or: /* @__PURE__ */ __name((expr2, ...expressions) => {
1158
- return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
1159
- }, "or"),
1160
- is: /* @__PURE__ */ __name((value, kind) => {
1161
- return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
1162
- }, "is"),
1163
- isLiteral: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "literal"), "isLiteral"),
1164
- isArray: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "array"), "isArray"),
1165
- isCall: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "call"), "isCall"),
1166
- isNull: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "null"), "isNull"),
1167
- isThis: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "this"), "isThis"),
1168
- isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
1169
- isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
1170
- isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
1171
- isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
1377
+ }
1378
+ if (relationFieldDef.array) {
1379
+ return eb.fn.coalesce(import_kysely3.sql`json_group_array(json_object(${import_kysely3.sql.join(objArgs)}))`, import_kysely3.sql`json_array()`).as("$j");
1380
+ } else {
1381
+ return import_kysely3.sql`json_object(${import_kysely3.sql.join(objArgs)})`.as("data");
1382
+ }
1383
+ });
1384
+ return tbl;
1385
+ }
1386
+ buildSkipTake(query, skip, take) {
1387
+ if (take !== void 0) {
1388
+ query = query.limit(take);
1389
+ }
1390
+ if (skip !== void 0) {
1391
+ query = query.offset(skip);
1392
+ if (take === void 0) {
1393
+ query = query.limit(-1);
1394
+ }
1395
+ }
1396
+ return query;
1397
+ }
1398
+ buildJsonObject(eb, value) {
1399
+ return eb.fn("json_object", Object.entries(value).flatMap(([key, value2]) => [
1400
+ import_kysely3.sql.lit(key),
1401
+ value2
1402
+ ]));
1403
+ }
1404
+ get supportsUpdateWithLimit() {
1405
+ return false;
1406
+ }
1407
+ get supportsDeleteWithLimit() {
1408
+ return false;
1409
+ }
1410
+ get supportsDistinctOn() {
1411
+ return false;
1412
+ }
1413
+ buildArrayLength(eb, array) {
1414
+ return eb.fn("json_array_length", [
1415
+ array
1416
+ ]);
1417
+ }
1418
+ buildArrayLiteralSQL(_values) {
1419
+ throw new Error("SQLite does not support array literals");
1420
+ }
1421
+ get supportInsertWithDefault() {
1422
+ return false;
1423
+ }
1172
1424
  };
1173
1425
 
1426
+ // src/client/crud/dialects/index.ts
1427
+ function getCrudDialect(schema, options) {
1428
+ return (0, import_ts_pattern5.match)(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
1429
+ }
1430
+ __name(getCrudDialect, "getCrudDialect");
1431
+
1174
1432
  // src/utils/default-operation-node-visitor.ts
1175
1433
  var import_kysely4 = require("kysely");
1176
1434
  var DefaultOperationNodeVisitor = class extends import_kysely4.OperationNodeVisitor {
@@ -1490,19 +1748,19 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
1490
1748
  };
1491
1749
 
1492
1750
  // src/plugins/policy/expression-transformer.ts
1751
+ var import_common_helpers5 = require("@zenstackhq/common-helpers");
1493
1752
  var import_kysely6 = require("kysely");
1494
- var import_tiny_invariant5 = __toESM(require("tiny-invariant"), 1);
1495
- var import_ts_pattern6 = require("ts-pattern");
1753
+ var import_ts_pattern7 = require("ts-pattern");
1496
1754
 
1497
1755
  // src/plugins/policy/expression-evaluator.ts
1498
- var import_tiny_invariant4 = __toESM(require("tiny-invariant"), 1);
1499
- var import_ts_pattern5 = require("ts-pattern");
1756
+ var import_common_helpers4 = require("@zenstackhq/common-helpers");
1757
+ var import_ts_pattern6 = require("ts-pattern");
1500
1758
  var ExpressionEvaluator = class {
1501
1759
  static {
1502
1760
  __name(this, "ExpressionEvaluator");
1503
1761
  }
1504
1762
  evaluate(expression, context) {
1505
- 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();
1763
+ 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();
1506
1764
  return result ?? null;
1507
1765
  }
1508
1766
  evaluateCall(expr2, context) {
@@ -1513,7 +1771,7 @@ var ExpressionEvaluator = class {
1513
1771
  }
1514
1772
  }
1515
1773
  evaluateUnary(expr2, context) {
1516
- return (0, import_ts_pattern5.match)(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1774
+ return (0, import_ts_pattern6.match)(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1517
1775
  }
1518
1776
  evaluateMember(expr2, context) {
1519
1777
  let val = this.evaluate(expr2.receiver, context);
@@ -1537,21 +1795,21 @@ var ExpressionEvaluator = class {
1537
1795
  }
1538
1796
  const left = this.evaluate(expr2.left, context);
1539
1797
  const right = this.evaluate(expr2.right, context);
1540
- 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", () => {
1798
+ 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", () => {
1541
1799
  const _right = right ?? [];
1542
- (0, import_tiny_invariant4.default)(Array.isArray(_right), 'expected array for "in" operator');
1800
+ (0, import_common_helpers4.invariant)(Array.isArray(_right), 'expected array for "in" operator');
1543
1801
  return _right.includes(left);
1544
1802
  }).exhaustive();
1545
1803
  }
1546
1804
  evaluateCollectionPredicate(expr2, context) {
1547
1805
  const op = expr2.op;
1548
- (0, import_tiny_invariant4.default)(op === "?" || op === "!" || op === "^", 'expected "?" or "!" or "^" operator');
1806
+ (0, import_common_helpers4.invariant)(op === "?" || op === "!" || op === "^", 'expected "?" or "!" or "^" operator');
1549
1807
  const left = this.evaluate(expr2.left, context);
1550
1808
  if (!left) {
1551
1809
  return false;
1552
1810
  }
1553
- (0, import_tiny_invariant4.default)(Array.isArray(left), "expected array");
1554
- return (0, import_ts_pattern5.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1811
+ (0, import_common_helpers4.invariant)(Array.isArray(left), "expected array");
1812
+ return (0, import_ts_pattern6.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1555
1813
  ...context,
1556
1814
  thisValue: item
1557
1815
  }))).with("!", () => left.every((item) => this.evaluate(expr2.right, {
@@ -1567,11 +1825,11 @@ var ExpressionEvaluator = class {
1567
1825
  // src/plugins/policy/utils.ts
1568
1826
  var import_kysely5 = require("kysely");
1569
1827
  function trueNode(dialect) {
1570
- return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean"));
1828
+ return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean", false));
1571
1829
  }
1572
1830
  __name(trueNode, "trueNode");
1573
1831
  function falseNode(dialect) {
1574
- return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean"));
1832
+ return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean", false));
1575
1833
  }
1576
1834
  __name(falseNode, "falseNode");
1577
1835
  function isTrueNode(node) {
@@ -1772,20 +2030,20 @@ var ExpressionTransformer = class {
1772
2030
  return import_kysely6.BinaryOperationNode.create(left, this.transformOperator(op), right);
1773
2031
  }
1774
2032
  transformCollectionPredicate(expr2, context) {
1775
- (0, import_tiny_invariant5.default)(expr2.op === "?" || expr2.op === "!" || expr2.op === "^", 'expected "?" or "!" or "^" operator');
2033
+ (0, import_common_helpers5.invariant)(expr2.op === "?" || expr2.op === "!" || expr2.op === "^", 'expected "?" or "!" or "^" operator');
1776
2034
  if (this.isAuthCall(expr2.left) || this.isAuthMember(expr2.left)) {
1777
2035
  const value = new ExpressionEvaluator().evaluate(expr2, {
1778
2036
  auth: this.auth
1779
2037
  });
1780
2038
  return this.transformValue(value, "Boolean");
1781
2039
  }
1782
- (0, import_tiny_invariant5.default)(ExpressionUtils.isField(expr2.left) || ExpressionUtils.isMember(expr2.left), "left operand must be field or member access");
2040
+ (0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.left) || ExpressionUtils.isMember(expr2.left), "left operand must be field or member access");
1783
2041
  let newContextModel;
1784
2042
  if (ExpressionUtils.isField(expr2.left)) {
1785
2043
  const fieldDef = requireField(this.schema, context.model, expr2.left.field);
1786
2044
  newContextModel = fieldDef.type;
1787
2045
  } else {
1788
- (0, import_tiny_invariant5.default)(ExpressionUtils.isField(expr2.left.receiver));
2046
+ (0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.left.receiver));
1789
2047
  const fieldDef = requireField(this.schema, context.model, expr2.left.receiver.field);
1790
2048
  newContextModel = fieldDef.type;
1791
2049
  for (const member of expr2.left.members) {
@@ -1805,7 +2063,7 @@ var ExpressionTransformer = class {
1805
2063
  const count = import_kysely6.FunctionNode.create("count", [
1806
2064
  import_kysely6.ValueNode.createImmediate(1)
1807
2065
  ]);
1808
- 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();
2066
+ 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();
1809
2067
  return this.transform(expr2.left, {
1810
2068
  ...context,
1811
2069
  memberSelect: import_kysely6.SelectionNode.create(import_kysely6.AliasNode.create(predicateResult, import_kysely6.IdentifierNode.create("$t"))),
@@ -1829,14 +2087,14 @@ var ExpressionTransformer = class {
1829
2087
  }
1830
2088
  }
1831
2089
  transformValue(value, type) {
1832
- return import_kysely6.ValueNode.create(this.dialect.transformPrimitive(value, type) ?? null);
2090
+ return import_kysely6.ValueNode.create(this.dialect.transformPrimitive(value, type, false) ?? null);
1833
2091
  }
1834
2092
  _unary(expr2, context) {
1835
- (0, import_tiny_invariant5.default)(expr2.op === "!", 'only "!" operator is supported');
2093
+ (0, import_common_helpers5.invariant)(expr2.op === "!", 'only "!" operator is supported');
1836
2094
  return import_kysely6.BinaryOperationNode.create(this.transform(expr2.operand, context), this.transformOperator("!="), trueNode(this.dialect));
1837
2095
  }
1838
2096
  transformOperator(op) {
1839
- const mappedOp = (0, import_ts_pattern6.match)(op).with("==", () => "=").otherwise(() => op);
2097
+ const mappedOp = (0, import_ts_pattern7.match)(op).with("==", () => "=").otherwise(() => op);
1840
2098
  return import_kysely6.OperatorNode.create(mappedOp);
1841
2099
  }
1842
2100
  _call(expr2, context) {
@@ -1875,10 +2133,10 @@ var ExpressionTransformer = class {
1875
2133
  if (this.isAuthCall(expr2.receiver)) {
1876
2134
  return this.valueMemberAccess(this.auth, expr2, this.authType);
1877
2135
  }
1878
- (0, import_tiny_invariant5.default)(ExpressionUtils.isField(expr2.receiver), "expect receiver to be field expression");
2136
+ (0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.receiver), "expect receiver to be field expression");
1879
2137
  const { memberFilter, memberSelect, ...restContext } = context;
1880
2138
  const receiver = this.transform(expr2.receiver, restContext);
1881
- (0, import_tiny_invariant5.default)(import_kysely6.SelectQueryNode.is(receiver), "expected receiver to be select query");
2139
+ (0, import_common_helpers5.invariant)(import_kysely6.SelectQueryNode.is(receiver), "expected receiver to be select query");
1882
2140
  const receiverField = requireField(this.schema, context.model, expr2.receiver.field);
1883
2141
  const memberFields = [];
1884
2142
  let currType = receiverField.type;
@@ -1902,7 +2160,7 @@ var ExpressionTransformer = class {
1902
2160
  thisEntity: void 0
1903
2161
  });
1904
2162
  if (currNode) {
1905
- (0, import_tiny_invariant5.default)(import_kysely6.SelectQueryNode.is(currNode), "expected select query node");
2163
+ (0, import_common_helpers5.invariant)(import_kysely6.SelectQueryNode.is(currNode), "expected select query node");
1906
2164
  currNode = {
1907
2165
  ...relation,
1908
2166
  selections: [
@@ -1919,8 +2177,8 @@ var ExpressionTransformer = class {
1919
2177
  };
1920
2178
  }
1921
2179
  } else {
1922
- (0, import_tiny_invariant5.default)(i === expr2.members.length - 1, "plain field access must be the last segment");
1923
- (0, import_tiny_invariant5.default)(!currNode, "plain field access must be the last segment");
2180
+ (0, import_common_helpers5.invariant)(i === expr2.members.length - 1, "plain field access must be the last segment");
2181
+ (0, import_common_helpers5.invariant)(!currNode, "plain field access must be the last segment");
1924
2182
  currNode = import_kysely6.ColumnNode.create(member);
1925
2183
  }
1926
2184
  }
@@ -2072,7 +2330,7 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2072
2330
  get kysely() {
2073
2331
  return this.client.$qb;
2074
2332
  }
2075
- async handle(node, proceed, transaction) {
2333
+ async handle(node, proceed) {
2076
2334
  if (!this.isCrudQueryNode(node)) {
2077
2335
  throw new RejectedByPolicyError(void 0, "non-CRUD queries are not allowed");
2078
2336
  }
@@ -2092,27 +2350,20 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2092
2350
  if (!mutationRequiresTransaction && !node.returning) {
2093
2351
  return proceed(this.transformNode(node));
2094
2352
  }
2095
- let readBackError = false;
2096
- const result = await transaction(async (txProceed) => {
2097
- if (import_kysely7.InsertQueryNode.is(node)) {
2098
- await this.enforcePreCreatePolicy(node, txProceed);
2099
- }
2100
- const transformedNode = this.transformNode(node);
2101
- const result2 = await txProceed(transformedNode);
2102
- if (!this.onlyReturningId(node)) {
2103
- const readBackResult = await this.processReadBack(node, result2, txProceed);
2104
- if (readBackResult.rows.length !== result2.rows.length) {
2105
- readBackError = true;
2106
- }
2107
- return readBackResult;
2108
- } else {
2109
- return result2;
2353
+ if (import_kysely7.InsertQueryNode.is(node)) {
2354
+ await this.enforcePreCreatePolicy(node, proceed);
2355
+ }
2356
+ const transformedNode = this.transformNode(node);
2357
+ const result = await proceed(transformedNode);
2358
+ if (!this.onlyReturningId(node)) {
2359
+ const readBackResult = await this.processReadBack(node, result, proceed);
2360
+ if (readBackResult.rows.length !== result.rows.length) {
2361
+ throw new RejectedByPolicyError(mutationModel, "result is not allowed to be read back");
2110
2362
  }
2111
- });
2112
- if (readBackError) {
2113
- throw new RejectedByPolicyError(mutationModel, "result is not allowed to be read back");
2363
+ return readBackResult;
2364
+ } else {
2365
+ return result;
2114
2366
  }
2115
- return result;
2116
2367
  }
2117
2368
  onlyReturningId(node) {
2118
2369
  if (!node.returning) {
@@ -2165,19 +2416,19 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2165
2416
  }
2166
2417
  }
2167
2418
  unwrapCreateValueRow(data, model, fields) {
2168
- (0, import_tiny_invariant6.default)(data.length === fields.length, "data length must match fields length");
2419
+ (0, import_common_helpers6.invariant)(data.length === fields.length, "data length must match fields length");
2169
2420
  const result = [];
2170
2421
  for (let i = 0; i < data.length; i++) {
2171
2422
  const item = data[i];
2172
2423
  const fieldDef = requireField(this.client.$schema, model, fields[i]);
2173
2424
  if (typeof item === "object" && item && "kind" in item) {
2174
- (0, import_tiny_invariant6.default)(item.kind === "ValueNode", "expecting a ValueNode");
2425
+ (0, import_common_helpers6.invariant)(item.kind === "ValueNode", "expecting a ValueNode");
2175
2426
  result.push({
2176
- node: import_kysely7.ValueNode.create(this.dialect.transformPrimitive(item.value, fieldDef.type)),
2427
+ node: import_kysely7.ValueNode.create(this.dialect.transformPrimitive(item.value, fieldDef.type, !!fieldDef.array)),
2177
2428
  raw: item.value
2178
2429
  });
2179
2430
  } else {
2180
- const value = this.dialect.transformPrimitive(item, fieldDef.type);
2431
+ const value = this.dialect.transformPrimitive(item, fieldDef.type, !!fieldDef.array);
2181
2432
  if (Array.isArray(value)) {
2182
2433
  result.push({
2183
2434
  node: import_kysely7.RawNode.createWithSql(this.dialect.buildArrayLiteralSQL(value)),
@@ -2246,7 +2497,7 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2246
2497
  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]))))));
2247
2498
  }
2248
2499
  getMutationModel(node) {
2249
- 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) => {
2500
+ 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) => {
2250
2501
  if (node2.from.froms.length !== 1) {
2251
2502
  throw new InternalError("Only one from table is supported for delete");
2252
2503
  }
@@ -2379,8 +2630,8 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2379
2630
  const modelDef = requireModel(this.client.$schema, modelName);
2380
2631
  const result = [];
2381
2632
  const extractOperations = /* @__PURE__ */ __name((expr2) => {
2382
- (0, import_tiny_invariant6.default)(ExpressionUtils.isLiteral(expr2), "expecting a literal");
2383
- (0, import_tiny_invariant6.default)(typeof expr2.value === "string", "expecting a string literal");
2633
+ (0, import_common_helpers6.invariant)(ExpressionUtils.isLiteral(expr2), "expecting a literal");
2634
+ (0, import_common_helpers6.invariant)(typeof expr2.value === "string", "expecting a string literal");
2384
2635
  return expr2.value.split(",").filter((v) => !!v).map((v) => v.trim());
2385
2636
  }, "extractOperations");
2386
2637
  if (modelDef.attributes) {
@@ -2408,20 +2659,29 @@ var PolicyPlugin = class {
2408
2659
  get description() {
2409
2660
  return "Enforces access policies defined in the schema.";
2410
2661
  }
2411
- onKyselyQuery({ query, client, proceed, transaction }) {
2662
+ onKyselyQuery({
2663
+ query,
2664
+ client,
2665
+ proceed
2666
+ /*, transaction*/
2667
+ }) {
2412
2668
  const handler = new PolicyHandler(client);
2413
- return handler.handle(query, proceed, transaction);
2669
+ return handler.handle(
2670
+ query,
2671
+ proceed
2672
+ /*, transaction*/
2673
+ );
2414
2674
  }
2415
2675
  };
2416
2676
 
2417
2677
  // src/utils/clone.ts
2418
- var import_is_plain_object2 = require("is-plain-object");
2678
+ var import_common_helpers7 = require("@zenstackhq/common-helpers");
2419
2679
  function clone(value) {
2420
2680
  if (Array.isArray(value)) {
2421
2681
  return value.map((v) => clone(v));
2422
2682
  }
2423
2683
  if (typeof value === "object") {
2424
- if (!value || !(0, import_is_plain_object2.isPlainObject)(value)) {
2684
+ if (!value || !(0, import_common_helpers7.isPlainObject)(value)) {
2425
2685
  return value;
2426
2686
  }
2427
2687
  const result = {};
@@ -2434,28 +2694,6 @@ function clone(value) {
2434
2694
  }
2435
2695
  __name(clone, "clone");
2436
2696
 
2437
- // src/utils/object-utils.ts
2438
- function extractFields(obj, fields) {
2439
- return Object.fromEntries(Object.entries(obj).filter(([key]) => fields.includes(key)));
2440
- }
2441
- __name(extractFields, "extractFields");
2442
- function fieldsToSelectObject(fields) {
2443
- return Object.fromEntries(fields.map((f) => [
2444
- f,
2445
- true
2446
- ]));
2447
- }
2448
- __name(fieldsToSelectObject, "fieldsToSelectObject");
2449
-
2450
- // src/client/constants.ts
2451
- var CONTEXT_COMMENT_PREFIX = "-- $$context:";
2452
- var NUMERIC_FIELD_TYPES = [
2453
- "Int",
2454
- "Float",
2455
- "BigInt",
2456
- "Decimal"
2457
- ];
2458
-
2459
2697
  // src/client/crud/operations/base.ts
2460
2698
  var BaseOperationHandler = class {
2461
2699
  static {
@@ -2499,17 +2737,17 @@ var BaseOperationHandler = class {
2499
2737
  getField(model, field) {
2500
2738
  return getField(this.schema, model, field);
2501
2739
  }
2502
- exists(kysely, model, filter) {
2740
+ async exists(kysely, model, filter) {
2503
2741
  const idFields = getIdFields(this.schema, model);
2504
2742
  const _filter = flattenCompoundUniqueFilters(this.schema, model, filter);
2505
2743
  const query = kysely.selectFrom(model).where((eb) => eb.and(_filter)).select(idFields.map((f) => kysely.dynamic.ref(f))).limit(1).modifyEnd(this.makeContextComment({
2506
2744
  model,
2507
2745
  operation: "read"
2508
2746
  }));
2509
- return query.executeTakeFirst();
2747
+ return this.executeQueryTakeFirst(kysely, query, "exists");
2510
2748
  }
2511
2749
  async read(kysely, model, args) {
2512
- let query = kysely.selectFrom(model);
2750
+ let query = this.dialect.buildSelectModel((0, import_kysely8.expressionBuilder)(), model);
2513
2751
  if (args?.where) {
2514
2752
  query = query.where((eb) => this.dialect.buildFilter(eb, model, model, args?.where));
2515
2753
  }
@@ -2529,15 +2767,16 @@ var BaseOperationHandler = class {
2529
2767
  query = query.distinctOn(distinct.map((f) => import_kysely8.sql.ref(`${model}.${f}`)));
2530
2768
  } else {
2531
2769
  inMemoryDistinct = distinct;
2770
+ query = distinct.reduce((acc, field) => acc.select((eb) => this.dialect.fieldRef(model, field, eb).as(`$distinct$${field}`)), query);
2532
2771
  }
2533
2772
  }
2534
- if (args?.select) {
2535
- query = this.buildFieldSelection(model, query, args?.select, model);
2773
+ if (args && "select" in args && args.select) {
2774
+ query = this.buildFieldSelection(model, query, args.select, model);
2536
2775
  } else {
2537
- query = this.buildSelectAllScalarFields(model, query, args?.omit);
2776
+ query = this.dialect.buildSelectAllFields(model, query, args?.omit);
2538
2777
  }
2539
- if (args?.include) {
2540
- query = this.buildFieldSelection(model, query, args?.include, model);
2778
+ if (args && "include" in args && args.include) {
2779
+ query = this.buildFieldSelection(model, query, args.include, model);
2541
2780
  }
2542
2781
  if (args?.cursor) {
2543
2782
  query = this.buildCursorFilter(model, query, args.cursor, args.orderBy, negateOrderBy);
@@ -2547,23 +2786,35 @@ var BaseOperationHandler = class {
2547
2786
  operation: "read"
2548
2787
  }));
2549
2788
  let result = [];
2789
+ const queryId = {
2790
+ queryId: `zenstack-${(0, import_cuid2.createId)()}`
2791
+ };
2792
+ const compiled = kysely.getExecutor().compileQuery(query.toOperationNode(), queryId);
2550
2793
  try {
2551
- result = await query.execute();
2794
+ const r = await kysely.getExecutor().executeQuery(compiled, queryId);
2795
+ result = r.rows;
2552
2796
  } catch (err) {
2553
- const { sql: sql10, parameters } = query.compile();
2554
- throw new QueryError(`Failed to execute query: ${err}, sql: ${sql10}, parameters: ${parameters}`);
2797
+ let message = `Failed to execute query: ${err}, sql: ${compiled.sql}`;
2798
+ if (this.options.debug) {
2799
+ message += `, parameters:
2800
+ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
2801
+ }
2802
+ throw new QueryError(message, err);
2555
2803
  }
2556
2804
  if (inMemoryDistinct) {
2557
2805
  const distinctResult = [];
2558
2806
  const seen = /* @__PURE__ */ new Set();
2559
2807
  for (const r of result) {
2560
- const key = safeJSONStringify(inMemoryDistinct.map((f) => r[f]));
2808
+ const key = safeJSONStringify(inMemoryDistinct.map((f) => r[`$distinct$${f}`]));
2561
2809
  if (!seen.has(key)) {
2562
2810
  distinctResult.push(r);
2563
2811
  seen.add(key);
2564
2812
  }
2565
2813
  }
2566
2814
  result = distinctResult;
2815
+ for (const r of result) {
2816
+ Object.keys(r).filter((k) => k.startsWith("$distinct$")).forEach((k) => delete r[k]);
2817
+ }
2567
2818
  }
2568
2819
  return result;
2569
2820
  }
@@ -2586,65 +2837,22 @@ var BaseOperationHandler = class {
2586
2837
  }
2587
2838
  const fieldDef = this.requireField(model, field);
2588
2839
  if (!fieldDef.relation) {
2589
- result = this.selectField(result, model, parentAlias, field);
2840
+ result = this.dialect.buildSelectField(result, model, parentAlias, field);
2590
2841
  } else {
2591
2842
  if (!fieldDef.array && !fieldDef.optional && payload.where) {
2592
2843
  throw new QueryError(`Field "${field}" doesn't support filtering`);
2593
2844
  }
2594
- result = this.dialect.buildRelationSelection(result, model, field, parentAlias, payload);
2845
+ if (fieldDef.originModel) {
2846
+ result = this.dialect.buildRelationSelection(result, fieldDef.originModel, field, fieldDef.originModel, payload);
2847
+ } else {
2848
+ result = this.dialect.buildRelationSelection(result, model, field, parentAlias, payload);
2849
+ }
2595
2850
  }
2596
2851
  }
2597
2852
  return result;
2598
2853
  }
2599
2854
  buildCountSelection(query, model, parentAlias, payload) {
2600
- const modelDef = requireModel(this.schema, model);
2601
- const toManyRelations = Object.entries(modelDef.fields).filter(([, field]) => field.relation && field.array);
2602
- const selections = payload === true ? {
2603
- select: toManyRelations.reduce((acc, [field]) => {
2604
- acc[field] = true;
2605
- return acc;
2606
- }, {})
2607
- } : payload;
2608
- const eb = (0, import_kysely8.expressionBuilder)();
2609
- const jsonObject = {};
2610
- for (const [field, value] of Object.entries(selections.select)) {
2611
- const fieldDef = requireField(this.schema, model, field);
2612
- const fieldModel = fieldDef.type;
2613
- const jointTable = `${parentAlias}$${field}$count`;
2614
- const joinPairs = buildJoinPairs(this.schema, model, parentAlias, field, jointTable);
2615
- query = query.leftJoin((eb2) => {
2616
- let result = eb2.selectFrom(fieldModel).selectAll();
2617
- if (value && typeof value === "object" && "where" in value && value.where && typeof value.where === "object") {
2618
- const filter = this.dialect.buildFilter(eb2, fieldModel, fieldModel, value.where);
2619
- result = result.where(filter);
2620
- }
2621
- return result.as(jointTable);
2622
- }, (join) => {
2623
- for (const [left, right] of joinPairs) {
2624
- join = join.onRef(left, "=", right);
2625
- }
2626
- return join;
2627
- });
2628
- jsonObject[field] = this.countIdDistinct(eb, fieldDef.type, jointTable);
2629
- }
2630
- query = query.select((eb2) => this.dialect.buildJsonObject(eb2, jsonObject).as("_count"));
2631
- return query;
2632
- }
2633
- countIdDistinct(eb, model, table) {
2634
- const idFields = getIdFields(this.schema, model);
2635
- return eb.fn.count(import_kysely8.sql.join(idFields.map((f) => import_kysely8.sql.ref(`${table}.${f}`)))).distinct();
2636
- }
2637
- buildSelectAllScalarFields(model, query, omit) {
2638
- const modelDef = this.requireModel(model);
2639
- return Object.keys(modelDef.fields).filter((f) => !isRelationField(this.schema, model, f)).filter((f) => omit?.[f] !== true).reduce((acc, f) => this.selectField(acc, model, model, f), query);
2640
- }
2641
- selectField(query, model, modelAlias, field) {
2642
- const fieldDef = this.requireField(model, field);
2643
- if (!fieldDef.computed) {
2644
- return query.select(import_kysely8.sql.ref(`${modelAlias}.${field}`).as(field));
2645
- } else {
2646
- return query.select((eb) => buildFieldRef(this.schema, model, field, this.options, eb).as(field));
2647
- }
2855
+ return query.select((eb) => this.dialect.buildCountJson(model, eb, parentAlias, payload).as("_count"));
2648
2856
  }
2649
2857
  buildCursorFilter(model, query, cursor, orderBy, negateOrderBy) {
2650
2858
  if (!orderBy) {
@@ -2668,9 +2876,12 @@ var BaseOperationHandler = class {
2668
2876
  result = result.where((eb2) => eb2.or(filters));
2669
2877
  return result;
2670
2878
  }
2671
- async create(kysely, model, data, fromRelation) {
2879
+ async create(kysely, model, data, fromRelation, creatingForDelegate = false) {
2672
2880
  const modelDef = this.requireModel(model);
2673
- const createFields = {};
2881
+ if (modelDef.isDelegate && !creatingForDelegate) {
2882
+ throw new QueryError(`Model "${this.model}" is a delegate and cannot be created directly.`);
2883
+ }
2884
+ let createFields = {};
2674
2885
  let parentUpdateTask = void 0;
2675
2886
  let m2m = void 0;
2676
2887
  if (fromRelation) {
@@ -2689,7 +2900,7 @@ var BaseOperationHandler = class {
2689
2900
  model: fromRelation.model,
2690
2901
  operation: "update"
2691
2902
  }));
2692
- return query2.execute();
2903
+ return this.executeQuery(kysely, query2, "update");
2693
2904
  }, "parentUpdateTask");
2694
2905
  }
2695
2906
  }
@@ -2699,14 +2910,14 @@ var BaseOperationHandler = class {
2699
2910
  const fieldDef = this.requireField(model, field);
2700
2911
  if (isScalarField(this.schema, model, field) || isForeignKeyField(this.schema, model, field)) {
2701
2912
  if (fieldDef.array && value && typeof value === "object" && "set" in value && Array.isArray(value.set)) {
2702
- createFields[field] = this.dialect.transformPrimitive(value.set, fieldDef.type);
2913
+ createFields[field] = this.dialect.transformPrimitive(value.set, fieldDef.type, true);
2703
2914
  } else {
2704
- createFields[field] = this.dialect.transformPrimitive(value, fieldDef.type);
2915
+ createFields[field] = this.dialect.transformPrimitive(value, fieldDef.type, !!fieldDef.array);
2705
2916
  }
2706
2917
  } else {
2707
2918
  const subM2M = getManyToManyRelation(this.schema, model, field);
2708
2919
  if (!subM2M && fieldDef.relation?.fields && fieldDef.relation?.references) {
2709
- const fkValues = await this.processOwnedRelation(kysely, fieldDef, value);
2920
+ const fkValues = await this.processOwnedRelationForCreate(kysely, fieldDef, value);
2710
2921
  for (let i = 0; i < fieldDef.relation.fields.length; i++) {
2711
2922
  createFields[fieldDef.relation.fields[i]] = fkValues[fieldDef.relation.references[i]];
2712
2923
  }
@@ -2718,16 +2929,20 @@ var BaseOperationHandler = class {
2718
2929
  }
2719
2930
  }
2720
2931
  }
2932
+ if (modelDef.baseModel) {
2933
+ const baseCreateResult = await this.processBaseModelCreate(kysely, modelDef.baseModel, createFields, model);
2934
+ createFields = baseCreateResult.remainingFields;
2935
+ }
2721
2936
  const updatedData = this.fillGeneratedValues(modelDef, createFields);
2722
2937
  const idFields = getIdFields(this.schema, model);
2723
- const query = kysely.insertInto(model).values(updatedData).returning(idFields).modifyEnd(this.makeContextComment({
2938
+ const query = kysely.insertInto(model).$if(Object.keys(updatedData).length === 0, (qb) => qb.defaultValues()).$if(Object.keys(updatedData).length > 0, (qb) => qb.values(updatedData)).returning(idFields).modifyEnd(this.makeContextComment({
2724
2939
  model,
2725
2940
  operation: "create"
2726
2941
  }));
2727
- const createdEntity = await query.executeTakeFirst();
2942
+ const createdEntity = await this.executeQueryTakeFirst(kysely, query, "create");
2728
2943
  if (Object.keys(postCreateRelations).length > 0) {
2729
2944
  const relationPromises = Object.entries(postCreateRelations).map(([field, subPayload]) => {
2730
- return this.processNoneOwnedRelation(kysely, model, field, subPayload, createdEntity);
2945
+ return this.processNoneOwnedRelationForCreate(kysely, model, field, subPayload, createdEntity);
2731
2946
  });
2732
2947
  await Promise.all(relationPromises);
2733
2948
  }
@@ -2739,10 +2954,32 @@ var BaseOperationHandler = class {
2739
2954
  }
2740
2955
  return createdEntity;
2741
2956
  }
2957
+ async processBaseModelCreate(kysely, model, createFields, forModel) {
2958
+ const thisCreateFields = {};
2959
+ const remainingFields = {};
2960
+ Object.entries(createFields).forEach(([field, value]) => {
2961
+ const fieldDef = this.getField(model, field);
2962
+ if (fieldDef) {
2963
+ thisCreateFields[field] = value;
2964
+ } else {
2965
+ remainingFields[field] = value;
2966
+ }
2967
+ });
2968
+ const discriminatorField = getDiscriminatorField(this.schema, model);
2969
+ (0, import_common_helpers8.invariant)(discriminatorField, `Base model "${model}" must have a discriminator field`);
2970
+ thisCreateFields[discriminatorField] = forModel;
2971
+ const baseEntity = await this.create(kysely, model, thisCreateFields, void 0, true);
2972
+ const idValues = extractIdFields(baseEntity, this.schema, model);
2973
+ Object.assign(remainingFields, idValues);
2974
+ return {
2975
+ baseEntity,
2976
+ remainingFields
2977
+ };
2978
+ }
2742
2979
  buildFkAssignments(model, relationField, entity) {
2743
2980
  const parentFkFields = {};
2744
- (0, import_tiny_invariant7.default)(relationField, "parentField must be defined if parentModel is defined");
2745
- (0, import_tiny_invariant7.default)(entity, "parentEntity must be defined if parentModel is defined");
2981
+ (0, import_common_helpers8.invariant)(relationField, "parentField must be defined if parentModel is defined");
2982
+ (0, import_common_helpers8.invariant)(entity, "parentEntity must be defined if parentModel is defined");
2746
2983
  const { keyPairs } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
2747
2984
  for (const pair of keyPairs) {
2748
2985
  if (!(pair.pk in entity)) {
@@ -2769,8 +3006,8 @@ var BaseOperationHandler = class {
2769
3006
  ].sort((a, b) => a.model.localeCompare(b.model));
2770
3007
  const firstIds = getIdFields(this.schema, sortedRecords[0].model);
2771
3008
  const secondIds = getIdFields(this.schema, sortedRecords[1].model);
2772
- (0, import_tiny_invariant7.default)(firstIds.length === 1, "many-to-many relation must have exactly one id field");
2773
- (0, import_tiny_invariant7.default)(secondIds.length === 1, "many-to-many relation must have exactly one id field");
3009
+ (0, import_common_helpers8.invariant)(firstIds.length === 1, "many-to-many relation must have exactly one id field");
3010
+ (0, import_common_helpers8.invariant)(secondIds.length === 1, "many-to-many relation must have exactly one id field");
2774
3011
  if (action === "connect") {
2775
3012
  const result = await kysely.insertInto(joinTable).values({
2776
3013
  A: sortedRecords[0].entity[firstIds[0]],
@@ -2787,14 +3024,14 @@ var BaseOperationHandler = class {
2787
3024
  }
2788
3025
  }
2789
3026
  resetManyToManyRelation(kysely, model, field, parentIds) {
2790
- (0, import_tiny_invariant7.default)(Object.keys(parentIds).length === 1, "parentIds must have exactly one field");
3027
+ (0, import_common_helpers8.invariant)(Object.keys(parentIds).length === 1, "parentIds must have exactly one field");
2791
3028
  const parentId = Object.values(parentIds)[0];
2792
3029
  const m2m = getManyToManyRelation(this.schema, model, field);
2793
- (0, import_tiny_invariant7.default)(m2m, "not a many-to-many relation");
3030
+ (0, import_common_helpers8.invariant)(m2m, "not a many-to-many relation");
2794
3031
  const eb = (0, import_kysely8.expressionBuilder)();
2795
3032
  return kysely.deleteFrom(m2m.joinTable).where(eb(`${m2m.joinTable}.${m2m.parentFkName}`, "=", parentId)).execute();
2796
3033
  }
2797
- async processOwnedRelation(kysely, relationField, payload) {
3034
+ async processOwnedRelationForCreate(kysely, relationField, payload) {
2798
3035
  if (!payload) {
2799
3036
  return;
2800
3037
  }
@@ -2812,7 +3049,7 @@ var BaseOperationHandler = class {
2812
3049
  }
2813
3050
  case "connect": {
2814
3051
  const referencedPkFields = relationField.relation.references;
2815
- (0, import_tiny_invariant7.default)(referencedPkFields, "relation must have fields info");
3052
+ (0, import_common_helpers8.invariant)(referencedPkFields, "relation must have fields info");
2816
3053
  const extractedFks = extractFields(subPayload, referencedPkFields);
2817
3054
  if (Object.keys(extractedFks).length === referencedPkFields.length) {
2818
3055
  result = extractedFks;
@@ -2844,21 +3081,27 @@ var BaseOperationHandler = class {
2844
3081
  }
2845
3082
  return result;
2846
3083
  }
2847
- processNoneOwnedRelation(kysely, contextModel, relationFieldName, payload, parentEntity) {
3084
+ processNoneOwnedRelationForCreate(kysely, contextModel, relationFieldName, payload, parentEntity) {
2848
3085
  const relationFieldDef = this.requireField(contextModel, relationFieldName);
2849
3086
  const relationModel = relationFieldDef.type;
2850
3087
  const tasks = [];
3088
+ const fromRelationContext = {
3089
+ model: contextModel,
3090
+ field: relationFieldName,
3091
+ ids: parentEntity
3092
+ };
2851
3093
  for (const [action, subPayload] of Object.entries(payload)) {
2852
3094
  if (!subPayload) {
2853
3095
  continue;
2854
3096
  }
2855
3097
  switch (action) {
2856
3098
  case "create": {
2857
- tasks.push(...enumerate(subPayload).map((item) => this.create(kysely, relationModel, item, {
2858
- model: contextModel,
2859
- field: relationFieldName,
2860
- ids: parentEntity
2861
- })));
3099
+ tasks.push(...enumerate(subPayload).map((item) => this.create(kysely, relationModel, item, fromRelationContext)));
3100
+ break;
3101
+ }
3102
+ case "createMany": {
3103
+ (0, import_common_helpers8.invariant)(relationFieldDef.array, "relation must be an array for createMany");
3104
+ tasks.push(this.createMany(kysely, relationModel, subPayload, false, fromRelationContext));
2862
3105
  break;
2863
3106
  }
2864
3107
  case "connect": {
@@ -2888,6 +3131,11 @@ var BaseOperationHandler = class {
2888
3131
  return Promise.all(tasks);
2889
3132
  }
2890
3133
  async createMany(kysely, model, input, returnData, fromRelation) {
3134
+ if (!input.data || Array.isArray(input.data) && input.data.length === 0) {
3135
+ return returnData ? [] : {
3136
+ count: 0
3137
+ };
3138
+ }
2891
3139
  const modelDef = this.requireModel(model);
2892
3140
  let relationKeyPairs = [];
2893
3141
  if (fromRelation) {
@@ -2897,12 +3145,12 @@ var BaseOperationHandler = class {
2897
3145
  }
2898
3146
  relationKeyPairs = keyPairs;
2899
3147
  }
2900
- const createData = enumerate(input.data).map((item) => {
3148
+ let createData = enumerate(input.data).map((item) => {
2901
3149
  const newItem = {};
2902
3150
  for (const [name, value] of Object.entries(item)) {
2903
3151
  const fieldDef = this.requireField(model, name);
2904
- (0, import_tiny_invariant7.default)(!fieldDef.relation, "createMany does not support relations");
2905
- newItem[name] = this.dialect.transformPrimitive(value, fieldDef.type);
3152
+ (0, import_common_helpers8.invariant)(!fieldDef.relation, "createMany does not support relations");
3153
+ newItem[name] = this.dialect.transformPrimitive(value, fieldDef.type, !!fieldDef.array);
2906
3154
  }
2907
3155
  if (fromRelation) {
2908
3156
  for (const { fk, pk } of relationKeyPairs) {
@@ -2911,14 +3159,44 @@ var BaseOperationHandler = class {
2911
3159
  }
2912
3160
  return this.fillGeneratedValues(modelDef, newItem);
2913
3161
  });
3162
+ if (!this.dialect.supportInsertWithDefault) {
3163
+ const allPassedFields = createData.reduce((acc, item) => {
3164
+ Object.keys(item).forEach((field) => {
3165
+ if (!acc.includes(field)) {
3166
+ acc.push(field);
3167
+ }
3168
+ });
3169
+ return acc;
3170
+ }, []);
3171
+ for (const item of createData) {
3172
+ if (Object.keys(item).length === allPassedFields.length) {
3173
+ continue;
3174
+ }
3175
+ for (const field of allPassedFields) {
3176
+ if (!(field in item)) {
3177
+ const fieldDef = this.requireField(model, field);
3178
+ if (fieldDef.default !== void 0 && fieldDef.default !== null && typeof fieldDef.default !== "object") {
3179
+ item[field] = this.dialect.transformPrimitive(fieldDef.default, fieldDef.type, !!fieldDef.array);
3180
+ }
3181
+ }
3182
+ }
3183
+ }
3184
+ }
3185
+ if (modelDef.baseModel) {
3186
+ if (input.skipDuplicates) {
3187
+ throw new QueryError('"skipDuplicates" options is not supported for polymorphic models');
3188
+ }
3189
+ const baseCreateResult = await this.processBaseModelCreateMany(kysely, modelDef.baseModel, createData, !!input.skipDuplicates, model);
3190
+ createData = baseCreateResult.remainingFieldRows;
3191
+ }
2914
3192
  const query = kysely.insertInto(model).values(createData).$if(!!input.skipDuplicates, (qb) => qb.onConflict((oc) => oc.doNothing())).modifyEnd(this.makeContextComment({
2915
3193
  model,
2916
3194
  operation: "create"
2917
3195
  }));
2918
3196
  if (!returnData) {
2919
- const result = await query.executeTakeFirstOrThrow();
3197
+ const result = await this.executeQuery(kysely, query, "createMany");
2920
3198
  return {
2921
- count: Number(result.numInsertedOrUpdatedRows)
3199
+ count: Number(result.numAffectedRows)
2922
3200
  };
2923
3201
  } else {
2924
3202
  const idFields = getIdFields(this.schema, model);
@@ -2926,10 +3204,46 @@ var BaseOperationHandler = class {
2926
3204
  return result;
2927
3205
  }
2928
3206
  }
3207
+ async processBaseModelCreateMany(kysely, model, createRows, skipDuplicates, forModel) {
3208
+ const thisCreateRows = [];
3209
+ const remainingFieldRows = [];
3210
+ const discriminatorField = getDiscriminatorField(this.schema, model);
3211
+ (0, import_common_helpers8.invariant)(discriminatorField, `Base model "${model}" must have a discriminator field`);
3212
+ for (const createFields of createRows) {
3213
+ const thisCreateFields = {};
3214
+ const remainingFields = {};
3215
+ Object.entries(createFields).forEach(([field, value]) => {
3216
+ const fieldDef = this.getField(model, field);
3217
+ if (fieldDef) {
3218
+ thisCreateFields[field] = value;
3219
+ } else {
3220
+ remainingFields[field] = value;
3221
+ }
3222
+ });
3223
+ thisCreateFields[discriminatorField] = forModel;
3224
+ thisCreateRows.push(thisCreateFields);
3225
+ remainingFieldRows.push(remainingFields);
3226
+ }
3227
+ const baseEntities = await this.createMany(kysely, model, {
3228
+ data: thisCreateRows,
3229
+ skipDuplicates
3230
+ }, true);
3231
+ for (let i = 0; i < baseEntities.length; i++) {
3232
+ const idValues = extractIdFields(baseEntities[i], this.schema, model);
3233
+ Object.assign(remainingFieldRows[i], idValues);
3234
+ }
3235
+ return {
3236
+ baseEntities,
3237
+ remainingFieldRows
3238
+ };
3239
+ }
2929
3240
  fillGeneratedValues(modelDef, data) {
2930
3241
  const fields = modelDef.fields;
2931
3242
  const values = clone(data);
2932
- for (const field in fields) {
3243
+ for (const [field, fieldDef] of Object.entries(fields)) {
3244
+ if (fieldDef.originModel) {
3245
+ continue;
3246
+ }
2933
3247
  if (!(field in data)) {
2934
3248
  if (typeof fields[field]?.default === "object" && "kind" in fields[field].default) {
2935
3249
  const generated = this.evalGenerator(fields[field].default);
@@ -2937,7 +3251,7 @@ var BaseOperationHandler = class {
2937
3251
  values[field] = generated;
2938
3252
  }
2939
3253
  } else if (fields[field]?.updatedAt) {
2940
- values[field] = this.dialect.transformPrimitive(/* @__PURE__ */ new Date(), "DateTime");
3254
+ values[field] = this.dialect.transformPrimitive(/* @__PURE__ */ new Date(), "DateTime", false);
2941
3255
  }
2942
3256
  }
2943
3257
  }
@@ -2945,7 +3259,7 @@ var BaseOperationHandler = class {
2945
3259
  }
2946
3260
  evalGenerator(defaultValue) {
2947
3261
  if (ExpressionUtils.isCall(defaultValue)) {
2948
- return (0, import_ts_pattern8.match)(defaultValue.function).with("cuid", () => (0, import_cuid2.createId)()).with("uuid", () => defaultValue.args?.[0] && ExpressionUtils.isLiteral(defaultValue.args?.[0]) && defaultValue.args[0].value === 7 ? uuid.v7() : uuid.v4()).with("nanoid", () => defaultValue.args?.[0] && ExpressionUtils.isLiteral(defaultValue.args[0]) && typeof defaultValue.args[0].value === "number" ? (0, import_nanoid.nanoid)(defaultValue.args[0].value) : (0, import_nanoid.nanoid)()).with("ulid", () => (0, import_ulid.ulid)()).otherwise(() => void 0);
3262
+ return (0, import_ts_pattern9.match)(defaultValue.function).with("cuid", () => (0, import_cuid2.createId)()).with("uuid", () => defaultValue.args?.[0] && ExpressionUtils.isLiteral(defaultValue.args?.[0]) && defaultValue.args[0].value === 7 ? uuid.v7() : uuid.v4()).with("nanoid", () => defaultValue.args?.[0] && ExpressionUtils.isLiteral(defaultValue.args[0]) && typeof defaultValue.args[0].value === "number" ? (0, import_nanoid.nanoid)(defaultValue.args[0].value) : (0, import_nanoid.nanoid)()).with("ulid", () => (0, import_ulid.ulid)()).otherwise(() => void 0);
2949
3263
  } else if (ExpressionUtils.isMember(defaultValue) && ExpressionUtils.isCall(defaultValue.receiver) && defaultValue.receiver.function === "auth") {
2950
3264
  let val = this.client.$auth;
2951
3265
  for (const member of defaultValue.members) {
@@ -2980,7 +3294,7 @@ var BaseOperationHandler = class {
2980
3294
  }
2981
3295
  } else {
2982
3296
  const fromRelationFieldDef = this.requireField(fromRelation.model, fromRelation.field);
2983
- (0, import_tiny_invariant7.default)(fromRelationFieldDef.relation?.opposite);
3297
+ (0, import_common_helpers8.invariant)(fromRelationFieldDef.relation?.opposite);
2984
3298
  parentWhere[fromRelationFieldDef.relation.opposite] = {
2985
3299
  some: fromRelation.ids
2986
3300
  };
@@ -3002,32 +3316,37 @@ var BaseOperationHandler = class {
3002
3316
  if (finalData === data) {
3003
3317
  finalData = clone(data);
3004
3318
  }
3005
- finalData[fieldName] = this.dialect.transformPrimitive(/* @__PURE__ */ new Date(), "DateTime");
3319
+ finalData[fieldName] = this.dialect.transformPrimitive(/* @__PURE__ */ new Date(), "DateTime", false);
3006
3320
  }
3007
3321
  }
3008
3322
  if (Object.keys(finalData).length === 0) {
3009
- const r = await this.readUnique(kysely, model, {
3010
- where: combinedWhere
3323
+ return combinedWhere;
3324
+ }
3325
+ let needIdRead = false;
3326
+ if (modelDef.baseModel && !this.isIdFilter(model, combinedWhere)) {
3327
+ needIdRead = true;
3328
+ }
3329
+ if (needIdRead) {
3330
+ const readResult = await this.readUnique(kysely, model, {
3331
+ where: combinedWhere,
3332
+ select: this.makeIdSelect(model)
3011
3333
  });
3012
- if (!r && throwIfNotFound) {
3334
+ if (!readResult && throwIfNotFound) {
3013
3335
  throw new NotFoundError(model);
3014
3336
  }
3015
- return r;
3337
+ combinedWhere = readResult;
3338
+ }
3339
+ if (modelDef.baseModel) {
3340
+ const baseUpdateResult = await this.processBaseModelUpdate(kysely, modelDef.baseModel, combinedWhere, finalData, throwIfNotFound);
3341
+ finalData = baseUpdateResult.remainingFields;
3342
+ combinedWhere = baseUpdateResult.baseEntity;
3016
3343
  }
3017
3344
  const updateFields = {};
3018
3345
  let thisEntity = void 0;
3019
3346
  for (const field in finalData) {
3020
3347
  const fieldDef = this.requireField(model, field);
3021
3348
  if (isScalarField(this.schema, model, field) || isForeignKeyField(this.schema, model, field)) {
3022
- if (this.isNumericField(fieldDef) && typeof finalData[field] === "object" && finalData[field]) {
3023
- updateFields[field] = this.transformIncrementalUpdate(model, field, fieldDef, finalData[field]);
3024
- continue;
3025
- }
3026
- if (fieldDef.array && typeof finalData[field] === "object" && !Array.isArray(finalData[field]) && finalData[field]) {
3027
- updateFields[field] = this.transformScalarListUpdate(model, field, fieldDef, finalData[field]);
3028
- continue;
3029
- }
3030
- updateFields[field] = this.dialect.transformPrimitive(finalData[field], fieldDef.type);
3349
+ updateFields[field] = this.processScalarFieldUpdateData(model, field, finalData);
3031
3350
  } else {
3032
3351
  if (!allowRelationUpdate) {
3033
3352
  throw new QueryError(`Relation update not allowed for field "${field}"`);
@@ -3049,16 +3368,14 @@ var BaseOperationHandler = class {
3049
3368
  }
3050
3369
  }
3051
3370
  if (Object.keys(updateFields).length === 0) {
3052
- return thisEntity ?? await this.readUnique(kysely, model, {
3053
- where: combinedWhere
3054
- });
3371
+ return combinedWhere;
3055
3372
  } else {
3056
3373
  const idFields = getIdFields(this.schema, model);
3057
3374
  const query = kysely.updateTable(model).where((eb) => this.dialect.buildFilter(eb, model, model, combinedWhere)).set(updateFields).returning(idFields).modifyEnd(this.makeContextComment({
3058
3375
  model,
3059
3376
  operation: "update"
3060
3377
  }));
3061
- const updatedEntity = await query.executeTakeFirst();
3378
+ const updatedEntity = await this.executeQueryTakeFirst(kysely, query, "update");
3062
3379
  if (!updatedEntity) {
3063
3380
  if (throwIfNotFound) {
3064
3381
  throw new NotFoundError(model);
@@ -3069,23 +3386,72 @@ var BaseOperationHandler = class {
3069
3386
  return updatedEntity;
3070
3387
  }
3071
3388
  }
3389
+ processScalarFieldUpdateData(model, field, data) {
3390
+ const fieldDef = this.requireField(model, field);
3391
+ if (this.isNumericIncrementalUpdate(fieldDef, data[field])) {
3392
+ return this.transformIncrementalUpdate(model, field, fieldDef, data[field]);
3393
+ }
3394
+ if (fieldDef.array && typeof data[field] === "object" && !Array.isArray(data[field]) && data[field]) {
3395
+ return this.transformScalarListUpdate(model, field, fieldDef, data[field]);
3396
+ }
3397
+ return this.dialect.transformPrimitive(data[field], fieldDef.type, !!fieldDef.array);
3398
+ }
3399
+ isNumericIncrementalUpdate(fieldDef, value) {
3400
+ if (!this.isNumericField(fieldDef)) {
3401
+ return false;
3402
+ }
3403
+ if (typeof value !== "object" || !value) {
3404
+ return false;
3405
+ }
3406
+ return [
3407
+ "increment",
3408
+ "decrement",
3409
+ "multiply",
3410
+ "divide",
3411
+ "set"
3412
+ ].some((key) => key in value);
3413
+ }
3414
+ isIdFilter(model, filter) {
3415
+ if (!filter || typeof filter !== "object") {
3416
+ return false;
3417
+ }
3418
+ const idFields = getIdFields(this.schema, model);
3419
+ return idFields.length === Object.keys(filter).length && idFields.every((field) => field in filter);
3420
+ }
3421
+ async processBaseModelUpdate(kysely, model, where, updateFields, throwIfNotFound) {
3422
+ const thisUpdateFields = {};
3423
+ const remainingFields = {};
3424
+ Object.entries(updateFields).forEach(([field, value]) => {
3425
+ const fieldDef = this.getField(model, field);
3426
+ if (fieldDef) {
3427
+ thisUpdateFields[field] = value;
3428
+ } else {
3429
+ remainingFields[field] = value;
3430
+ }
3431
+ });
3432
+ const baseEntity = await this.update(kysely, model, where, thisUpdateFields, void 0, void 0, throwIfNotFound);
3433
+ return {
3434
+ baseEntity,
3435
+ remainingFields
3436
+ };
3437
+ }
3072
3438
  transformIncrementalUpdate(model, field, fieldDef, payload) {
3073
- (0, import_tiny_invariant7.default)(Object.keys(payload).length === 1, 'Only one of "set", "increment", "decrement", "multiply", or "divide" can be provided');
3439
+ (0, import_common_helpers8.invariant)(Object.keys(payload).length === 1, 'Only one of "set", "increment", "decrement", "multiply", or "divide" can be provided');
3074
3440
  const key = Object.keys(payload)[0];
3075
- const value = this.dialect.transformPrimitive(payload[key], fieldDef.type);
3441
+ const value = this.dialect.transformPrimitive(payload[key], fieldDef.type, false);
3076
3442
  const eb = (0, import_kysely8.expressionBuilder)();
3077
- const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb);
3078
- return (0, import_ts_pattern8.match)(key).with("set", () => value).with("increment", () => eb(fieldRef, "+", value)).with("decrement", () => eb(fieldRef, "-", value)).with("multiply", () => eb(fieldRef, "*", value)).with("divide", () => eb(fieldRef, "/", value)).otherwise(() => {
3443
+ const fieldRef = this.dialect.fieldRef(model, field, eb);
3444
+ return (0, import_ts_pattern9.match)(key).with("set", () => value).with("increment", () => eb(fieldRef, "+", value)).with("decrement", () => eb(fieldRef, "-", value)).with("multiply", () => eb(fieldRef, "*", value)).with("divide", () => eb(fieldRef, "/", value)).otherwise(() => {
3079
3445
  throw new InternalError(`Invalid incremental update operation: ${key}`);
3080
3446
  });
3081
3447
  }
3082
3448
  transformScalarListUpdate(model, field, fieldDef, payload) {
3083
- (0, import_tiny_invariant7.default)(Object.keys(payload).length === 1, 'Only one of "set", "push" can be provided');
3449
+ (0, import_common_helpers8.invariant)(Object.keys(payload).length === 1, 'Only one of "set", "push" can be provided');
3084
3450
  const key = Object.keys(payload)[0];
3085
- const value = this.dialect.transformPrimitive(payload[key], fieldDef.type);
3451
+ const value = this.dialect.transformPrimitive(payload[key], fieldDef.type, true);
3086
3452
  const eb = (0, import_kysely8.expressionBuilder)();
3087
- const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb);
3088
- return (0, import_ts_pattern8.match)(key).with("set", () => value).with("push", () => {
3453
+ const fieldRef = this.dialect.fieldRef(model, field, eb);
3454
+ return (0, import_ts_pattern9.match)(key).with("set", () => value).with("push", () => {
3089
3455
  return eb(fieldRef, "||", eb.val(ensureArray(value)));
3090
3456
  }).otherwise(() => {
3091
3457
  throw new InternalError(`Invalid array update operation: ${key}`);
@@ -3097,7 +3463,7 @@ var BaseOperationHandler = class {
3097
3463
  makeContextComment(context) {
3098
3464
  return import_kysely8.sql.raw(`${CONTEXT_COMMENT_PREFIX}${JSON.stringify(context)}`);
3099
3465
  }
3100
- async updateMany(kysely, model, where, data, limit, returnData) {
3466
+ async updateMany(kysely, model, where, data, limit, returnData, filterModel) {
3101
3467
  if (typeof data !== "object") {
3102
3468
  throw new InternalError("data must be an object");
3103
3469
  }
@@ -3106,49 +3472,79 @@ var BaseOperationHandler = class {
3106
3472
  count: 0
3107
3473
  };
3108
3474
  }
3109
- const updateFields = {};
3475
+ const modelDef = this.requireModel(model);
3476
+ if (modelDef.baseModel && limit !== void 0) {
3477
+ throw new QueryError("Updating with a limit is not supported for polymorphic models");
3478
+ }
3479
+ filterModel ??= model;
3480
+ let updateFields = {};
3110
3481
  for (const field in data) {
3111
- const fieldDef = this.requireField(model, field);
3112
3482
  if (isRelationField(this.schema, model, field)) {
3113
3483
  continue;
3114
3484
  }
3115
- updateFields[field] = this.dialect.transformPrimitive(data[field], fieldDef.type);
3485
+ updateFields[field] = this.processScalarFieldUpdateData(model, field, data);
3486
+ }
3487
+ let shouldFallbackToIdFilter = false;
3488
+ if (limit !== void 0 && !this.dialect.supportsUpdateWithLimit) {
3489
+ shouldFallbackToIdFilter = true;
3490
+ }
3491
+ if (modelDef.isDelegate || modelDef.baseModel) {
3492
+ shouldFallbackToIdFilter = true;
3493
+ }
3494
+ let resultFromBaseModel = void 0;
3495
+ if (modelDef.baseModel) {
3496
+ const baseResult = await this.processBaseModelUpdateMany(kysely, modelDef.baseModel, where, updateFields, filterModel);
3497
+ updateFields = baseResult.remainingFields;
3498
+ resultFromBaseModel = baseResult.baseResult;
3499
+ }
3500
+ if (Object.keys(updateFields).length === 0) {
3501
+ return resultFromBaseModel ?? (returnData ? [] : {
3502
+ count: 0
3503
+ });
3116
3504
  }
3117
3505
  let query = kysely.updateTable(model).set(updateFields);
3118
- if (limit === void 0) {
3119
- query = query.where((eb) => this.dialect.buildFilter(eb, model, model, where));
3506
+ if (!shouldFallbackToIdFilter) {
3507
+ query = query.where((eb) => this.dialect.buildFilter(eb, model, model, where)).$if(limit !== void 0, (qb) => qb.limit(limit));
3120
3508
  } else {
3121
- if (this.dialect.supportsUpdateWithLimit) {
3122
- query = query.where((eb) => this.dialect.buildFilter(eb, model, model, where)).limit(limit);
3123
- } else {
3124
- query = query.where((eb) => eb(eb.refTuple(
3125
- ...this.buildIdFieldRefs(kysely, model)
3126
- ), "in", kysely.selectFrom(model).where((eb2) => this.dialect.buildFilter(eb2, model, model, where)).select(this.buildIdFieldRefs(kysely, model)).limit(limit)));
3127
- }
3509
+ query = query.where((eb) => eb(eb.refTuple(
3510
+ ...this.buildIdFieldRefs(kysely, model)
3511
+ ), "in", this.dialect.buildSelectModel(eb, filterModel).where(this.dialect.buildFilter(eb, filterModel, filterModel, where)).select(this.buildIdFieldRefs(kysely, filterModel)).$if(limit !== void 0, (qb) => qb.limit(limit))));
3128
3512
  }
3129
3513
  query = query.modifyEnd(this.makeContextComment({
3130
3514
  model,
3131
3515
  operation: "update"
3132
3516
  }));
3133
- try {
3134
- if (!returnData) {
3135
- const result = await query.executeTakeFirstOrThrow();
3136
- return {
3137
- count: Number(result.numUpdatedRows)
3138
- };
3517
+ if (!returnData) {
3518
+ const result = await this.executeQuery(kysely, query, "update");
3519
+ return {
3520
+ count: Number(result.numAffectedRows)
3521
+ };
3522
+ } else {
3523
+ const idFields = getIdFields(this.schema, model);
3524
+ const result = await query.returning(idFields).execute();
3525
+ return result;
3526
+ }
3527
+ }
3528
+ async processBaseModelUpdateMany(kysely, model, where, updateFields, filterModel) {
3529
+ const thisUpdateFields = {};
3530
+ const remainingFields = {};
3531
+ Object.entries(updateFields).forEach(([field, value]) => {
3532
+ const fieldDef = this.getField(model, field);
3533
+ if (fieldDef) {
3534
+ thisUpdateFields[field] = value;
3139
3535
  } else {
3140
- const idFields = getIdFields(this.schema, model);
3141
- const result = await query.returning(idFields).execute();
3142
- return result;
3536
+ remainingFields[field] = value;
3143
3537
  }
3144
- } catch (err) {
3145
- const { sql: sql10, parameters } = query.compile();
3146
- throw new QueryError(`Error during updateMany: ${err}, sql: ${sql10}, parameters: ${parameters}`);
3147
- }
3538
+ });
3539
+ const baseResult = await this.updateMany(kysely, model, where, thisUpdateFields, void 0, false, filterModel);
3540
+ return {
3541
+ baseResult,
3542
+ remainingFields
3543
+ };
3148
3544
  }
3149
3545
  buildIdFieldRefs(kysely, model) {
3150
3546
  const idFields = getIdFields(this.schema, model);
3151
- return idFields.map((f) => kysely.dynamic.ref(f));
3547
+ return idFields.map((f) => kysely.dynamic.ref(`${model}.${f}`));
3152
3548
  }
3153
3549
  async processRelationUpdates(kysely, model, field, fieldDef, parentIds, args, throwIfNotFound) {
3154
3550
  const tasks = [];
@@ -3161,12 +3557,12 @@ var BaseOperationHandler = class {
3161
3557
  for (const [key, value] of Object.entries(args)) {
3162
3558
  switch (key) {
3163
3559
  case "create": {
3164
- (0, import_tiny_invariant7.default)(!Array.isArray(value) || fieldDef.array, "relation must be an array if create is an array");
3560
+ (0, import_common_helpers8.invariant)(!Array.isArray(value) || fieldDef.array, "relation must be an array if create is an array");
3165
3561
  tasks.push(...enumerate(value).map((item) => this.create(kysely, fieldModel, item, fromRelationContext)));
3166
3562
  break;
3167
3563
  }
3168
3564
  case "createMany": {
3169
- (0, import_tiny_invariant7.default)(fieldDef.array, "relation must be an array for createMany");
3565
+ (0, import_common_helpers8.invariant)(fieldDef.array, "relation must be an array for createMany");
3170
3566
  tasks.push(this.createMany(kysely, fieldModel, value, false, fromRelationContext));
3171
3567
  break;
3172
3568
  }
@@ -3183,7 +3579,7 @@ var BaseOperationHandler = class {
3183
3579
  break;
3184
3580
  }
3185
3581
  case "set": {
3186
- (0, import_tiny_invariant7.default)(fieldDef.array, "relation must be an array");
3582
+ (0, import_common_helpers8.invariant)(fieldDef.array, "relation must be an array");
3187
3583
  tasks.push(this.setRelation(kysely, fieldModel, value, fromRelationContext));
3188
3584
  break;
3189
3585
  }
@@ -3252,7 +3648,7 @@ var BaseOperationHandler = class {
3252
3648
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
3253
3649
  let updateResult;
3254
3650
  if (ownedByModel) {
3255
- (0, import_tiny_invariant7.default)(_data.length === 1, "only one entity can be connected");
3651
+ (0, import_common_helpers8.invariant)(_data.length === 1, "only one entity can be connected");
3256
3652
  const target = await this.readUnique(kysely, model, {
3257
3653
  where: _data[0]
3258
3654
  });
@@ -3266,7 +3662,7 @@ var BaseOperationHandler = class {
3266
3662
  model: fromRelation.model,
3267
3663
  operation: "update"
3268
3664
  }));
3269
- updateResult = await query.executeTakeFirstOrThrow();
3665
+ updateResult = await this.executeQuery(kysely, query, "connect");
3270
3666
  } else {
3271
3667
  const relationFieldDef = this.requireField(fromRelation.model, fromRelation.field);
3272
3668
  if (!relationFieldDef.array) {
@@ -3277,7 +3673,7 @@ var BaseOperationHandler = class {
3277
3673
  model: fromRelation.model,
3278
3674
  operation: "update"
3279
3675
  }));
3280
- await query2.execute();
3676
+ await this.executeQuery(kysely, query2, "disconnect");
3281
3677
  }
3282
3678
  const query = kysely.updateTable(model).where((eb) => eb.or(_data.map((d) => eb.and(d)))).set(keyPairs.reduce((acc, { fk, pk }) => ({
3283
3679
  ...acc,
@@ -3286,9 +3682,9 @@ var BaseOperationHandler = class {
3286
3682
  model,
3287
3683
  operation: "update"
3288
3684
  }));
3289
- updateResult = await query.executeTakeFirstOrThrow();
3685
+ updateResult = await this.executeQuery(kysely, query, "connect");
3290
3686
  }
3291
- if (_data.length > updateResult.numUpdatedRows) {
3687
+ if (_data.length > updateResult.numAffectedRows) {
3292
3688
  throw new NotFoundError(model);
3293
3689
  }
3294
3690
  }
@@ -3342,7 +3738,7 @@ var BaseOperationHandler = class {
3342
3738
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
3343
3739
  const eb = (0, import_kysely8.expressionBuilder)();
3344
3740
  if (ownedByModel) {
3345
- (0, import_tiny_invariant7.default)(disconnectConditions.length === 1, "only one entity can be disconnected");
3741
+ (0, import_common_helpers8.invariant)(disconnectConditions.length === 1, "only one entity can be disconnected");
3346
3742
  const condition = disconnectConditions[0];
3347
3743
  const query = kysely.updateTable(fromRelation.model).where(eb.and(fromRelation.ids)).$if(condition !== true, (qb) => qb.where(eb(
3348
3744
  // @ts-ignore
@@ -3356,7 +3752,7 @@ var BaseOperationHandler = class {
3356
3752
  model: fromRelation.model,
3357
3753
  operation: "update"
3358
3754
  }));
3359
- await query.executeTakeFirstOrThrow();
3755
+ await this.executeQuery(kysely, query, "disconnect");
3360
3756
  } else {
3361
3757
  const query = kysely.updateTable(model).where(eb.and([
3362
3758
  // fk filter
@@ -3373,7 +3769,7 @@ var BaseOperationHandler = class {
3373
3769
  model,
3374
3770
  operation: "update"
3375
3771
  }));
3376
- await query.executeTakeFirstOrThrow();
3772
+ await this.executeQuery(kysely, query, "disconnect");
3377
3773
  }
3378
3774
  }
3379
3775
  }
@@ -3411,7 +3807,7 @@ var BaseOperationHandler = class {
3411
3807
  model,
3412
3808
  operation: "update"
3413
3809
  }));
3414
- await query.execute();
3810
+ await this.executeQuery(kysely, query, "disconnect");
3415
3811
  if (_data.length > 0) {
3416
3812
  const query2 = kysely.updateTable(model).where((eb) => eb.or(_data.map((d) => eb.and(d)))).set(keyPairs.reduce((acc, { fk, pk }) => ({
3417
3813
  ...acc,
@@ -3420,8 +3816,8 @@ var BaseOperationHandler = class {
3420
3816
  model,
3421
3817
  operation: "update"
3422
3818
  }));
3423
- const r = await query2.executeTakeFirstOrThrow();
3424
- if (_data.length > r.numUpdatedRows) {
3819
+ const r = await this.executeQuery(kysely, query2, "connect");
3820
+ if (_data.length > r.numAffectedRows) {
3425
3821
  throw new NotFoundError(model);
3426
3822
  }
3427
3823
  }
@@ -3450,7 +3846,7 @@ var BaseOperationHandler = class {
3450
3846
  const m2m = getManyToManyRelation(this.schema, fromRelation.model, fromRelation.field);
3451
3847
  if (m2m) {
3452
3848
  const fieldDef = this.requireField(fromRelation.model, fromRelation.field);
3453
- (0, import_tiny_invariant7.default)(fieldDef.relation?.opposite);
3849
+ (0, import_common_helpers8.invariant)(fieldDef.relation?.opposite);
3454
3850
  deleteResult = await this.delete(kysely, model, {
3455
3851
  AND: [
3456
3852
  {
@@ -3462,7 +3858,7 @@ var BaseOperationHandler = class {
3462
3858
  OR: deleteConditions
3463
3859
  }
3464
3860
  ]
3465
- }, void 0, false);
3861
+ });
3466
3862
  } else {
3467
3863
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
3468
3864
  if (ownedByModel) {
@@ -3473,7 +3869,7 @@ var BaseOperationHandler = class {
3473
3869
  throw new NotFoundError(model);
3474
3870
  }
3475
3871
  const fieldDef = this.requireField(fromRelation.model, fromRelation.field);
3476
- (0, import_tiny_invariant7.default)(fieldDef.relation?.opposite);
3872
+ (0, import_common_helpers8.invariant)(fieldDef.relation?.opposite);
3477
3873
  deleteResult = await this.delete(kysely, model, {
3478
3874
  AND: [
3479
3875
  // filter for parent
@@ -3485,7 +3881,7 @@ var BaseOperationHandler = class {
3485
3881
  OR: deleteConditions
3486
3882
  }
3487
3883
  ]
3488
- }, void 0, false);
3884
+ });
3489
3885
  } else {
3490
3886
  deleteResult = await this.delete(kysely, model, {
3491
3887
  AND: [
@@ -3497,7 +3893,7 @@ var BaseOperationHandler = class {
3497
3893
  OR: deleteConditions
3498
3894
  }
3499
3895
  ]
3500
- }, void 0, false);
3896
+ });
3501
3897
  }
3502
3898
  }
3503
3899
  if (throwForNotFound && expectedDeleteCount > deleteResult.count) {
@@ -3508,33 +3904,59 @@ var BaseOperationHandler = class {
3508
3904
  return enumerate(data).map((item) => flattenCompoundUniqueFilters(this.schema, model, item));
3509
3905
  }
3510
3906
  // #endregion
3511
- async delete(kysely, model, where, limit, returnData) {
3907
+ async delete(kysely, model, where, limit, filterModel) {
3908
+ filterModel ??= model;
3909
+ const modelDef = this.requireModel(model);
3910
+ if (modelDef.baseModel) {
3911
+ if (limit !== void 0) {
3912
+ throw new QueryError("Deleting with a limit is not supported for polymorphic models");
3913
+ }
3914
+ return this.processBaseModelDelete(kysely, modelDef.baseModel, where, limit, filterModel);
3915
+ }
3512
3916
  let query = kysely.deleteFrom(model);
3513
- if (limit === void 0) {
3917
+ let needIdFilter = false;
3918
+ if (limit !== void 0 && !this.dialect.supportsDeleteWithLimit) {
3919
+ needIdFilter = true;
3920
+ }
3921
+ if (modelDef.isDelegate || modelDef.baseModel) {
3922
+ needIdFilter = true;
3923
+ }
3924
+ if (!needIdFilter) {
3514
3925
  query = query.where((eb) => this.dialect.buildFilter(eb, model, model, where));
3515
3926
  } else {
3516
- if (this.dialect.supportsDeleteWithLimit) {
3517
- query = query.where((eb) => this.dialect.buildFilter(eb, model, model, where)).limit(limit);
3518
- } else {
3519
- query = query.where((eb) => eb(eb.refTuple(
3520
- ...this.buildIdFieldRefs(kysely, model)
3521
- ), "in", kysely.selectFrom(model).where((eb2) => this.dialect.buildFilter(eb2, model, model, where)).select(this.buildIdFieldRefs(kysely, model)).limit(limit)));
3522
- }
3927
+ query = query.where((eb) => eb(eb.refTuple(
3928
+ ...this.buildIdFieldRefs(kysely, model)
3929
+ ), "in", this.dialect.buildSelectModel(eb, filterModel).where((eb2) => this.dialect.buildFilter(eb2, filterModel, filterModel, where)).select(this.buildIdFieldRefs(kysely, filterModel)).$if(limit !== void 0, (qb) => qb.limit(limit))));
3523
3930
  }
3931
+ await this.processDelegateRelationDelete(kysely, modelDef, where, limit);
3524
3932
  query = query.modifyEnd(this.makeContextComment({
3525
3933
  model,
3526
3934
  operation: "delete"
3527
3935
  }));
3528
- if (returnData) {
3529
- const result = await query.execute();
3530
- return result;
3531
- } else {
3532
- const result = await query.executeTakeFirstOrThrow();
3533
- return {
3534
- count: Number(result.numDeletedRows)
3535
- };
3936
+ const result = await this.executeQuery(kysely, query, "delete");
3937
+ return {
3938
+ count: Number(result.numAffectedRows)
3939
+ };
3940
+ }
3941
+ async processDelegateRelationDelete(kysely, modelDef, where, limit) {
3942
+ for (const fieldDef of Object.values(modelDef.fields)) {
3943
+ if (fieldDef.relation && fieldDef.relation.opposite) {
3944
+ const oppositeModelDef = this.requireModel(fieldDef.type);
3945
+ const oppositeRelation = this.requireField(fieldDef.type, fieldDef.relation.opposite);
3946
+ if (oppositeModelDef.baseModel && oppositeRelation.relation?.onDelete === "Cascade") {
3947
+ if (limit !== void 0) {
3948
+ throw new QueryError("Deleting with a limit is not supported for polymorphic models");
3949
+ }
3950
+ await this.delete(kysely, fieldDef.type, {
3951
+ [fieldDef.relation.opposite]: where
3952
+ }, void 0);
3953
+ }
3954
+ }
3536
3955
  }
3537
3956
  }
3957
+ async processBaseModelDelete(kysely, model, where, limit, filterModel) {
3958
+ return this.delete(kysely, model, where, limit, filterModel);
3959
+ }
3538
3960
  makeIdSelect(model) {
3539
3961
  const modelDef = this.requireModel(model);
3540
3962
  return modelDef.idFields.reduce((acc, f) => {
@@ -3543,7 +3965,7 @@ var BaseOperationHandler = class {
3543
3965
  }, {});
3544
3966
  }
3545
3967
  trimResult(data, args) {
3546
- if (!args.select) {
3968
+ if (!("select" in args) || !args.select) {
3547
3969
  return data;
3548
3970
  }
3549
3971
  return Object.keys(args.select).reduce((acc, field) => {
@@ -3553,9 +3975,9 @@ var BaseOperationHandler = class {
3553
3975
  }
3554
3976
  needReturnRelations(model, args) {
3555
3977
  let returnRelation = false;
3556
- if (args.include) {
3978
+ if ("include" in args && args.include) {
3557
3979
  returnRelation = Object.keys(args.include).length > 0;
3558
- } else if (args.select) {
3980
+ } else if ("select" in args && args.select) {
3559
3981
  returnRelation = Object.entries(args.select).some(([K, v]) => {
3560
3982
  const fieldDef = this.requireField(model, K);
3561
3983
  return fieldDef.relation && v;
@@ -3563,11 +3985,13 @@ var BaseOperationHandler = class {
3563
3985
  }
3564
3986
  return returnRelation;
3565
3987
  }
3566
- async safeTransaction(callback) {
3988
+ async safeTransaction(callback, isolationLevel) {
3567
3989
  if (this.kysely.isTransaction) {
3568
3990
  return callback(this.kysely);
3569
3991
  } else {
3570
- return this.kysely.transaction().setIsolationLevel("repeatable read").execute(callback);
3992
+ let txBuilder = this.kysely.transaction();
3993
+ txBuilder = txBuilder.setIsolationLevel(isolationLevel ?? "repeatable read");
3994
+ return txBuilder.execute(callback);
3571
3995
  }
3572
3996
  }
3573
3997
  // Given a unique filter of a model, return the entity ids by trying to
@@ -3586,6 +4010,47 @@ var BaseOperationHandler = class {
3586
4010
  where: uniqueFilter
3587
4011
  });
3588
4012
  }
4013
+ /**
4014
+ * Normalize input args to strip `undefined` fields
4015
+ */
4016
+ normalizeArgs(args) {
4017
+ if (!args) {
4018
+ return;
4019
+ }
4020
+ const newArgs = clone(args);
4021
+ this.doNormalizeArgs(newArgs);
4022
+ return newArgs;
4023
+ }
4024
+ doNormalizeArgs(args) {
4025
+ if (args && typeof args === "object") {
4026
+ for (const [key, value] of Object.entries(args)) {
4027
+ if (value === void 0) {
4028
+ delete args[key];
4029
+ } else if (value && (0, import_common_helpers8.isPlainObject)(value)) {
4030
+ this.doNormalizeArgs(value);
4031
+ }
4032
+ }
4033
+ }
4034
+ }
4035
+ makeQueryId(operation) {
4036
+ return {
4037
+ queryId: `${operation}-${(0, import_cuid2.createId)()}`
4038
+ };
4039
+ }
4040
+ executeQuery(kysely, query, operation) {
4041
+ return kysely.executeQuery(query.compile(), this.makeQueryId(operation));
4042
+ }
4043
+ async executeQueryTakeFirst(kysely, query, operation) {
4044
+ const result = await kysely.executeQuery(query.compile(), this.makeQueryId(operation));
4045
+ return result.rows[0];
4046
+ }
4047
+ async executeQueryTakeFirstOrThrow(kysely, query, operation) {
4048
+ const result = await kysely.executeQuery(query.compile(), this.makeQueryId(operation));
4049
+ if (result.rows.length === 0) {
4050
+ throw new QueryError("No rows found");
4051
+ }
4052
+ return result.rows[0];
4053
+ }
3589
4054
  };
3590
4055
 
3591
4056
  // src/client/crud/operations/aggregate.ts
@@ -3594,21 +4059,37 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
3594
4059
  __name(this, "AggregateOperationHandler");
3595
4060
  }
3596
4061
  async handle(_operation, args) {
3597
- const validatedArgs = this.inputValidator.validateAggregateArgs(this.model, args);
4062
+ const normalizedArgs = this.normalizeArgs(args);
4063
+ const parsedArgs = this.inputValidator.validateAggregateArgs(this.model, normalizedArgs);
3598
4064
  let query = this.kysely.selectFrom((eb) => {
3599
- let subQuery = eb.selectFrom(this.model).selectAll(this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, validatedArgs?.where));
3600
- const skip = validatedArgs?.skip;
3601
- let take = validatedArgs?.take;
4065
+ let subQuery = this.dialect.buildSelectModel(eb, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
4066
+ const selectedFields = [];
4067
+ for (const [key, value] of Object.entries(parsedArgs)) {
4068
+ if (key.startsWith("_") && value && typeof value === "object") {
4069
+ Object.entries(value).filter(([field]) => field !== "_all").filter(([, val]) => val === true).forEach(([field]) => {
4070
+ if (!selectedFields.includes(field)) selectedFields.push(field);
4071
+ });
4072
+ }
4073
+ }
4074
+ if (selectedFields.length > 0) {
4075
+ for (const field of selectedFields) {
4076
+ subQuery = this.dialect.buildSelectField(subQuery, this.model, this.model, field);
4077
+ }
4078
+ } else {
4079
+ subQuery = subQuery.select(() => eb.lit(1).as("_all"));
4080
+ }
4081
+ const skip = parsedArgs?.skip;
4082
+ let take = parsedArgs?.take;
3602
4083
  let negateOrderBy = false;
3603
4084
  if (take !== void 0 && take < 0) {
3604
4085
  negateOrderBy = true;
3605
4086
  take = -take;
3606
4087
  }
3607
4088
  subQuery = this.dialect.buildSkipTake(subQuery, skip, take);
3608
- subQuery = this.dialect.buildOrderBy(subQuery, this.model, this.model, validatedArgs.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
4089
+ subQuery = this.dialect.buildOrderBy(subQuery, this.model, this.model, parsedArgs.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
3609
4090
  return subQuery.as("$sub");
3610
4091
  });
3611
- for (const [key, value] of Object.entries(validatedArgs)) {
4092
+ for (const [key, value] of Object.entries(parsedArgs)) {
3612
4093
  switch (key) {
3613
4094
  case "_count": {
3614
4095
  if (value === true) {
@@ -3633,7 +4114,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
3633
4114
  Object.entries(value).forEach(([field, val]) => {
3634
4115
  if (val === true) {
3635
4116
  query = query.select((eb) => {
3636
- const fn = (0, import_ts_pattern9.match)(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
4117
+ const fn = (0, import_ts_pattern10.match)(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
3637
4118
  return fn(import_kysely9.sql.ref(`$sub.${field}`)).as(`${key}.${field}`);
3638
4119
  });
3639
4120
  }
@@ -3642,9 +4123,9 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
3642
4123
  }
3643
4124
  }
3644
4125
  }
3645
- const result = await query.executeTakeFirstOrThrow();
4126
+ const result = await this.executeQuery(this.kysely, query, "aggregate");
3646
4127
  const ret = {};
3647
- for (const [key, value] of Object.entries(result)) {
4128
+ for (const [key, value] of Object.entries(result.rows[0])) {
3648
4129
  if (key === "_count") {
3649
4130
  ret[key] = value;
3650
4131
  continue;
@@ -3666,7 +4147,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
3666
4147
  val = parseFloat(val);
3667
4148
  } else {
3668
4149
  if (op === "_sum" || op === "_min" || op === "_max") {
3669
- val = (0, import_ts_pattern9.match)(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
4150
+ val = (0, import_ts_pattern10.match)(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
3670
4151
  }
3671
4152
  }
3672
4153
  }
@@ -3687,34 +4168,47 @@ var CountOperationHandler = class extends BaseOperationHandler {
3687
4168
  __name(this, "CountOperationHandler");
3688
4169
  }
3689
4170
  async handle(_operation, args) {
3690
- const validatedArgs = this.inputValidator.validateCountArgs(this.model, args);
4171
+ const normalizedArgs = this.normalizeArgs(args);
4172
+ const parsedArgs = this.inputValidator.validateCountArgs(this.model, normalizedArgs);
4173
+ const subQueryName = "$sub";
3691
4174
  let query = this.kysely.selectFrom((eb) => {
3692
- let subQuery = eb.selectFrom(this.model).selectAll().where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, validatedArgs?.where));
3693
- subQuery = this.dialect.buildSkipTake(subQuery, validatedArgs?.skip, validatedArgs?.take);
3694
- return subQuery.as("$sub");
4175
+ let subQuery = this.dialect.buildSelectModel(eb, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
4176
+ if (parsedArgs?.select && typeof parsedArgs.select === "object") {
4177
+ for (const [key, value] of Object.entries(parsedArgs.select)) {
4178
+ if (key !== "_all" && value === true) {
4179
+ subQuery = this.dialect.buildSelectField(subQuery, this.model, this.model, key);
4180
+ }
4181
+ }
4182
+ } else {
4183
+ subQuery = subQuery.select(() => eb.lit(1).as("_all"));
4184
+ }
4185
+ subQuery = this.dialect.buildSkipTake(subQuery, parsedArgs?.skip, parsedArgs?.take);
4186
+ return subQuery.as(subQueryName);
3695
4187
  });
3696
- if (validatedArgs?.select && typeof validatedArgs.select === "object") {
3697
- query = query.select((eb) => Object.keys(validatedArgs.select).map((key) => key === "_all" ? eb.cast(eb.fn.countAll(), "integer").as("_all") : eb.cast(eb.fn.count(import_kysely10.sql.ref(`$sub.${key}`)), "integer").as(key)));
3698
- return query.executeTakeFirstOrThrow();
4188
+ if (parsedArgs?.select && typeof parsedArgs.select === "object") {
4189
+ query = query.select((eb) => Object.keys(parsedArgs.select).map((key) => key === "_all" ? eb.cast(eb.fn.countAll(), "integer").as("_all") : eb.cast(eb.fn.count(import_kysely10.sql.ref(`${subQueryName}.${key}`)), "integer").as(key)));
4190
+ const result = await this.executeQuery(this.kysely, query, "count");
4191
+ return result.rows[0];
3699
4192
  } else {
3700
4193
  query = query.select((eb) => eb.cast(eb.fn.countAll(), "integer").as("count"));
3701
- const result = await query.executeTakeFirstOrThrow();
3702
- return result.count;
4194
+ const result = await this.executeQuery(this.kysely, query, "count");
4195
+ return result.rows[0].count;
3703
4196
  }
3704
4197
  }
3705
4198
  };
3706
4199
 
3707
4200
  // src/client/crud/operations/create.ts
3708
- var import_ts_pattern10 = require("ts-pattern");
4201
+ var import_ts_pattern11 = require("ts-pattern");
3709
4202
  var CreateOperationHandler = class extends BaseOperationHandler {
3710
4203
  static {
3711
4204
  __name(this, "CreateOperationHandler");
3712
4205
  }
3713
4206
  async handle(operation, args) {
3714
- return (0, import_ts_pattern10.match)(operation).with("create", () => this.runCreate(this.inputValidator.validateCreateArgs(this.model, args))).with("createMany", () => {
3715
- return this.runCreateMany(this.inputValidator.validateCreateManyArgs(this.model, args));
4207
+ const normalizedArgs = this.normalizeArgs(args);
4208
+ return (0, import_ts_pattern11.match)(operation).with("create", () => this.runCreate(this.inputValidator.validateCreateArgs(this.model, normalizedArgs))).with("createMany", () => {
4209
+ return this.runCreateMany(this.inputValidator.validateCreateManyArgs(this.model, normalizedArgs));
3716
4210
  }).with("createManyAndReturn", () => {
3717
- return this.runCreateManyAndReturn(this.inputValidator.validateCreateManyAndReturnArgs(this.model, args));
4211
+ return this.runCreateManyAndReturn(this.inputValidator.validateCreateManyAndReturnArgs(this.model, normalizedArgs));
3718
4212
  }).exhaustive();
3719
4213
  }
3720
4214
  async runCreate(args) {
@@ -3758,13 +4252,14 @@ var CreateOperationHandler = class extends BaseOperationHandler {
3758
4252
  };
3759
4253
 
3760
4254
  // src/client/crud/operations/delete.ts
3761
- var import_ts_pattern11 = require("ts-pattern");
4255
+ var import_ts_pattern12 = require("ts-pattern");
3762
4256
  var DeleteOperationHandler = class extends BaseOperationHandler {
3763
4257
  static {
3764
4258
  __name(this, "DeleteOperationHandler");
3765
4259
  }
3766
4260
  async handle(operation, args) {
3767
- return (0, import_ts_pattern11.match)(operation).with("delete", () => this.runDelete(this.inputValidator.validateDeleteArgs(this.model, args))).with("deleteMany", () => this.runDeleteMany(this.inputValidator.validateDeleteManyArgs(this.model, args))).exhaustive();
4261
+ const normalizedArgs = this.normalizeArgs(args);
4262
+ return (0, import_ts_pattern12.match)(operation).with("delete", () => this.runDelete(this.inputValidator.validateDeleteArgs(this.model, normalizedArgs))).with("deleteMany", () => this.runDeleteMany(this.inputValidator.validateDeleteManyArgs(this.model, normalizedArgs))).exhaustive();
3768
4263
  }
3769
4264
  async runDelete(args) {
3770
4265
  const existing = await this.readUnique(this.kysely, this.model, {
@@ -3776,15 +4271,19 @@ var DeleteOperationHandler = class extends BaseOperationHandler {
3776
4271
  if (!existing) {
3777
4272
  throw new NotFoundError(this.model);
3778
4273
  }
3779
- const result = await this.delete(this.kysely, this.model, args.where, void 0, false);
3780
- if (result.count === 0) {
3781
- throw new NotFoundError(this.model);
3782
- }
4274
+ await this.safeTransaction(async (tx) => {
4275
+ const result = await this.delete(tx, this.model, args.where);
4276
+ if (result.count === 0) {
4277
+ throw new NotFoundError(this.model);
4278
+ }
4279
+ });
3783
4280
  return existing;
3784
4281
  }
3785
4282
  async runDeleteMany(args) {
3786
- const result = await this.delete(this.kysely, this.model, args?.where, args?.limit, false);
3787
- return result;
4283
+ return await this.safeTransaction(async (tx) => {
4284
+ const result = await this.delete(tx, this.model, args?.where, args?.limit);
4285
+ return result;
4286
+ });
3788
4287
  }
3789
4288
  };
3790
4289
 
@@ -3794,7 +4293,8 @@ var FindOperationHandler = class extends BaseOperationHandler {
3794
4293
  __name(this, "FindOperationHandler");
3795
4294
  }
3796
4295
  async handle(operation, args, validateArgs = true) {
3797
- const parsedArgs = validateArgs ? this.inputValidator.validateFindArgs(this.model, operation === "findUnique", args) : args;
4296
+ const normalizedArgs = this.normalizeArgs(args);
4297
+ const parsedArgs = validateArgs ? this.inputValidator.validateFindArgs(this.model, operation === "findUnique", normalizedArgs) : normalizedArgs;
3798
4298
  const result = await this.read(this.client.$qb, this.model, parsedArgs);
3799
4299
  const finalResult = operation === "findMany" ? result : result[0] ?? null;
3800
4300
  return finalResult;
@@ -3803,17 +4303,18 @@ var FindOperationHandler = class extends BaseOperationHandler {
3803
4303
 
3804
4304
  // src/client/crud/operations/group-by.ts
3805
4305
  var import_kysely11 = require("kysely");
3806
- var import_ts_pattern12 = require("ts-pattern");
3807
- var GroupByeOperationHandler = class extends BaseOperationHandler {
4306
+ var import_ts_pattern13 = require("ts-pattern");
4307
+ var GroupByOperationHandler = class extends BaseOperationHandler {
3808
4308
  static {
3809
- __name(this, "GroupByeOperationHandler");
4309
+ __name(this, "GroupByOperationHandler");
3810
4310
  }
3811
4311
  async handle(_operation, args) {
3812
- const validatedArgs = this.inputValidator.validateGroupByArgs(this.model, args);
4312
+ const normalizedArgs = this.normalizeArgs(args);
4313
+ const parsedArgs = this.inputValidator.validateGroupByArgs(this.model, normalizedArgs);
3813
4314
  let query = this.kysely.selectFrom((eb) => {
3814
- let subQuery = eb.selectFrom(this.model).selectAll().where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, validatedArgs?.where));
3815
- const skip = validatedArgs?.skip;
3816
- let take = validatedArgs?.take;
4315
+ let subQuery = eb.selectFrom(this.model).selectAll().where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
4316
+ const skip = parsedArgs?.skip;
4317
+ let take = parsedArgs?.take;
3817
4318
  let negateOrderBy = false;
3818
4319
  if (take !== void 0 && take < 0) {
3819
4320
  negateOrderBy = true;
@@ -3823,20 +4324,21 @@ var GroupByeOperationHandler = class extends BaseOperationHandler {
3823
4324
  subQuery = this.dialect.buildOrderBy(subQuery, this.model, this.model, void 0, skip !== void 0 || take !== void 0, negateOrderBy);
3824
4325
  return subQuery.as("$sub");
3825
4326
  });
3826
- const bys = typeof validatedArgs.by === "string" ? [
3827
- validatedArgs.by
3828
- ] : validatedArgs.by;
3829
- query = query.groupBy(bys);
3830
- if (validatedArgs.orderBy) {
3831
- query = this.dialect.buildOrderBy(query, this.model, "$sub", validatedArgs.orderBy, false, false);
4327
+ const fieldRef = /* @__PURE__ */ __name((field) => this.dialect.fieldRef(this.model, field, (0, import_kysely11.expressionBuilder)(), "$sub"), "fieldRef");
4328
+ const bys = typeof parsedArgs.by === "string" ? [
4329
+ parsedArgs.by
4330
+ ] : parsedArgs.by;
4331
+ query = query.groupBy(bys.map((by) => fieldRef(by)));
4332
+ if (parsedArgs.orderBy) {
4333
+ query = this.dialect.buildOrderBy(query, this.model, "$sub", parsedArgs.orderBy, false, false);
3832
4334
  }
3833
- if (validatedArgs.having) {
3834
- query = query.having((eb1) => this.dialect.buildFilter(eb1, this.model, "$sub", validatedArgs.having));
4335
+ if (parsedArgs.having) {
4336
+ query = query.having((eb) => this.dialect.buildFilter(eb, this.model, "$sub", parsedArgs.having));
3835
4337
  }
3836
4338
  for (const by of bys) {
3837
- query = query.select(() => import_kysely11.sql.ref(`$sub.${by}`).as(by));
4339
+ query = query.select(() => fieldRef(by).as(by));
3838
4340
  }
3839
- for (const [key, value] of Object.entries(validatedArgs)) {
4341
+ for (const [key, value] of Object.entries(parsedArgs)) {
3840
4342
  switch (key) {
3841
4343
  case "_count": {
3842
4344
  if (value === true) {
@@ -3847,7 +4349,7 @@ var GroupByeOperationHandler = class extends BaseOperationHandler {
3847
4349
  if (field === "_all") {
3848
4350
  query = query.select((eb) => eb.cast(eb.fn.countAll(), "integer").as(`_count._all`));
3849
4351
  } else {
3850
- query = query.select((eb) => eb.cast(eb.fn.count(import_kysely11.sql.ref(`$sub.${field}`)), "integer").as(`${key}.${field}`));
4352
+ query = query.select((eb) => eb.cast(eb.fn.count(fieldRef(field)), "integer").as(`${key}.${field}`));
3851
4353
  }
3852
4354
  }
3853
4355
  });
@@ -3860,18 +4362,15 @@ var GroupByeOperationHandler = class extends BaseOperationHandler {
3860
4362
  case "_min": {
3861
4363
  Object.entries(value).forEach(([field, val]) => {
3862
4364
  if (val === true) {
3863
- query = query.select((eb) => {
3864
- const fn = (0, import_ts_pattern12.match)(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
3865
- return fn(import_kysely11.sql.ref(`$sub.${field}`)).as(`${key}.${field}`);
3866
- });
4365
+ query = query.select((eb) => aggregate(eb, fieldRef(field), key).as(`${key}.${field}`));
3867
4366
  }
3868
4367
  });
3869
4368
  break;
3870
4369
  }
3871
4370
  }
3872
4371
  }
3873
- const result = await query.execute();
3874
- return result.map((row) => this.postProcessRow(row));
4372
+ const result = await this.executeQuery(this.kysely, query, "groupBy");
4373
+ return result.rows.map((row) => this.postProcessRow(row));
3875
4374
  }
3876
4375
  postProcessRow(row) {
3877
4376
  const ret = {};
@@ -3898,7 +4397,7 @@ var GroupByeOperationHandler = class extends BaseOperationHandler {
3898
4397
  val = parseFloat(val);
3899
4398
  } else {
3900
4399
  if (op === "_sum" || op === "_min" || op === "_max") {
3901
- val = (0, import_ts_pattern12.match)(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
4400
+ val = (0, import_ts_pattern13.match)(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
3902
4401
  }
3903
4402
  }
3904
4403
  }
@@ -3913,31 +4412,45 @@ var GroupByeOperationHandler = class extends BaseOperationHandler {
3913
4412
  };
3914
4413
 
3915
4414
  // src/client/crud/operations/update.ts
3916
- var import_ts_pattern13 = require("ts-pattern");
4415
+ var import_ts_pattern14 = require("ts-pattern");
3917
4416
  var UpdateOperationHandler = class extends BaseOperationHandler {
3918
4417
  static {
3919
4418
  __name(this, "UpdateOperationHandler");
3920
4419
  }
3921
4420
  async handle(operation, args) {
3922
- return (0, import_ts_pattern13.match)(operation).with("update", () => this.runUpdate(this.inputValidator.validateUpdateArgs(this.model, args))).with("updateMany", () => this.runUpdateMany(this.inputValidator.validateUpdateManyArgs(this.model, args))).with("updateManyAndReturn", () => this.runUpdateManyAndReturn(this.inputValidator.validateUpdateManyAndReturnArgs(this.model, args))).with("upsert", () => this.runUpsert(this.inputValidator.validateUpsertArgs(this.model, args))).exhaustive();
4421
+ const normalizedArgs = this.normalizeArgs(args);
4422
+ return (0, import_ts_pattern14.match)(operation).with("update", () => this.runUpdate(this.inputValidator.validateUpdateArgs(this.model, normalizedArgs))).with("updateMany", () => this.runUpdateMany(this.inputValidator.validateUpdateManyArgs(this.model, normalizedArgs))).with("updateManyAndReturn", () => this.runUpdateManyAndReturn(this.inputValidator.validateUpdateManyAndReturnArgs(this.model, normalizedArgs))).with("upsert", () => this.runUpsert(this.inputValidator.validateUpsertArgs(this.model, normalizedArgs))).exhaustive();
3923
4423
  }
3924
4424
  async runUpdate(args) {
3925
- const result = await this.safeTransaction(async (tx) => {
3926
- const updated = await this.update(tx, this.model, args.where, args.data);
3927
- return this.readUnique(tx, this.model, {
3928
- select: args.select,
3929
- include: args.include,
3930
- omit: args.omit,
3931
- where: getIdValues(this.schema, this.model, updated)
3932
- });
4425
+ const readBackResult = await this.safeTransaction(async (tx) => {
4426
+ const updateResult = await this.update(tx, this.model, args.where, args.data);
4427
+ const readFilter = updateResult ?? args.where;
4428
+ let readBackResult2 = void 0;
4429
+ try {
4430
+ readBackResult2 = await this.readUnique(tx, this.model, {
4431
+ select: args.select,
4432
+ include: args.include,
4433
+ omit: args.omit,
4434
+ where: readFilter
4435
+ });
4436
+ } catch {
4437
+ }
4438
+ return readBackResult2;
3933
4439
  });
3934
- if (!result && this.hasPolicyEnabled) {
3935
- throw new RejectedByPolicyError(this.model, "result is not allowed to be read back");
4440
+ if (!readBackResult) {
4441
+ if (this.hasPolicyEnabled) {
4442
+ throw new RejectedByPolicyError(this.model, "result is not allowed to be read back");
4443
+ } else {
4444
+ return null;
4445
+ }
4446
+ } else {
4447
+ return readBackResult;
3936
4448
  }
3937
- return result;
3938
4449
  }
3939
4450
  async runUpdateMany(args) {
3940
- return this.updateMany(this.kysely, this.model, args.where, args.data, args.limit, false);
4451
+ return this.safeTransaction(async (tx) => {
4452
+ return this.updateMany(tx, this.model, args.where, args.data, args.limit, false);
4453
+ });
3941
4454
  }
3942
4455
  async runUpdateManyAndReturn(args) {
3943
4456
  if (!args) {
@@ -3975,19 +4488,19 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
3975
4488
  };
3976
4489
 
3977
4490
  // src/client/crud/validator.ts
4491
+ var import_common_helpers9 = require("@zenstackhq/common-helpers");
3978
4492
  var import_decimal = __toESM(require("decimal.js"), 1);
3979
4493
  var import_json_stable_stringify = __toESM(require("json-stable-stringify"), 1);
3980
- var import_ts_pattern14 = require("ts-pattern");
4494
+ var import_ts_pattern15 = require("ts-pattern");
3981
4495
  var import_zod = require("zod");
3982
4496
  var InputValidator = class {
3983
4497
  static {
3984
4498
  __name(this, "InputValidator");
3985
4499
  }
3986
4500
  schema;
3987
- schemaCache;
4501
+ schemaCache = /* @__PURE__ */ new Map();
3988
4502
  constructor(schema) {
3989
4503
  this.schema = schema;
3990
- this.schemaCache = /* @__PURE__ */ new Map();
3991
4504
  }
3992
4505
  validateFindArgs(model, unique, args) {
3993
4506
  return this.validate(model, "find", {
@@ -4044,7 +4557,7 @@ var InputValidator = class {
4044
4557
  }
4045
4558
  const { error } = schema.safeParse(args);
4046
4559
  if (error) {
4047
- throw new QueryError(`Invalid ${operation} args: ${error.message}`);
4560
+ throw new InputValidationError(`Invalid ${operation} args: ${error.message}`, error);
4048
4561
  }
4049
4562
  return args;
4050
4563
  }
@@ -4063,11 +4576,11 @@ var InputValidator = class {
4063
4576
  fields["distinct"] = this.makeDistinctSchema(model).optional();
4064
4577
  fields["cursor"] = this.makeCursorSchema(model).optional();
4065
4578
  if (options.collection) {
4066
- fields["skip"] = import_zod.z.number().int().nonnegative().optional();
4067
- fields["take"] = import_zod.z.number().int().optional();
4579
+ fields["skip"] = this.makeSkipSchema().optional();
4580
+ fields["take"] = this.makeTakeSchema().optional();
4068
4581
  fields["orderBy"] = this.orArray(this.makeOrderBySchema(model, true, false), true).optional();
4069
4582
  }
4070
- let result = import_zod.z.object(fields).strict();
4583
+ let result = import_zod.z.strictObject(fields);
4071
4584
  result = this.refineForSelectIncludeMutuallyExclusive(result);
4072
4585
  result = this.refineForSelectOmitMutuallyExclusive(result);
4073
4586
  if (!options.unique) {
@@ -4076,22 +4589,50 @@ var InputValidator = class {
4076
4589
  return result;
4077
4590
  }
4078
4591
  makePrimitiveSchema(type) {
4079
- return (0, import_ts_pattern14.match)(type).with("String", () => import_zod.z.string()).with("Int", () => import_zod.z.number()).with("Float", () => import_zod.z.number()).with("Boolean", () => import_zod.z.boolean()).with("BigInt", () => import_zod.z.union([
4080
- import_zod.z.number(),
4081
- import_zod.z.bigint()
4082
- ])).with("Decimal", () => import_zod.z.union([
4083
- import_zod.z.number(),
4084
- import_zod.z.instanceof(import_decimal.default),
4085
- import_zod.z.string()
4086
- ])).with("DateTime", () => import_zod.z.union([
4087
- import_zod.z.date(),
4088
- import_zod.z.string().datetime()
4089
- ])).with("Bytes", () => import_zod.z.instanceof(Uint8Array)).otherwise(() => import_zod.z.unknown());
4090
- }
4091
- makeWhereSchema(model, unique, withoutRelationFields = false) {
4592
+ if (this.schema.typeDefs && type in this.schema.typeDefs) {
4593
+ return this.makeTypeDefSchema(type);
4594
+ } else {
4595
+ return (0, import_ts_pattern15.match)(type).with("String", () => import_zod.z.string()).with("Int", () => import_zod.z.int()).with("Float", () => import_zod.z.number()).with("Boolean", () => import_zod.z.boolean()).with("BigInt", () => import_zod.z.union([
4596
+ import_zod.z.int(),
4597
+ import_zod.z.bigint()
4598
+ ])).with("Decimal", () => import_zod.z.union([
4599
+ import_zod.z.number(),
4600
+ import_zod.z.instanceof(import_decimal.default),
4601
+ import_zod.z.string()
4602
+ ])).with("DateTime", () => import_zod.z.union([
4603
+ import_zod.z.date(),
4604
+ import_zod.z.string().datetime()
4605
+ ])).with("Bytes", () => import_zod.z.instanceof(Uint8Array)).otherwise(() => import_zod.z.unknown());
4606
+ }
4607
+ }
4608
+ makeTypeDefSchema(type) {
4609
+ const key = `$typedef-${type}`;
4610
+ let schema = this.schemaCache.get(key);
4611
+ if (schema) {
4612
+ return schema;
4613
+ }
4614
+ const typeDef = this.schema.typeDefs?.[type];
4615
+ (0, import_common_helpers9.invariant)(typeDef, `Type definition "${type}" not found in schema`);
4616
+ schema = import_zod.z.looseObject(Object.fromEntries(Object.entries(typeDef.fields).map(([field, def]) => {
4617
+ let fieldSchema = this.makePrimitiveSchema(def.type);
4618
+ if (def.array) {
4619
+ fieldSchema = fieldSchema.array();
4620
+ }
4621
+ if (def.optional) {
4622
+ fieldSchema = fieldSchema.optional();
4623
+ }
4624
+ return [
4625
+ field,
4626
+ fieldSchema
4627
+ ];
4628
+ })));
4629
+ this.schemaCache.set(key, schema);
4630
+ return schema;
4631
+ }
4632
+ makeWhereSchema(model, unique, withoutRelationFields = false, withAggregations = false) {
4092
4633
  const modelDef = getModel(this.schema, model);
4093
4634
  if (!modelDef) {
4094
- throw new QueryError(`Model "${model}" not found`);
4635
+ throw new QueryError(`Model "${model}" not found in schema`);
4095
4636
  }
4096
4637
  const fields = {};
4097
4638
  for (const field of Object.keys(modelDef.fields)) {
@@ -4106,7 +4647,7 @@ var InputValidator = class {
4106
4647
  if (fieldDef.array) {
4107
4648
  fieldSchema = import_zod.z.union([
4108
4649
  fieldSchema,
4109
- import_zod.z.object({
4650
+ import_zod.z.strictObject({
4110
4651
  some: fieldSchema.optional(),
4111
4652
  every: fieldSchema.optional(),
4112
4653
  none: fieldSchema.optional()
@@ -4115,7 +4656,7 @@ var InputValidator = class {
4115
4656
  } else {
4116
4657
  fieldSchema = import_zod.z.union([
4117
4658
  fieldSchema,
4118
- import_zod.z.object({
4659
+ import_zod.z.strictObject({
4119
4660
  is: fieldSchema.optional(),
4120
4661
  isNot: fieldSchema.optional()
4121
4662
  })
@@ -4125,12 +4666,12 @@ var InputValidator = class {
4125
4666
  const enumDef = getEnum(this.schema, fieldDef.type);
4126
4667
  if (enumDef) {
4127
4668
  if (Object.keys(enumDef).length > 0) {
4128
- fieldSchema = this.makeEnumFilterSchema(enumDef, !!fieldDef.optional);
4669
+ fieldSchema = this.makeEnumFilterSchema(enumDef, !!fieldDef.optional, withAggregations);
4129
4670
  }
4130
4671
  } else if (fieldDef.array) {
4131
4672
  fieldSchema = this.makeArrayFilterSchema(fieldDef.type);
4132
4673
  } else {
4133
- fieldSchema = this.makePrimitiveFilterSchema(fieldDef.type, !!fieldDef.optional);
4674
+ fieldSchema = this.makePrimitiveFilterSchema(fieldDef.type, !!fieldDef.optional, withAggregations);
4134
4675
  }
4135
4676
  }
4136
4677
  if (fieldSchema) {
@@ -4141,18 +4682,32 @@ var InputValidator = class {
4141
4682
  const uniqueFields = getUniqueFields(this.schema, model);
4142
4683
  for (const uniqueField of uniqueFields) {
4143
4684
  if ("defs" in uniqueField) {
4144
- fields[uniqueField.name] = import_zod.z.object(Object.fromEntries(Object.entries(uniqueField.defs).map(([key, def]) => [
4145
- key,
4146
- this.makePrimitiveFilterSchema(def.type, !!def.optional)
4147
- ]))).optional();
4685
+ fields[uniqueField.name] = import_zod.z.object(Object.fromEntries(Object.entries(uniqueField.defs).map(([key, def]) => {
4686
+ (0, import_common_helpers9.invariant)(!def.relation, "unique field cannot be a relation");
4687
+ let fieldSchema;
4688
+ const enumDef = getEnum(this.schema, def.type);
4689
+ if (enumDef) {
4690
+ if (Object.keys(enumDef).length > 0) {
4691
+ fieldSchema = this.makeEnumFilterSchema(enumDef, !!def.optional, false);
4692
+ } else {
4693
+ fieldSchema = import_zod.z.never();
4694
+ }
4695
+ } else {
4696
+ fieldSchema = this.makePrimitiveFilterSchema(def.type, !!def.optional, false);
4697
+ }
4698
+ return [
4699
+ key,
4700
+ fieldSchema
4701
+ ];
4702
+ }))).optional();
4148
4703
  }
4149
4704
  }
4150
4705
  }
4151
- fields["$expr"] = import_zod.z.function().optional();
4706
+ fields["$expr"] = import_zod.z.custom((v) => typeof v === "function").optional();
4152
4707
  fields["AND"] = this.orArray(import_zod.z.lazy(() => this.makeWhereSchema(model, false, withoutRelationFields)), true).optional();
4153
4708
  fields["OR"] = import_zod.z.lazy(() => this.makeWhereSchema(model, false, withoutRelationFields)).array().optional();
4154
4709
  fields["NOT"] = this.orArray(import_zod.z.lazy(() => this.makeWhereSchema(model, false, withoutRelationFields)), true).optional();
4155
- const baseWhere = import_zod.z.object(fields).strict();
4710
+ const baseWhere = import_zod.z.strictObject(fields);
4156
4711
  let result = baseWhere;
4157
4712
  if (unique) {
4158
4713
  const uniqueFields = getUniqueFields(this.schema, model);
@@ -4171,21 +4726,25 @@ var InputValidator = class {
4171
4726
  }
4172
4727
  return result;
4173
4728
  }
4174
- makeEnumFilterSchema(enumDef, optional) {
4729
+ makeEnumFilterSchema(enumDef, optional, withAggregations) {
4175
4730
  const baseSchema = import_zod.z.enum(Object.keys(enumDef));
4176
- const components = this.makeCommonPrimitiveFilterComponents(baseSchema, optional, () => import_zod.z.lazy(() => this.makeEnumFilterSchema(enumDef, optional)));
4731
+ const components = this.makeCommonPrimitiveFilterComponents(baseSchema, optional, () => import_zod.z.lazy(() => this.makeEnumFilterSchema(enumDef, optional, withAggregations)), [
4732
+ "equals",
4733
+ "in",
4734
+ "notIn",
4735
+ "not"
4736
+ ], withAggregations ? [
4737
+ "_count",
4738
+ "_min",
4739
+ "_max"
4740
+ ] : void 0);
4177
4741
  return import_zod.z.union([
4178
4742
  this.nullableIf(baseSchema, optional),
4179
- import_zod.z.object({
4180
- equals: components.equals,
4181
- in: components.in,
4182
- notIn: components.notIn,
4183
- not: components.not
4184
- })
4743
+ import_zod.z.strictObject(components)
4185
4744
  ]);
4186
4745
  }
4187
4746
  makeArrayFilterSchema(type) {
4188
- return import_zod.z.object({
4747
+ return import_zod.z.strictObject({
4189
4748
  equals: this.makePrimitiveSchema(type).array().optional(),
4190
4749
  has: this.makePrimitiveSchema(type).optional(),
4191
4750
  hasEvery: this.makePrimitiveSchema(type).array().optional(),
@@ -4193,39 +4752,59 @@ var InputValidator = class {
4193
4752
  isEmpty: import_zod.z.boolean().optional()
4194
4753
  });
4195
4754
  }
4196
- makePrimitiveFilterSchema(type, optional) {
4197
- return (0, import_ts_pattern14.match)(type).with("String", () => this.makeStringFilterSchema(optional)).with(import_ts_pattern14.P.union("Int", "Float", "Decimal", "BigInt"), (type2) => this.makeNumberFilterSchema(this.makePrimitiveSchema(type2), optional)).with("Boolean", () => this.makeBooleanFilterSchema(optional)).with("DateTime", () => this.makeDateTimeFilterSchema(optional)).with("Bytes", () => this.makeBytesFilterSchema(optional)).exhaustive();
4755
+ makePrimitiveFilterSchema(type, optional, withAggregations) {
4756
+ if (this.schema.typeDefs && type in this.schema.typeDefs) {
4757
+ return this.makeTypeDefFilterSchema(type, optional);
4758
+ }
4759
+ return (0, import_ts_pattern15.match)(type).with("String", () => this.makeStringFilterSchema(optional, withAggregations)).with(import_ts_pattern15.P.union("Int", "Float", "Decimal", "BigInt"), (type2) => this.makeNumberFilterSchema(this.makePrimitiveSchema(type2), optional, withAggregations)).with("Boolean", () => this.makeBooleanFilterSchema(optional, withAggregations)).with("DateTime", () => this.makeDateTimeFilterSchema(optional, withAggregations)).with("Bytes", () => this.makeBytesFilterSchema(optional, withAggregations)).with("Json", () => import_zod.z.any()).with("Unsupported", () => import_zod.z.never()).exhaustive();
4760
+ }
4761
+ makeTypeDefFilterSchema(_type, _optional) {
4762
+ return import_zod.z.never();
4198
4763
  }
4199
- makeDateTimeFilterSchema(optional) {
4764
+ makeDateTimeFilterSchema(optional, withAggregations) {
4200
4765
  return this.makeCommonPrimitiveFilterSchema(import_zod.z.union([
4201
- import_zod.z.string().datetime(),
4766
+ import_zod.z.iso.datetime(),
4202
4767
  import_zod.z.date()
4203
- ]), optional, () => import_zod.z.lazy(() => this.makeDateTimeFilterSchema(optional)));
4204
- }
4205
- makeBooleanFilterSchema(optional) {
4768
+ ]), optional, () => import_zod.z.lazy(() => this.makeDateTimeFilterSchema(optional, withAggregations)), withAggregations ? [
4769
+ "_count",
4770
+ "_min",
4771
+ "_max"
4772
+ ] : void 0);
4773
+ }
4774
+ makeBooleanFilterSchema(optional, withAggregations) {
4775
+ const components = this.makeCommonPrimitiveFilterComponents(import_zod.z.boolean(), optional, () => import_zod.z.lazy(() => this.makeBooleanFilterSchema(optional, withAggregations)), [
4776
+ "equals",
4777
+ "not"
4778
+ ], withAggregations ? [
4779
+ "_count",
4780
+ "_min",
4781
+ "_max"
4782
+ ] : void 0);
4206
4783
  return import_zod.z.union([
4207
4784
  this.nullableIf(import_zod.z.boolean(), optional),
4208
- import_zod.z.object({
4209
- equals: this.nullableIf(import_zod.z.boolean(), optional).optional(),
4210
- not: import_zod.z.lazy(() => this.makeBooleanFilterSchema(optional)).optional()
4211
- })
4785
+ import_zod.z.strictObject(components)
4212
4786
  ]);
4213
4787
  }
4214
- makeBytesFilterSchema(optional) {
4788
+ makeBytesFilterSchema(optional, withAggregations) {
4215
4789
  const baseSchema = import_zod.z.instanceof(Uint8Array);
4216
- const components = this.makeCommonPrimitiveFilterComponents(baseSchema, optional, () => import_zod.z.instanceof(Uint8Array));
4790
+ const components = this.makeCommonPrimitiveFilterComponents(baseSchema, optional, () => import_zod.z.instanceof(Uint8Array), [
4791
+ "equals",
4792
+ "in",
4793
+ "notIn",
4794
+ "not"
4795
+ ], withAggregations ? [
4796
+ "_count",
4797
+ "_min",
4798
+ "_max"
4799
+ ] : void 0);
4217
4800
  return import_zod.z.union([
4218
4801
  this.nullableIf(baseSchema, optional),
4219
- import_zod.z.object({
4220
- equals: components.equals,
4221
- in: components.in,
4222
- notIn: components.notIn,
4223
- not: components.not
4224
- })
4802
+ import_zod.z.strictObject(components)
4225
4803
  ]);
4226
4804
  }
4227
- makeCommonPrimitiveFilterComponents(baseSchema, optional, makeThis) {
4228
- return {
4805
+ makeCommonPrimitiveFilterComponents(baseSchema, optional, makeThis, supportedOperators = void 0, withAggregations = void 0) {
4806
+ const commonAggSchema = /* @__PURE__ */ __name(() => this.makeCommonPrimitiveFilterSchema(baseSchema, false, makeThis, void 0).optional(), "commonAggSchema");
4807
+ let result = {
4229
4808
  equals: this.nullableIf(baseSchema.optional(), optional),
4230
4809
  notEquals: this.nullableIf(baseSchema.optional(), optional),
4231
4810
  in: baseSchema.array().optional(),
@@ -4234,20 +4813,70 @@ var InputValidator = class {
4234
4813
  lte: baseSchema.optional(),
4235
4814
  gt: baseSchema.optional(),
4236
4815
  gte: baseSchema.optional(),
4237
- not: makeThis().optional()
4816
+ not: makeThis().optional(),
4817
+ ...withAggregations?.includes("_count") ? {
4818
+ _count: this.makeNumberFilterSchema(import_zod.z.int(), false, false).optional()
4819
+ } : {},
4820
+ ...withAggregations?.includes("_avg") ? {
4821
+ _avg: commonAggSchema()
4822
+ } : {},
4823
+ ...withAggregations?.includes("_sum") ? {
4824
+ _sum: commonAggSchema()
4825
+ } : {},
4826
+ ...withAggregations?.includes("_min") ? {
4827
+ _min: commonAggSchema()
4828
+ } : {},
4829
+ ...withAggregations?.includes("_max") ? {
4830
+ _max: commonAggSchema()
4831
+ } : {}
4238
4832
  };
4833
+ if (supportedOperators) {
4834
+ const keys = [
4835
+ ...supportedOperators,
4836
+ ...withAggregations ?? []
4837
+ ];
4838
+ result = extractFields(result, keys);
4839
+ }
4840
+ return result;
4239
4841
  }
4240
- makeCommonPrimitiveFilterSchema(baseSchema, optional, makeThis) {
4842
+ makeCommonPrimitiveFilterSchema(baseSchema, optional, makeThis, withAggregations = void 0) {
4241
4843
  return import_zod.z.union([
4242
4844
  this.nullableIf(baseSchema, optional),
4243
- import_zod.z.object(this.makeCommonPrimitiveFilterComponents(baseSchema, optional, makeThis))
4845
+ import_zod.z.strictObject(this.makeCommonPrimitiveFilterComponents(baseSchema, optional, makeThis, void 0, withAggregations))
4244
4846
  ]);
4245
4847
  }
4246
- makeNumberFilterSchema(baseSchema, optional) {
4247
- return this.makeCommonPrimitiveFilterSchema(baseSchema, optional, () => import_zod.z.lazy(() => this.makeNumberFilterSchema(baseSchema, optional)));
4848
+ makeNumberFilterSchema(baseSchema, optional, withAggregations) {
4849
+ return this.makeCommonPrimitiveFilterSchema(baseSchema, optional, () => import_zod.z.lazy(() => this.makeNumberFilterSchema(baseSchema, optional, withAggregations)), withAggregations ? [
4850
+ "_count",
4851
+ "_avg",
4852
+ "_sum",
4853
+ "_min",
4854
+ "_max"
4855
+ ] : void 0);
4856
+ }
4857
+ makeStringFilterSchema(optional, withAggregations) {
4858
+ return import_zod.z.union([
4859
+ this.nullableIf(import_zod.z.string(), optional),
4860
+ import_zod.z.strictObject({
4861
+ ...this.makeCommonPrimitiveFilterComponents(import_zod.z.string(), optional, () => import_zod.z.lazy(() => this.makeStringFilterSchema(optional, withAggregations)), void 0, withAggregations ? [
4862
+ "_count",
4863
+ "_min",
4864
+ "_max"
4865
+ ] : void 0),
4866
+ startsWith: import_zod.z.string().optional(),
4867
+ endsWith: import_zod.z.string().optional(),
4868
+ contains: import_zod.z.string().optional(),
4869
+ ...this.providerSupportsCaseSensitivity ? {
4870
+ mode: this.makeStringModeSchema().optional()
4871
+ } : {}
4872
+ })
4873
+ ]);
4248
4874
  }
4249
- makeStringFilterSchema(optional) {
4250
- return this.makeCommonPrimitiveFilterSchema(import_zod.z.string(), optional, () => import_zod.z.lazy(() => this.makeStringFilterSchema(optional)));
4875
+ makeStringModeSchema() {
4876
+ return import_zod.z.union([
4877
+ import_zod.z.literal("default"),
4878
+ import_zod.z.literal("insensitive")
4879
+ ]);
4251
4880
  }
4252
4881
  makeSelectSchema(model) {
4253
4882
  const modelDef = requireModel(this.schema, model);
@@ -4257,7 +4886,7 @@ var InputValidator = class {
4257
4886
  if (fieldDef.relation) {
4258
4887
  fields[field] = import_zod.z.union([
4259
4888
  import_zod.z.literal(true),
4260
- import_zod.z.object({
4889
+ import_zod.z.strictObject({
4261
4890
  select: import_zod.z.lazy(() => this.makeSelectSchema(fieldDef.type)).optional(),
4262
4891
  include: import_zod.z.lazy(() => this.makeIncludeSchema(fieldDef.type)).optional()
4263
4892
  })
@@ -4266,22 +4895,24 @@ var InputValidator = class {
4266
4895
  fields[field] = import_zod.z.boolean().optional();
4267
4896
  }
4268
4897
  }
4269
- const toManyRelations = Object.entries(modelDef.fields).filter(([, value]) => value.relation && value.array);
4898
+ const toManyRelations = Object.values(modelDef.fields).filter((def) => def.relation && def.array);
4270
4899
  if (toManyRelations.length > 0) {
4271
4900
  fields["_count"] = import_zod.z.union([
4272
4901
  import_zod.z.literal(true),
4273
- import_zod.z.object(toManyRelations.reduce((acc, [name, fieldDef]) => ({
4274
- ...acc,
4275
- [name]: import_zod.z.union([
4276
- import_zod.z.boolean(),
4277
- import_zod.z.object({
4278
- where: this.makeWhereSchema(fieldDef.type, false, false)
4279
- })
4280
- ]).optional()
4281
- }), {}))
4902
+ import_zod.z.strictObject({
4903
+ select: import_zod.z.strictObject(toManyRelations.reduce((acc, fieldDef) => ({
4904
+ ...acc,
4905
+ [fieldDef.name]: import_zod.z.union([
4906
+ import_zod.z.boolean(),
4907
+ import_zod.z.strictObject({
4908
+ where: this.makeWhereSchema(fieldDef.type, false, false)
4909
+ })
4910
+ ]).optional()
4911
+ }), {}))
4912
+ })
4282
4913
  ]).optional();
4283
4914
  }
4284
- return import_zod.z.object(fields).strict();
4915
+ return import_zod.z.strictObject(fields);
4285
4916
  }
4286
4917
  makeOmitSchema(model) {
4287
4918
  const modelDef = requireModel(this.schema, model);
@@ -4292,7 +4923,7 @@ var InputValidator = class {
4292
4923
  fields[field] = import_zod.z.boolean().optional();
4293
4924
  }
4294
4925
  }
4295
- return import_zod.z.object(fields).strict();
4926
+ return import_zod.z.strictObject(fields);
4296
4927
  }
4297
4928
  makeIncludeSchema(model) {
4298
4929
  const modelDef = requireModel(this.schema, model);
@@ -4302,15 +4933,20 @@ var InputValidator = class {
4302
4933
  if (fieldDef.relation) {
4303
4934
  fields[field] = import_zod.z.union([
4304
4935
  import_zod.z.literal(true),
4305
- import_zod.z.object({
4936
+ import_zod.z.strictObject({
4306
4937
  select: import_zod.z.lazy(() => this.makeSelectSchema(fieldDef.type)).optional(),
4307
4938
  include: import_zod.z.lazy(() => this.makeIncludeSchema(fieldDef.type)).optional(),
4308
- where: import_zod.z.lazy(() => this.makeWhereSchema(fieldDef.type, false)).optional()
4939
+ omit: import_zod.z.lazy(() => this.makeOmitSchema(fieldDef.type)).optional(),
4940
+ where: import_zod.z.lazy(() => this.makeWhereSchema(fieldDef.type, false)).optional(),
4941
+ orderBy: import_zod.z.lazy(() => this.makeOrderBySchema(fieldDef.type, true, false)).optional(),
4942
+ skip: this.makeSkipSchema().optional(),
4943
+ take: this.makeTakeSchema().optional(),
4944
+ distinct: this.makeDistinctSchema(fieldDef.type).optional()
4309
4945
  })
4310
4946
  ]).optional();
4311
4947
  }
4312
4948
  }
4313
- return import_zod.z.object(fields).strict();
4949
+ return import_zod.z.strictObject(fields);
4314
4950
  }
4315
4951
  makeOrderBySchema(model, withRelation, WithAggregation) {
4316
4952
  const modelDef = requireModel(this.schema, model);
@@ -4323,13 +4959,21 @@ var InputValidator = class {
4323
4959
  const fieldDef = requireField(this.schema, model, field);
4324
4960
  if (fieldDef.relation) {
4325
4961
  if (withRelation) {
4326
- fields[field] = import_zod.z.lazy(() => this.makeOrderBySchema(fieldDef.type, withRelation, WithAggregation).optional());
4962
+ fields[field] = import_zod.z.lazy(() => {
4963
+ let relationOrderBy = this.makeOrderBySchema(fieldDef.type, withRelation, WithAggregation);
4964
+ if (fieldDef.array) {
4965
+ relationOrderBy = relationOrderBy.extend({
4966
+ _count: sort
4967
+ });
4968
+ }
4969
+ return relationOrderBy.optional();
4970
+ });
4327
4971
  }
4328
4972
  } else {
4329
4973
  if (fieldDef.optional) {
4330
4974
  fields[field] = import_zod.z.union([
4331
4975
  sort,
4332
- import_zod.z.object({
4976
+ import_zod.z.strictObject({
4333
4977
  sort,
4334
4978
  nulls: import_zod.z.union([
4335
4979
  import_zod.z.literal("first"),
@@ -4354,7 +4998,7 @@ var InputValidator = class {
4354
4998
  fields[agg] = import_zod.z.lazy(() => this.makeOrderBySchema(model, true, false).optional());
4355
4999
  }
4356
5000
  }
4357
- return import_zod.z.object(fields);
5001
+ return import_zod.z.strictObject(fields);
4358
5002
  }
4359
5003
  makeDistinctSchema(model) {
4360
5004
  const modelDef = requireModel(this.schema, model);
@@ -4373,7 +5017,7 @@ var InputValidator = class {
4373
5017
  select: this.makeSelectSchema(model).optional(),
4374
5018
  include: this.makeIncludeSchema(model).optional(),
4375
5019
  omit: this.makeOmitSchema(model).optional()
4376
- }).strict();
5020
+ });
4377
5021
  return this.refineForSelectIncludeMutuallyExclusive(schema);
4378
5022
  }
4379
5023
  makeCreateManySchema(model) {
@@ -4381,15 +5025,15 @@ var InputValidator = class {
4381
5025
  }
4382
5026
  makeCreateManyAndReturnSchema(model) {
4383
5027
  const base = this.makeCreateManyDataSchema(model, []);
4384
- const result = base.merge(import_zod.z.object({
5028
+ const result = base.merge(import_zod.z.strictObject({
4385
5029
  select: this.makeSelectSchema(model).optional(),
4386
5030
  omit: this.makeOmitSchema(model).optional()
4387
5031
  }));
4388
5032
  return this.refineForSelectOmitMutuallyExclusive(result).optional();
4389
5033
  }
4390
5034
  makeCreateDataSchema(model, canBeArray, withoutFields = [], withoutRelationFields = false) {
4391
- const regularAndFkFields = {};
4392
- const regularAndRelationFields = {};
5035
+ const uncheckedVariantFields = {};
5036
+ const checkedVariantFields = {};
4393
5037
  const modelDef = requireModel(this.schema, model);
4394
5038
  const hasRelation = !withoutRelationFields && Object.entries(modelDef.fields).some(([f, def]) => !withoutFields.includes(f) && def.relation);
4395
5039
  Object.keys(modelDef.fields).forEach((field) => {
@@ -4400,6 +5044,9 @@ var InputValidator = class {
4400
5044
  if (fieldDef.computed) {
4401
5045
  return;
4402
5046
  }
5047
+ if (this.isDelegateDiscriminator(fieldDef)) {
5048
+ return;
5049
+ }
4403
5050
  if (fieldDef.relation) {
4404
5051
  if (withoutRelationFields) {
4405
5052
  return;
@@ -4431,13 +5078,16 @@ var InputValidator = class {
4431
5078
  if (fieldDef.optional && !fieldDef.array) {
4432
5079
  fieldSchema = fieldSchema.nullable();
4433
5080
  }
4434
- regularAndRelationFields[field] = fieldSchema;
5081
+ checkedVariantFields[field] = fieldSchema;
5082
+ if (fieldDef.array || !fieldDef.relation.references) {
5083
+ uncheckedVariantFields[field] = fieldSchema;
5084
+ }
4435
5085
  } else {
4436
5086
  let fieldSchema = this.makePrimitiveSchema(fieldDef.type);
4437
5087
  if (fieldDef.array) {
4438
5088
  fieldSchema = import_zod.z.union([
4439
5089
  import_zod.z.array(fieldSchema),
4440
- import_zod.z.object({
5090
+ import_zod.z.strictObject({
4441
5091
  set: import_zod.z.array(fieldSchema)
4442
5092
  })
4443
5093
  ]).optional();
@@ -4448,27 +5098,34 @@ var InputValidator = class {
4448
5098
  if (fieldDef.optional) {
4449
5099
  fieldSchema = fieldSchema.nullable();
4450
5100
  }
4451
- regularAndFkFields[field] = fieldSchema;
5101
+ uncheckedVariantFields[field] = fieldSchema;
4452
5102
  if (!fieldDef.foreignKeyFor) {
4453
- regularAndRelationFields[field] = fieldSchema;
5103
+ checkedVariantFields[field] = fieldSchema;
4454
5104
  }
4455
5105
  }
4456
5106
  });
4457
5107
  if (!hasRelation) {
4458
- return this.orArray(import_zod.z.object(regularAndFkFields).strict(), canBeArray);
5108
+ return this.orArray(import_zod.z.strictObject(uncheckedVariantFields), canBeArray);
4459
5109
  } else {
4460
5110
  return import_zod.z.union([
4461
- import_zod.z.object(regularAndFkFields).strict(),
4462
- import_zod.z.object(regularAndRelationFields).strict(),
5111
+ import_zod.z.strictObject(uncheckedVariantFields),
5112
+ import_zod.z.strictObject(checkedVariantFields),
4463
5113
  ...canBeArray ? [
4464
- import_zod.z.array(import_zod.z.object(regularAndFkFields).strict())
5114
+ import_zod.z.array(import_zod.z.strictObject(uncheckedVariantFields))
4465
5115
  ] : [],
4466
5116
  ...canBeArray ? [
4467
- import_zod.z.array(import_zod.z.object(regularAndRelationFields).strict())
5117
+ import_zod.z.array(import_zod.z.strictObject(checkedVariantFields))
4468
5118
  ] : []
4469
5119
  ]);
4470
5120
  }
4471
5121
  }
5122
+ isDelegateDiscriminator(fieldDef) {
5123
+ if (!fieldDef.originModel) {
5124
+ return false;
5125
+ }
5126
+ const discriminatorField = getDiscriminatorField(this.schema, fieldDef.originModel);
5127
+ return discriminatorField === fieldDef.name;
5128
+ }
4472
5129
  makeRelationManipulationSchema(fieldDef, withoutFields, mode) {
4473
5130
  const fieldType = fieldDef.type;
4474
5131
  const array = !!fieldDef.array;
@@ -4485,31 +5142,31 @@ var InputValidator = class {
4485
5142
  fields["disconnect"] = this.makeDisconnectDataSchema(fieldType, array).optional();
4486
5143
  fields["delete"] = this.makeDeleteRelationDataSchema(fieldType, array, true).optional();
4487
5144
  }
4488
- fields["update"] = array ? this.orArray(import_zod.z.object({
5145
+ fields["update"] = array ? this.orArray(import_zod.z.strictObject({
4489
5146
  where: this.makeWhereSchema(fieldType, true),
4490
5147
  data: this.makeUpdateDataSchema(fieldType, withoutFields)
4491
5148
  }), true).optional() : import_zod.z.union([
4492
- import_zod.z.object({
5149
+ import_zod.z.strictObject({
4493
5150
  where: this.makeWhereSchema(fieldType, true),
4494
5151
  data: this.makeUpdateDataSchema(fieldType, withoutFields)
4495
5152
  }),
4496
5153
  this.makeUpdateDataSchema(fieldType, withoutFields)
4497
5154
  ]).optional();
4498
- fields["upsert"] = this.orArray(import_zod.z.object({
5155
+ fields["upsert"] = this.orArray(import_zod.z.strictObject({
4499
5156
  where: this.makeWhereSchema(fieldType, true),
4500
5157
  create: this.makeCreateDataSchema(fieldType, false, withoutFields),
4501
5158
  update: this.makeUpdateDataSchema(fieldType, withoutFields)
4502
5159
  }), true).optional();
4503
5160
  if (array) {
4504
5161
  fields["set"] = this.makeSetDataSchema(fieldType, true).optional();
4505
- fields["updateMany"] = this.orArray(import_zod.z.object({
5162
+ fields["updateMany"] = this.orArray(import_zod.z.strictObject({
4506
5163
  where: this.makeWhereSchema(fieldType, false, true),
4507
5164
  data: this.makeUpdateDataSchema(fieldType, withoutFields)
4508
5165
  }), true).optional();
4509
5166
  fields["deleteMany"] = this.makeDeleteRelationDataSchema(fieldType, true, false).optional();
4510
5167
  }
4511
5168
  }
4512
- return import_zod.z.object(fields).strict().refine((v) => Object.keys(v).length > 0, "At least one action is required");
5169
+ return import_zod.z.strictObject(fields);
4513
5170
  }
4514
5171
  makeSetDataSchema(model, canBeArray) {
4515
5172
  return this.orArray(this.makeWhereSchema(model, true), canBeArray);
@@ -4539,13 +5196,13 @@ var InputValidator = class {
4539
5196
  return this.orArray(import_zod.z.object({
4540
5197
  where: whereSchema,
4541
5198
  create: createSchema
4542
- }).strict(), canBeArray);
5199
+ }), canBeArray);
4543
5200
  }
4544
5201
  makeCreateManyDataSchema(model, withoutFields) {
4545
5202
  return import_zod.z.object({
4546
5203
  data: this.makeCreateDataSchema(model, true, withoutFields, true),
4547
5204
  skipDuplicates: import_zod.z.boolean().optional()
4548
- }).strict();
5205
+ });
4549
5206
  }
4550
5207
  // #endregion
4551
5208
  // #region Update
@@ -4556,19 +5213,19 @@ var InputValidator = class {
4556
5213
  select: this.makeSelectSchema(model).optional(),
4557
5214
  include: this.makeIncludeSchema(model).optional(),
4558
5215
  omit: this.makeOmitSchema(model).optional()
4559
- }).strict();
5216
+ });
4560
5217
  return this.refineForSelectIncludeMutuallyExclusive(schema);
4561
5218
  }
4562
5219
  makeUpdateManySchema(model) {
4563
5220
  return import_zod.z.object({
4564
5221
  where: this.makeWhereSchema(model, false).optional(),
4565
5222
  data: this.makeUpdateDataSchema(model, [], true),
4566
- limit: import_zod.z.number().int().nonnegative().optional()
4567
- }).strict();
5223
+ limit: import_zod.z.int().nonnegative().optional()
5224
+ });
4568
5225
  }
4569
5226
  makeUpdateManyAndReturnSchema(model) {
4570
5227
  const base = this.makeUpdateManySchema(model);
4571
- const result = base.merge(import_zod.z.object({
5228
+ const result = base.merge(import_zod.z.strictObject({
4572
5229
  select: this.makeSelectSchema(model).optional(),
4573
5230
  omit: this.makeOmitSchema(model).optional()
4574
5231
  }));
@@ -4582,12 +5239,12 @@ var InputValidator = class {
4582
5239
  select: this.makeSelectSchema(model).optional(),
4583
5240
  include: this.makeIncludeSchema(model).optional(),
4584
5241
  omit: this.makeOmitSchema(model).optional()
4585
- }).strict();
5242
+ });
4586
5243
  return this.refineForSelectIncludeMutuallyExclusive(schema);
4587
5244
  }
4588
5245
  makeUpdateDataSchema(model, withoutFields = [], withoutRelationFields = false) {
4589
- const regularAndFkFields = {};
4590
- const regularAndRelationFields = {};
5246
+ const uncheckedVariantFields = {};
5247
+ const checkedVariantFields = {};
4591
5248
  const modelDef = requireModel(this.schema, model);
4592
5249
  const hasRelation = Object.entries(modelDef.fields).some(([key, value]) => value.relation && !withoutFields.includes(key));
4593
5250
  Object.keys(modelDef.fields).forEach((field) => {
@@ -4612,7 +5269,10 @@ var InputValidator = class {
4612
5269
  if (fieldDef.optional && !fieldDef.array) {
4613
5270
  fieldSchema = fieldSchema.nullable();
4614
5271
  }
4615
- regularAndRelationFields[field] = fieldSchema;
5272
+ checkedVariantFields[field] = fieldSchema;
5273
+ if (fieldDef.array || !fieldDef.relation.references) {
5274
+ uncheckedVariantFields[field] = fieldSchema;
5275
+ }
4616
5276
  } else {
4617
5277
  let fieldSchema = this.makePrimitiveSchema(fieldDef.type).optional();
4618
5278
  if (this.isNumericField(fieldDef)) {
@@ -4639,18 +5299,18 @@ var InputValidator = class {
4639
5299
  if (fieldDef.optional) {
4640
5300
  fieldSchema = fieldSchema.nullable();
4641
5301
  }
4642
- regularAndFkFields[field] = fieldSchema;
5302
+ uncheckedVariantFields[field] = fieldSchema;
4643
5303
  if (!fieldDef.foreignKeyFor) {
4644
- regularAndRelationFields[field] = fieldSchema;
5304
+ checkedVariantFields[field] = fieldSchema;
4645
5305
  }
4646
5306
  }
4647
5307
  });
4648
5308
  if (!hasRelation) {
4649
- return import_zod.z.object(regularAndFkFields).strict();
5309
+ return import_zod.z.strictObject(uncheckedVariantFields);
4650
5310
  } else {
4651
5311
  return import_zod.z.union([
4652
- import_zod.z.object(regularAndFkFields).strict(),
4653
- import_zod.z.object(regularAndRelationFields).strict()
5312
+ import_zod.z.strictObject(uncheckedVariantFields),
5313
+ import_zod.z.strictObject(checkedVariantFields)
4654
5314
  ]);
4655
5315
  }
4656
5316
  }
@@ -4661,25 +5321,25 @@ var InputValidator = class {
4661
5321
  where: this.makeWhereSchema(model, true),
4662
5322
  select: this.makeSelectSchema(model).optional(),
4663
5323
  include: this.makeIncludeSchema(model).optional()
4664
- }).strict();
5324
+ });
4665
5325
  return this.refineForSelectIncludeMutuallyExclusive(schema);
4666
5326
  }
4667
5327
  makeDeleteManySchema(model) {
4668
5328
  return import_zod.z.object({
4669
5329
  where: this.makeWhereSchema(model, false).optional(),
4670
- limit: import_zod.z.number().int().nonnegative().optional()
4671
- }).strict().optional();
5330
+ limit: import_zod.z.int().nonnegative().optional()
5331
+ }).optional();
4672
5332
  }
4673
5333
  // #endregion
4674
5334
  // #region Count
4675
5335
  makeCountSchema(model) {
4676
5336
  return import_zod.z.object({
4677
5337
  where: this.makeWhereSchema(model, false).optional(),
4678
- skip: import_zod.z.number().int().nonnegative().optional(),
4679
- take: import_zod.z.number().int().optional(),
5338
+ skip: this.makeSkipSchema().optional(),
5339
+ take: this.makeTakeSchema().optional(),
4680
5340
  orderBy: this.orArray(this.makeOrderBySchema(model, true, false), true).optional(),
4681
5341
  select: this.makeCountAggregateInputSchema(model).optional()
4682
- }).strict().optional();
5342
+ }).optional();
4683
5343
  }
4684
5344
  makeCountAggregateInputSchema(model) {
4685
5345
  const modelDef = requireModel(this.schema, model);
@@ -4691,7 +5351,7 @@ var InputValidator = class {
4691
5351
  acc[field] = import_zod.z.literal(true).optional();
4692
5352
  return acc;
4693
5353
  }, {})
4694
- }).strict()
5354
+ })
4695
5355
  ]);
4696
5356
  }
4697
5357
  // #endregion
@@ -4699,19 +5359,19 @@ var InputValidator = class {
4699
5359
  makeAggregateSchema(model) {
4700
5360
  return import_zod.z.object({
4701
5361
  where: this.makeWhereSchema(model, false).optional(),
4702
- skip: import_zod.z.number().int().nonnegative().optional(),
4703
- take: import_zod.z.number().int().optional(),
5362
+ skip: this.makeSkipSchema().optional(),
5363
+ take: this.makeTakeSchema().optional(),
4704
5364
  orderBy: this.orArray(this.makeOrderBySchema(model, true, false), true).optional(),
4705
5365
  _count: this.makeCountAggregateInputSchema(model).optional(),
4706
5366
  _avg: this.makeSumAvgInputSchema(model).optional(),
4707
5367
  _sum: this.makeSumAvgInputSchema(model).optional(),
4708
5368
  _min: this.makeMinMaxInputSchema(model).optional(),
4709
5369
  _max: this.makeMinMaxInputSchema(model).optional()
4710
- }).strict().optional();
5370
+ }).optional();
4711
5371
  }
4712
5372
  makeSumAvgInputSchema(model) {
4713
5373
  const modelDef = requireModel(this.schema, model);
4714
- return import_zod.z.object(Object.keys(modelDef.fields).reduce((acc, field) => {
5374
+ return import_zod.z.strictObject(Object.keys(modelDef.fields).reduce((acc, field) => {
4715
5375
  const fieldDef = requireField(this.schema, model, field);
4716
5376
  if (this.isNumericField(fieldDef)) {
4717
5377
  acc[field] = import_zod.z.literal(true).optional();
@@ -4721,7 +5381,7 @@ var InputValidator = class {
4721
5381
  }
4722
5382
  makeMinMaxInputSchema(model) {
4723
5383
  const modelDef = requireModel(this.schema, model);
4724
- return import_zod.z.object(Object.keys(modelDef.fields).reduce((acc, field) => {
5384
+ return import_zod.z.strictObject(Object.keys(modelDef.fields).reduce((acc, field) => {
4725
5385
  const fieldDef = requireField(this.schema, model, field);
4726
5386
  if (!fieldDef.relation && !fieldDef.array) {
4727
5387
  acc[field] = import_zod.z.literal(true).optional();
@@ -4736,30 +5396,42 @@ var InputValidator = class {
4736
5396
  where: this.makeWhereSchema(model, false).optional(),
4737
5397
  orderBy: this.orArray(this.makeOrderBySchema(model, false, true), true).optional(),
4738
5398
  by: this.orArray(import_zod.z.enum(nonRelationFields), true),
4739
- having: this.makeWhereSchema(model, false, true).optional(),
4740
- skip: import_zod.z.number().int().nonnegative().optional(),
4741
- take: import_zod.z.number().int().optional(),
5399
+ having: this.makeHavingSchema(model).optional(),
5400
+ skip: this.makeSkipSchema().optional(),
5401
+ take: this.makeTakeSchema().optional(),
4742
5402
  _count: this.makeCountAggregateInputSchema(model).optional(),
4743
5403
  _avg: this.makeSumAvgInputSchema(model).optional(),
4744
5404
  _sum: this.makeSumAvgInputSchema(model).optional(),
4745
5405
  _min: this.makeMinMaxInputSchema(model).optional(),
4746
5406
  _max: this.makeMinMaxInputSchema(model).optional()
4747
- }).strict();
5407
+ });
4748
5408
  schema = schema.refine((value) => {
4749
5409
  const bys = typeof value.by === "string" ? [
4750
5410
  value.by
4751
5411
  ] : value.by;
4752
- if (value.having && Object.keys(value.having).filter((f) => !f.startsWith("_")).some((key) => !bys.includes(key))) {
4753
- return false;
4754
- } else {
4755
- return true;
5412
+ if (value.having && typeof value.having === "object") {
5413
+ for (const [key, val] of Object.entries(value.having)) {
5414
+ if (AGGREGATE_OPERATORS.includes(key)) {
5415
+ continue;
5416
+ }
5417
+ if (bys.includes(key)) {
5418
+ continue;
5419
+ }
5420
+ if (!val || typeof val !== "object") {
5421
+ return false;
5422
+ }
5423
+ if (!this.onlyAggregationFields(val)) {
5424
+ return false;
5425
+ }
5426
+ }
4756
5427
  }
5428
+ return true;
4757
5429
  }, 'fields in "having" must be in "by"');
4758
5430
  schema = schema.refine((value) => {
4759
5431
  const bys = typeof value.by === "string" ? [
4760
5432
  value.by
4761
5433
  ] : value.by;
4762
- if (value.orderBy && Object.keys(value.orderBy).filter((f) => !f.startsWith("_")).some((key) => !bys.includes(key))) {
5434
+ if (value.orderBy && Object.keys(value.orderBy).filter((f) => !AGGREGATE_OPERATORS.includes(f)).some((key) => !bys.includes(key))) {
4763
5435
  return false;
4764
5436
  } else {
4765
5437
  return true;
@@ -4767,8 +5439,31 @@ var InputValidator = class {
4767
5439
  }, 'fields in "orderBy" must be in "by"');
4768
5440
  return schema;
4769
5441
  }
5442
+ onlyAggregationFields(val) {
5443
+ for (const [key, value] of Object.entries(val)) {
5444
+ if (AGGREGATE_OPERATORS.includes(key)) {
5445
+ continue;
5446
+ }
5447
+ if (LOGICAL_COMBINATORS.includes(key)) {
5448
+ if (enumerate(value).every((v) => this.onlyAggregationFields(v))) {
5449
+ continue;
5450
+ }
5451
+ }
5452
+ return false;
5453
+ }
5454
+ return true;
5455
+ }
5456
+ makeHavingSchema(model) {
5457
+ return this.makeWhereSchema(model, false, true, true);
5458
+ }
4770
5459
  // #endregion
4771
5460
  // #region Helpers
5461
+ makeSkipSchema() {
5462
+ return import_zod.z.int().nonnegative();
5463
+ }
5464
+ makeTakeSchema() {
5465
+ return import_zod.z.int();
5466
+ }
4772
5467
  refineForSelectIncludeMutuallyExclusive(schema) {
4773
5468
  return schema.refine((value) => !(value["select"] && value["include"]), '"select" and "include" cannot be used together');
4774
5469
  }
@@ -4787,6 +5482,9 @@ var InputValidator = class {
4787
5482
  isNumericField(fieldDef) {
4788
5483
  return NUMERIC_FIELD_TYPES.includes(fieldDef.type) && !fieldDef.array;
4789
5484
  }
5485
+ get providerSupportsCaseSensitivity() {
5486
+ return this.schema.provider.type === "postgresql";
5487
+ }
4790
5488
  };
4791
5489
 
4792
5490
  // src/client/executor/zenstack-driver.ts
@@ -4796,11 +5494,11 @@ var ZenStackDriver = class {
4796
5494
  }
4797
5495
  #driver;
4798
5496
  #log;
4799
- txConnection;
4800
5497
  #initPromise;
4801
5498
  #initDone;
4802
5499
  #destroyPromise;
4803
5500
  #connections = /* @__PURE__ */ new WeakSet();
5501
+ #txConnections = /* @__PURE__ */ new WeakMap();
4804
5502
  constructor(driver, log) {
4805
5503
  this.#initDone = false;
4806
5504
  this.#driver = driver;
@@ -4841,21 +5539,30 @@ var ZenStackDriver = class {
4841
5539
  }
4842
5540
  async beginTransaction(connection, settings) {
4843
5541
  const result = await this.#driver.beginTransaction(connection, settings);
4844
- this.txConnection = connection;
5542
+ this.#txConnections.set(connection, []);
4845
5543
  return result;
4846
5544
  }
4847
- commitTransaction(connection) {
5545
+ async commitTransaction(connection) {
4848
5546
  try {
4849
- return this.#driver.commitTransaction(connection);
4850
- } finally {
4851
- this.txConnection = void 0;
5547
+ const result = await this.#driver.commitTransaction(connection);
5548
+ const callbacks = this.#txConnections.get(connection);
5549
+ this.#txConnections.delete(connection);
5550
+ if (callbacks) {
5551
+ for (const callback of callbacks) {
5552
+ await callback();
5553
+ }
5554
+ }
5555
+ return result;
5556
+ } catch (err) {
5557
+ this.#txConnections.delete(connection);
5558
+ throw err;
4852
5559
  }
4853
5560
  }
4854
- rollbackTransaction(connection) {
5561
+ async rollbackTransaction(connection) {
4855
5562
  try {
4856
- return this.#driver.rollbackTransaction(connection);
5563
+ return await this.#driver.rollbackTransaction(connection);
4857
5564
  } finally {
4858
- this.txConnection = void 0;
5565
+ this.#txConnections.delete(connection);
4859
5566
  }
4860
5567
  }
4861
5568
  async destroy() {
@@ -4933,6 +5640,22 @@ var ZenStackDriver = class {
4933
5640
  #calculateDurationMillis(startTime) {
4934
5641
  return performanceNow() - startTime;
4935
5642
  }
5643
+ isTransactionConnection(connection) {
5644
+ return this.#txConnections.has(connection);
5645
+ }
5646
+ registerTransactionCommitCallback(connection, callback) {
5647
+ if (!this.#txConnections.has(connection)) {
5648
+ return;
5649
+ }
5650
+ const callbacks = this.#txConnections.get(connection);
5651
+ if (callbacks) {
5652
+ callbacks.push(callback);
5653
+ } else {
5654
+ this.#txConnections.set(connection, [
5655
+ callback
5656
+ ]);
5657
+ }
5658
+ }
4936
5659
  };
4937
5660
  function performanceNow() {
4938
5661
  if (typeof performance !== "undefined" && typeof performance.now === "function") {
@@ -4946,7 +5669,8 @@ __name(performanceNow, "performanceNow");
4946
5669
  // src/client/executor/zenstack-query-executor.ts
4947
5670
  var import_kysely13 = require("kysely");
4948
5671
  var import_nanoid2 = require("nanoid");
4949
- var import_ts_pattern15 = require("ts-pattern");
5672
+ var import_node_util2 = require("util");
5673
+ var import_ts_pattern16 = require("ts-pattern");
4950
5674
 
4951
5675
  // src/client/executor/name-mapper.ts
4952
5676
  var import_kysely12 = require("kysely");
@@ -4955,11 +5679,11 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
4955
5679
  __name(this, "QueryNameMapper");
4956
5680
  }
4957
5681
  schema;
4958
- modelToTableMap;
4959
- fieldToColumnMap;
4960
- modelStack;
5682
+ modelToTableMap = /* @__PURE__ */ new Map();
5683
+ fieldToColumnMap = /* @__PURE__ */ new Map();
5684
+ modelStack = [];
4961
5685
  constructor(schema) {
4962
- super(), this.schema = schema, this.modelToTableMap = /* @__PURE__ */ new Map(), this.fieldToColumnMap = /* @__PURE__ */ new Map(), this.modelStack = [];
5686
+ super(), this.schema = schema;
4963
5687
  for (const [modelName, modelDef] of Object.entries(schema.models)) {
4964
5688
  const mappedName = this.getMappedName(modelDef);
4965
5689
  if (mappedName) {
@@ -5148,7 +5872,7 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
5148
5872
  this.requireCurrentModel(contextNode);
5149
5873
  model = model ?? this.currentModel;
5150
5874
  const modelDef = requireModel(this.schema, model);
5151
- const scalarFields = Object.entries(modelDef.fields).filter(([, fieldDef]) => !fieldDef.relation && !fieldDef.computed).map(([fieldName]) => fieldName);
5875
+ const scalarFields = Object.entries(modelDef.fields).filter(([, fieldDef]) => !fieldDef.relation && !fieldDef.computed && !fieldDef.originModel).map(([fieldName]) => fieldName);
5152
5876
  return scalarFields;
5153
5877
  }
5154
5878
  };
@@ -5173,16 +5897,18 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5173
5897
  get options() {
5174
5898
  return this.client.$options;
5175
5899
  }
5176
- async executeQuery(compiledQuery, queryId) {
5900
+ async executeQuery(compiledQuery, _queryId) {
5177
5901
  let queryNode = compiledQuery.query;
5178
5902
  let mutationInterceptionInfo;
5179
5903
  if (this.isMutationNode(queryNode) && this.hasMutationHooks) {
5180
5904
  mutationInterceptionInfo = await this.callMutationInterceptionFilters(queryNode);
5181
5905
  }
5182
5906
  const task = /* @__PURE__ */ __name(async () => {
5183
- await this.callBeforeMutationHooks(queryNode, mutationInterceptionInfo);
5907
+ if (this.isMutationNode(queryNode)) {
5908
+ await this.callBeforeMutationHooks(queryNode, mutationInterceptionInfo);
5909
+ }
5184
5910
  const oldQueryNode = queryNode;
5185
- if ((import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.DeleteQueryNode.is(queryNode)) && mutationInterceptionInfo?.loadAfterMutationEntity) {
5911
+ if ((import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.UpdateQueryNode.is(queryNode)) && mutationInterceptionInfo?.loadAfterMutationEntity) {
5186
5912
  queryNode = {
5187
5913
  ...queryNode,
5188
5914
  returning: import_kysely13.ReturningNode.create([
@@ -5190,42 +5916,73 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5190
5916
  ])
5191
5917
  };
5192
5918
  }
5193
- const result = await this.proceedQueryWithKyselyInterceptors(queryNode, queryId);
5194
- await this.callAfterQueryInterceptionFilters(result, queryNode, mutationInterceptionInfo);
5919
+ const queryParams = compiledQuery.$raw ? compiledQuery.parameters : void 0;
5920
+ const result = await this.proceedQueryWithKyselyInterceptors(queryNode, queryParams);
5921
+ if (this.isMutationNode(queryNode)) {
5922
+ await this.callAfterMutationHooks(result.result, queryNode, mutationInterceptionInfo, result.connection);
5923
+ }
5195
5924
  if (oldQueryNode !== queryNode) {
5196
5925
  }
5197
- return result;
5926
+ return result.result;
5198
5927
  }, "task");
5199
- return this.executeWithTransaction(task, !!mutationInterceptionInfo?.useTransactionForMutation);
5200
- }
5201
- proceedQueryWithKyselyInterceptors(queryNode, queryId) {
5202
- let proceed = /* @__PURE__ */ __name((q) => this.proceedQuery(q, queryId), "proceed");
5203
- const makeTx = /* @__PURE__ */ __name((p) => (callback) => {
5204
- return this.executeWithTransaction(() => callback(p));
5205
- }, "makeTx");
5206
- const hooks = this.options.plugins?.filter((plugin) => typeof plugin.onKyselyQuery === "function").map((plugin) => plugin.onKyselyQuery.bind(plugin)) ?? [];
5928
+ return task();
5929
+ }
5930
+ proceedQueryWithKyselyInterceptors(queryNode, parameters) {
5931
+ let proceed = /* @__PURE__ */ __name((q) => this.proceedQuery(q, parameters), "proceed");
5932
+ const hooks = [];
5933
+ for (const plugin of this.client.$options.plugins ?? []) {
5934
+ if (plugin.onKyselyQuery) {
5935
+ hooks.push(plugin.onKyselyQuery.bind(plugin));
5936
+ }
5937
+ }
5207
5938
  for (const hook of hooks) {
5208
5939
  const _proceed = proceed;
5209
- proceed = /* @__PURE__ */ __name((query) => {
5210
- return hook({
5940
+ proceed = /* @__PURE__ */ __name(async (query) => {
5941
+ let connection;
5942
+ const _p = /* @__PURE__ */ __name(async (q) => {
5943
+ const r = await _proceed(q);
5944
+ connection = r.connection;
5945
+ return r.result;
5946
+ }, "_p");
5947
+ const hookResult = await hook({
5211
5948
  client: this.client,
5212
5949
  schema: this.client.$schema,
5213
5950
  kysely: this.kysely,
5214
5951
  query,
5215
- proceed: _proceed,
5216
- transaction: makeTx(_proceed)
5952
+ proceed: _p
5217
5953
  });
5954
+ return {
5955
+ result: hookResult,
5956
+ connection
5957
+ };
5218
5958
  }, "proceed");
5219
5959
  }
5220
5960
  return proceed(queryNode);
5221
5961
  }
5222
- async proceedQuery(query, queryId) {
5962
+ async proceedQuery(query, parameters) {
5223
5963
  const finalQuery = this.nameMapper.transformNode(query);
5224
- const compiled = this.compileQuery(finalQuery);
5964
+ let compiled = this.compileQuery(finalQuery);
5965
+ if (parameters) {
5966
+ compiled = {
5967
+ ...compiled,
5968
+ parameters
5969
+ };
5970
+ }
5225
5971
  try {
5226
- return this.driver.txConnection ? await super.withConnectionProvider(new import_kysely13.SingleConnectionProvider(this.driver.txConnection)).executeQuery(compiled, queryId) : await super.executeQuery(compiled, queryId);
5972
+ return await this.provideConnection(async (connection) => {
5973
+ const result = await connection.executeQuery(compiled);
5974
+ return {
5975
+ result,
5976
+ connection
5977
+ };
5978
+ });
5227
5979
  } catch (err) {
5228
- throw new QueryError(`Failed to execute query: ${err}, sql: ${compiled.sql}, parameters: ${compiled.parameters}`);
5980
+ let message = `Failed to execute query: ${err}, sql: ${compiled.sql}`;
5981
+ if (this.options.debug) {
5982
+ message += `, parameters:
5983
+ ${compiled.parameters.map((p) => (0, import_node_util2.inspect)(p)).join("\n")}`;
5984
+ }
5985
+ throw new QueryError(message, err);
5229
5986
  }
5230
5987
  }
5231
5988
  isMutationNode(queryNode) {
@@ -5253,30 +6010,15 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5253
6010
  return new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, this.connectionProvider, []);
5254
6011
  }
5255
6012
  withConnectionProvider(connectionProvider) {
5256
- return new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, connectionProvider);
5257
- }
5258
- async executeWithTransaction(callback, useTransaction = true) {
5259
- if (!useTransaction || this.driver.txConnection) {
5260
- return callback();
5261
- } else {
5262
- return this.provideConnection(async (connection) => {
5263
- try {
5264
- await this.driver.beginTransaction(connection, {});
5265
- const result = await callback();
5266
- await this.driver.commitTransaction(connection);
5267
- return result;
5268
- } catch (error) {
5269
- await this.driver.rollbackTransaction(connection);
5270
- throw error;
5271
- }
5272
- });
5273
- }
6013
+ const newExecutor = new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, connectionProvider);
6014
+ newExecutor.client = this.client.withExecutor(newExecutor);
6015
+ return newExecutor;
5274
6016
  }
5275
6017
  get hasMutationHooks() {
5276
6018
  return this.client.$options.plugins?.some((plugin) => plugin.beforeEntityMutation || plugin.afterEntityMutation);
5277
6019
  }
5278
6020
  getMutationModel(queryNode) {
5279
- return (0, import_ts_pattern15.match)(queryNode).when(import_kysely13.InsertQueryNode.is, (node) => node.into.table.identifier.name).when(import_kysely13.UpdateQueryNode.is, (node) => node.table.table.identifier.name).when(import_kysely13.DeleteQueryNode.is, (node) => {
6021
+ return (0, import_ts_pattern16.match)(queryNode).when(import_kysely13.InsertQueryNode.is, (node) => node.into.table.identifier.name).when(import_kysely13.UpdateQueryNode.is, (node) => node.table.table.identifier.name).when(import_kysely13.DeleteQueryNode.is, (node) => {
5280
6022
  if (node.from.froms.length !== 1) {
5281
6023
  throw new InternalError(`Delete query must have exactly one from table`);
5282
6024
  }
@@ -5292,7 +6034,7 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5292
6034
  const result = {
5293
6035
  intercept: false
5294
6036
  };
5295
- const { action, where } = (0, import_ts_pattern15.match)(queryNode).when(import_kysely13.InsertQueryNode.is, () => ({
6037
+ const { action, where } = (0, import_ts_pattern16.match)(queryNode).when(import_kysely13.InsertQueryNode.is, () => ({
5296
6038
  action: "create",
5297
6039
  where: void 0
5298
6040
  })).when(import_kysely13.UpdateQueryNode.is, (node) => ({
@@ -5312,14 +6054,13 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5312
6054
  queryNode
5313
6055
  });
5314
6056
  result.intercept ||= filterResult.intercept;
5315
- result.useTransactionForMutation ||= filterResult.useTransactionForMutation;
5316
6057
  result.loadBeforeMutationEntity ||= filterResult.loadBeforeMutationEntity;
5317
6058
  result.loadAfterMutationEntity ||= filterResult.loadAfterMutationEntity;
5318
6059
  }
5319
6060
  }
5320
6061
  let beforeMutationEntities;
5321
6062
  if (result.loadBeforeMutationEntity && (import_kysely13.UpdateQueryNode.is(queryNode) || import_kysely13.DeleteQueryNode.is(queryNode))) {
5322
- beforeMutationEntities = await this.loadEntities(this.kysely, mutationModel, where);
6063
+ beforeMutationEntities = await this.loadEntities(mutationModel, where);
5323
6064
  }
5324
6065
  return {
5325
6066
  ...result,
@@ -5332,16 +6073,16 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5332
6073
  return void 0;
5333
6074
  }
5334
6075
  }
5335
- callBeforeMutationHooks(queryNode, mutationInterceptionInfo) {
6076
+ async callBeforeMutationHooks(queryNode, mutationInterceptionInfo) {
5336
6077
  if (!mutationInterceptionInfo?.intercept) {
5337
6078
  return;
5338
6079
  }
5339
6080
  if (this.options.plugins) {
6081
+ const mutationModel = this.getMutationModel(queryNode);
5340
6082
  for (const plugin of this.options.plugins) {
5341
6083
  if (plugin.beforeEntityMutation) {
5342
- plugin.beforeEntityMutation({
5343
- // context: this.queryContext,
5344
- model: this.getMutationModel(queryNode),
6084
+ await plugin.beforeEntityMutation({
6085
+ model: mutationModel,
5345
6086
  action: mutationInterceptionInfo.action,
5346
6087
  queryNode,
5347
6088
  entities: mutationInterceptionInfo.beforeMutationEntities
@@ -5350,44 +6091,59 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5350
6091
  }
5351
6092
  }
5352
6093
  }
5353
- async callAfterQueryInterceptionFilters(queryResult, queryNode, mutationInterceptionInfo) {
6094
+ async callAfterMutationHooks(queryResult, queryNode, mutationInterceptionInfo, connection) {
5354
6095
  if (!mutationInterceptionInfo?.intercept) {
5355
6096
  return;
5356
6097
  }
5357
- if (this.options.plugins) {
5358
- const mutationModel = this.getMutationModel(queryNode);
5359
- for (const plugin of this.options.plugins) {
5360
- if (plugin.afterEntityMutation) {
5361
- let afterMutationEntities = void 0;
5362
- if (mutationInterceptionInfo.loadAfterMutationEntity) {
5363
- if (import_kysely13.UpdateQueryNode.is(queryNode)) {
5364
- afterMutationEntities = await this.loadEntities(this.kysely, mutationModel, mutationInterceptionInfo.where);
5365
- } else {
5366
- afterMutationEntities = queryResult.rows;
5367
- }
5368
- }
5369
- plugin.afterEntityMutation({
5370
- model: this.getMutationModel(queryNode),
6098
+ const hooks = [];
6099
+ for (const plugin of this.options.plugins ?? []) {
6100
+ if (plugin.afterEntityMutation) {
6101
+ hooks.push(plugin.afterEntityMutation.bind(plugin));
6102
+ }
6103
+ }
6104
+ if (hooks.length === 0) {
6105
+ return;
6106
+ }
6107
+ const mutationModel = this.getMutationModel(queryNode);
6108
+ const inTransaction = this.driver.isTransactionConnection(connection);
6109
+ for (const hook of hooks) {
6110
+ let afterMutationEntities = void 0;
6111
+ if (mutationInterceptionInfo.loadAfterMutationEntity) {
6112
+ if (import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.UpdateQueryNode.is(queryNode)) {
6113
+ afterMutationEntities = queryResult.rows;
6114
+ }
6115
+ }
6116
+ const action = /* @__PURE__ */ __name(async () => {
6117
+ try {
6118
+ await hook({
6119
+ model: mutationModel,
5371
6120
  action: mutationInterceptionInfo.action,
5372
6121
  queryNode,
5373
6122
  beforeMutationEntities: mutationInterceptionInfo.beforeMutationEntities,
5374
6123
  afterMutationEntities
5375
6124
  });
6125
+ } catch (err) {
6126
+ console.error(`Error in afterEntityMutation hook for model "${mutationModel}": ${err}`);
5376
6127
  }
6128
+ }, "action");
6129
+ if (inTransaction) {
6130
+ this.driver.registerTransactionCommitCallback(connection, action);
6131
+ } else {
6132
+ await action();
5377
6133
  }
5378
6134
  }
5379
6135
  }
5380
- async loadEntities(kysely, model, where) {
5381
- const selectQuery = kysely.selectFrom(model).selectAll();
6136
+ async loadEntities(model, where) {
6137
+ const selectQuery = this.kysely.selectFrom(model).selectAll();
5382
6138
  let selectQueryNode = selectQuery.toOperationNode();
5383
6139
  selectQueryNode = {
5384
6140
  ...selectQueryNode,
5385
6141
  where: this.andNodes(selectQueryNode.where, where)
5386
6142
  };
5387
- const compiled = kysely.getExecutor().compileQuery(selectQueryNode, {
6143
+ const compiled = this.compileQuery(selectQueryNode);
6144
+ const result = await this.executeQuery(compiled, {
5388
6145
  queryId: `zenstack-${(0, import_nanoid2.nanoid)()}`
5389
6146
  });
5390
- const result = await kysely.executeQuery(compiled);
5391
6147
  return result.rows;
5392
6148
  }
5393
6149
  andNodes(condition1, condition2) {
@@ -5416,9 +6172,9 @@ __export(functions_exports, {
5416
6172
  search: () => search,
5417
6173
  startsWith: () => startsWith
5418
6174
  });
6175
+ var import_common_helpers10 = require("@zenstackhq/common-helpers");
5419
6176
  var import_kysely14 = require("kysely");
5420
- var import_tiny_invariant8 = __toESM(require("tiny-invariant"), 1);
5421
- var import_ts_pattern16 = require("ts-pattern");
6177
+ var import_ts_pattern17 = require("ts-pattern");
5422
6178
  var contains = /* @__PURE__ */ __name((eb, args) => {
5423
6179
  const [field, search2, caseInsensitive = false] = args;
5424
6180
  if (!field) {
@@ -5503,7 +6259,7 @@ var isEmpty = /* @__PURE__ */ __name((eb, args, { dialect }) => {
5503
6259
  return eb(dialect.buildArrayLength(eb, field), "=", import_kysely14.sql.lit(0));
5504
6260
  }, "isEmpty");
5505
6261
  var now = /* @__PURE__ */ __name((eb, _args, { dialect }) => {
5506
- return (0, import_ts_pattern16.match)(dialect.provider).with("postgresql", () => eb.fn("now")).with("sqlite", () => import_kysely14.sql.raw("CURRENT_TIMESTAMP")).exhaustive();
6262
+ return (0, import_ts_pattern17.match)(dialect.provider).with("postgresql", () => eb.fn("now")).with("sqlite", () => import_kysely14.sql.raw("CURRENT_TIMESTAMP")).exhaustive();
5507
6263
  }, "now");
5508
6264
  var currentModel = /* @__PURE__ */ __name((_eb, args, { model }) => {
5509
6265
  let result = model;
@@ -5523,8 +6279,8 @@ var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
5523
6279
  }, "currentOperation");
5524
6280
  function processCasing(casing, result, model) {
5525
6281
  const opNode = casing.toOperationNode();
5526
- (0, import_tiny_invariant8.default)(import_kysely14.ValueNode.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
5527
- result = (0, import_ts_pattern16.match)(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => `${result.charAt(0).toUpperCase() + result.slice(1)}`).with("uncapitalize", () => `${result.charAt(0).toLowerCase() + result.slice(1)}`).otherwise(() => {
6282
+ (0, import_common_helpers10.invariant)(import_kysely14.ValueNode.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
6283
+ result = (0, import_ts_pattern17.match)(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => (0, import_common_helpers10.upperCaseFirst)(result)).with("uncapitalize", () => (0, import_common_helpers10.lowerCaseFirst)(result)).otherwise(() => {
5528
6284
  throw new Error(`Invalid casing value: ${opNode.value}. Must be "original", "upper", "lower", "capitalize", or "uncapitalize".`);
5529
6285
  });
5530
6286
  return result;
@@ -5532,9 +6288,9 @@ function processCasing(casing, result, model) {
5532
6288
  __name(processCasing, "processCasing");
5533
6289
 
5534
6290
  // src/client/helpers/schema-db-pusher.ts
6291
+ var import_common_helpers11 = require("@zenstackhq/common-helpers");
5535
6292
  var import_kysely15 = require("kysely");
5536
- var import_tiny_invariant9 = __toESM(require("tiny-invariant"), 1);
5537
- var import_ts_pattern17 = require("ts-pattern");
6293
+ var import_ts_pattern18 = require("ts-pattern");
5538
6294
  var SchemaDbPusher = class {
5539
6295
  static {
5540
6296
  __name(this, "SchemaDbPusher");
@@ -5565,14 +6321,17 @@ var SchemaDbPusher = class {
5565
6321
  for (const [fieldName, fieldDef] of Object.entries(modelDef.fields)) {
5566
6322
  if (fieldDef.relation) {
5567
6323
  table = this.addForeignKeyConstraint(table, model, fieldName, fieldDef);
5568
- } else {
6324
+ } else if (!this.isComputedField(fieldDef)) {
5569
6325
  table = this.createModelField(table, fieldName, fieldDef, modelDef);
5570
6326
  }
5571
6327
  }
5572
6328
  table = this.addPrimaryKeyConstraint(table, model, modelDef);
5573
- table = this.addUniqueConstraint(table, modelDef);
6329
+ table = this.addUniqueConstraint(table, model, modelDef);
5574
6330
  return table;
5575
6331
  }
6332
+ isComputedField(fieldDef) {
6333
+ return fieldDef.attributes?.some((a) => a.name === "@computed");
6334
+ }
5576
6335
  addPrimaryKeyConstraint(table, model, modelDef) {
5577
6336
  if (modelDef.idFields.length === 1) {
5578
6337
  if (Object.values(modelDef.fields).some((f) => f.id)) {
@@ -5584,16 +6343,19 @@ var SchemaDbPusher = class {
5584
6343
  }
5585
6344
  return table;
5586
6345
  }
5587
- addUniqueConstraint(table, modelDef) {
6346
+ addUniqueConstraint(table, model, modelDef) {
5588
6347
  for (const [key, value] of Object.entries(modelDef.uniqueFields)) {
5589
- (0, import_tiny_invariant9.default)(typeof value === "object", "expecting an object");
6348
+ (0, import_common_helpers11.invariant)(typeof value === "object", "expecting an object");
5590
6349
  if ("type" in value) {
5591
6350
  const fieldDef = modelDef.fields[key];
5592
6351
  if (fieldDef.unique) {
5593
6352
  continue;
5594
6353
  }
6354
+ table = table.addUniqueConstraint(`unique_${model}_${key}`, [
6355
+ key
6356
+ ]);
5595
6357
  } else {
5596
- table = table.addUniqueConstraint(`unique_${key}`, Object.keys(value));
6358
+ table = table.addUniqueConstraint(`unique_${model}_${key}`, Object.keys(value));
5597
6359
  }
5598
6360
  }
5599
6361
  return table;
@@ -5632,7 +6394,7 @@ var SchemaDbPusher = class {
5632
6394
  return "serial";
5633
6395
  }
5634
6396
  const type = fieldDef.type;
5635
- const result = (0, import_ts_pattern17.match)(type).with("String", () => "text").with("Boolean", () => "boolean").with("Int", () => "integer").with("Float", () => "real").with("BigInt", () => "bigint").with("Decimal", () => "decimal").with("DateTime", () => "timestamp").with("Bytes", () => this.schema.provider.type === "postgresql" ? "bytea" : "blob").otherwise(() => {
6397
+ const result = (0, import_ts_pattern18.match)(type).with("String", () => "text").with("Boolean", () => "boolean").with("Int", () => "integer").with("Float", () => "real").with("BigInt", () => "bigint").with("Decimal", () => "decimal").with("DateTime", () => "timestamp").with("Bytes", () => this.schema.provider.type === "postgresql" ? "bytea" : "blob").with("Json", () => "jsonb").otherwise(() => {
5636
6398
  throw new Error(`Unsupported field type: ${type}`);
5637
6399
  });
5638
6400
  if (fieldDef.array) {
@@ -5645,7 +6407,7 @@ var SchemaDbPusher = class {
5645
6407
  return fieldDef.default && ExpressionUtils.isCall(fieldDef.default) && fieldDef.default.function === "autoincrement";
5646
6408
  }
5647
6409
  addForeignKeyConstraint(table, model, fieldName, fieldDef) {
5648
- (0, import_tiny_invariant9.default)(fieldDef.relation, "field must be a relation");
6410
+ (0, import_common_helpers11.invariant)(fieldDef.relation, "field must be a relation");
5649
6411
  if (!fieldDef.relation.fields || !fieldDef.relation.references) {
5650
6412
  return table;
5651
6413
  }
@@ -5661,16 +6423,16 @@ var SchemaDbPusher = class {
5661
6423
  return table;
5662
6424
  }
5663
6425
  mapCascadeAction(action) {
5664
- return (0, import_ts_pattern17.match)(action).with("SetNull", () => "set null").with("Cascade", () => "cascade").with("Restrict", () => "restrict").with("NoAction", () => "no action").with("SetDefault", () => "set default").exhaustive();
6426
+ return (0, import_ts_pattern18.match)(action).with("SetNull", () => "set null").with("Cascade", () => "cascade").with("Restrict", () => "restrict").with("NoAction", () => "no action").with("SetDefault", () => "set default").exhaustive();
5665
6427
  }
5666
6428
  };
5667
6429
 
5668
6430
  // src/client/promise.ts
5669
- function createDeferredPromise(callback) {
6431
+ function createZenStackPromise(callback) {
5670
6432
  let promise;
5671
- const cb = /* @__PURE__ */ __name(() => {
6433
+ const cb = /* @__PURE__ */ __name((txClient) => {
5672
6434
  try {
5673
- return promise ??= valueToPromise(callback());
6435
+ return promise ??= valueToPromise(callback(txClient));
5674
6436
  } catch (err) {
5675
6437
  return Promise.reject(err);
5676
6438
  }
@@ -5685,10 +6447,11 @@ function createDeferredPromise(callback) {
5685
6447
  finally(onFinally) {
5686
6448
  return cb().finally(onFinally);
5687
6449
  },
6450
+ cb,
5688
6451
  [Symbol.toStringTag]: "ZenStackPromise"
5689
6452
  };
5690
6453
  }
5691
- __name(createDeferredPromise, "createDeferredPromise");
6454
+ __name(createZenStackPromise, "createZenStackPromise");
5692
6455
  function valueToPromise(thing) {
5693
6456
  if (typeof thing === "object" && typeof thing?.then === "function") {
5694
6457
  return thing;
@@ -5699,9 +6462,9 @@ function valueToPromise(thing) {
5699
6462
  __name(valueToPromise, "valueToPromise");
5700
6463
 
5701
6464
  // src/client/result-processor.ts
6465
+ var import_common_helpers12 = require("@zenstackhq/common-helpers");
5702
6466
  var import_decimal2 = __toESM(require("decimal.js"), 1);
5703
- var import_tiny_invariant10 = __toESM(require("tiny-invariant"), 1);
5704
- var import_ts_pattern18 = require("ts-pattern");
6467
+ var import_ts_pattern19 = require("ts-pattern");
5705
6468
  var ResultProcessor = class {
5706
6469
  static {
5707
6470
  __name(this, "ResultProcessor");
@@ -5735,6 +6498,21 @@ var ResultProcessor = class {
5735
6498
  data[key] = typeof value === "string" ? JSON.parse(value) : value;
5736
6499
  continue;
5737
6500
  }
6501
+ if (key.startsWith(DELEGATE_JOINED_FIELD_PREFIX)) {
6502
+ if (value) {
6503
+ const subRow = this.transformJson(value);
6504
+ const subModel = key.slice(DELEGATE_JOINED_FIELD_PREFIX.length);
6505
+ const idValues = getIdValues(this.schema, subModel, subRow);
6506
+ if (Object.values(idValues).some((v) => v === null || v === void 0)) {
6507
+ delete data[key];
6508
+ continue;
6509
+ }
6510
+ const processedSubRow = this.processRow(subRow, subModel);
6511
+ Object.assign(data, processedSubRow);
6512
+ }
6513
+ delete data[key];
6514
+ continue;
6515
+ }
5738
6516
  const fieldDef = getField(this.schema, model, key);
5739
6517
  if (!fieldDef) {
5740
6518
  continue;
@@ -5774,20 +6552,24 @@ var ResultProcessor = class {
5774
6552
  return this.doProcessResult(relationData, fieldDef.type);
5775
6553
  }
5776
6554
  transformScalar(value, type) {
5777
- return (0, import_ts_pattern18.match)(type).with("Boolean", () => this.transformBoolean(value)).with("DateTime", () => this.transformDate(value)).with("Bytes", () => this.transformBytes(value)).with("Decimal", () => this.transformDecimal(value)).with("BigInt", () => this.transformBigInt(value)).otherwise(() => value);
6555
+ if (this.schema.typeDefs && type in this.schema.typeDefs) {
6556
+ return this.transformJson(value);
6557
+ } else {
6558
+ return (0, import_ts_pattern19.match)(type).with("Boolean", () => this.transformBoolean(value)).with("DateTime", () => this.transformDate(value)).with("Bytes", () => this.transformBytes(value)).with("Decimal", () => this.transformDecimal(value)).with("BigInt", () => this.transformBigInt(value)).with("Json", () => this.transformJson(value)).otherwise(() => value);
6559
+ }
5778
6560
  }
5779
6561
  transformDecimal(value) {
5780
6562
  if (value instanceof import_decimal2.default) {
5781
6563
  return value;
5782
6564
  }
5783
- (0, import_tiny_invariant10.default)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal2.default, `Expected string, number or Decimal, got ${typeof value}`);
6565
+ (0, import_common_helpers12.invariant)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal2.default, `Expected string, number or Decimal, got ${typeof value}`);
5784
6566
  return new import_decimal2.default(value);
5785
6567
  }
5786
6568
  transformBigInt(value) {
5787
6569
  if (typeof value === "bigint") {
5788
6570
  return value;
5789
6571
  }
5790
- (0, import_tiny_invariant10.default)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
6572
+ (0, import_common_helpers12.invariant)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
5791
6573
  return BigInt(value);
5792
6574
  }
5793
6575
  transformBoolean(value) {
@@ -5806,6 +6588,9 @@ var ResultProcessor = class {
5806
6588
  return Buffer.isBuffer(value) ? Uint8Array.from(value) : value;
5807
6589
  }
5808
6590
  fixReversedResult(data, model, args) {
6591
+ if (!data) {
6592
+ return;
6593
+ }
5809
6594
  if (Array.isArray(data) && typeof args === "object" && args && args.take !== void 0 && args.take < 0) {
5810
6595
  data.reverse();
5811
6596
  }
@@ -5819,13 +6604,19 @@ var ResultProcessor = class {
5819
6604
  continue;
5820
6605
  }
5821
6606
  const fieldDef = getField(this.schema, model, field);
5822
- if (!fieldDef?.relation) {
6607
+ if (!fieldDef || !fieldDef.relation || !fieldDef.array) {
5823
6608
  continue;
5824
6609
  }
5825
6610
  this.fixReversedResult(row[field], fieldDef.type, value);
5826
6611
  }
5827
6612
  }
5828
6613
  }
6614
+ transformJson(value) {
6615
+ return (0, import_ts_pattern19.match)(this.schema.provider.type).with("sqlite", () => {
6616
+ (0, import_common_helpers12.invariant)(typeof value === "string", "Expected string, got " + typeof value);
6617
+ return JSON.parse(value);
6618
+ }).otherwise(() => value);
6619
+ }
5829
6620
  };
5830
6621
 
5831
6622
  // src/client/client-impl.ts
@@ -5844,7 +6635,7 @@ var ClientImpl = class _ClientImpl {
5844
6635
  $schema;
5845
6636
  kyselyProps;
5846
6637
  auth;
5847
- constructor(schema, options, baseClient) {
6638
+ constructor(schema, options, baseClient, executor) {
5848
6639
  this.schema = schema;
5849
6640
  this.options = options;
5850
6641
  this.$schema = schema;
@@ -5856,24 +6647,23 @@ var ClientImpl = class _ClientImpl {
5856
6647
  if (baseClient) {
5857
6648
  this.kyselyProps = {
5858
6649
  ...baseClient.kyselyProps,
5859
- executor: new ZenStackQueryExecutor(this, baseClient.kyselyProps.driver, baseClient.kyselyProps.dialect.createQueryCompiler(), baseClient.kyselyProps.dialect.createAdapter(), new import_kysely16.DefaultConnectionProvider(baseClient.kyselyProps.driver))
6650
+ executor: executor ?? new ZenStackQueryExecutor(this, baseClient.kyselyProps.driver, baseClient.kyselyProps.dialect.createQueryCompiler(), baseClient.kyselyProps.dialect.createAdapter(), new import_kysely16.DefaultConnectionProvider(baseClient.kyselyProps.driver))
5860
6651
  };
5861
6652
  this.kyselyRaw = baseClient.kyselyRaw;
6653
+ this.auth = baseClient.auth;
5862
6654
  } else {
5863
- const dialect = this.getKyselyDialect();
5864
- const driver = new ZenStackDriver(dialect.createDriver(), new import_kysely16.Log(this.$options.log ?? []));
5865
- const compiler = dialect.createQueryCompiler();
5866
- const adapter = dialect.createAdapter();
6655
+ const driver = new ZenStackDriver(options.dialect.createDriver(), new import_kysely16.Log(this.$options.log ?? []));
6656
+ const compiler = options.dialect.createQueryCompiler();
6657
+ const adapter = options.dialect.createAdapter();
5867
6658
  const connectionProvider = new import_kysely16.DefaultConnectionProvider(driver);
5868
- const executor = new ZenStackQueryExecutor(this, driver, compiler, adapter, connectionProvider);
5869
6659
  this.kyselyProps = {
5870
6660
  config: {
5871
- dialect,
6661
+ dialect: options.dialect,
5872
6662
  log: this.$options.log
5873
6663
  },
5874
- dialect,
6664
+ dialect: options.dialect,
5875
6665
  driver,
5876
- executor
6666
+ executor: executor ?? new ZenStackQueryExecutor(this, driver, compiler, adapter, connectionProvider)
5877
6667
  };
5878
6668
  this.kyselyRaw = new import_kysely16.Kysely({
5879
6669
  ...this.kyselyProps,
@@ -5889,31 +6679,58 @@ var ClientImpl = class _ClientImpl {
5889
6679
  get $qbRaw() {
5890
6680
  return this.kyselyRaw;
5891
6681
  }
5892
- getKyselyDialect() {
5893
- return (0, import_ts_pattern19.match)(this.schema.provider.type).with("sqlite", () => this.makeSqliteKyselyDialect()).with("postgresql", () => this.makePostgresKyselyDialect()).exhaustive();
6682
+ get isTransaction() {
6683
+ return this.kysely.isTransaction;
5894
6684
  }
5895
- makePostgresKyselyDialect() {
5896
- const { dialectConfigProvider } = this.schema.provider;
5897
- const mergedConfig = {
5898
- ...dialectConfigProvider(),
5899
- ...this.options?.dialectConfig
5900
- };
5901
- return new import_kysely16.PostgresDialect(mergedConfig);
6685
+ /**
6686
+ * Create a new client with a new query executor.
6687
+ */
6688
+ withExecutor(executor) {
6689
+ return new _ClientImpl(this.schema, this.$options, this, executor);
5902
6690
  }
5903
- makeSqliteKyselyDialect() {
5904
- const { dialectConfigProvider } = this.schema.provider;
5905
- const mergedConfig = {
5906
- ...dialectConfigProvider(),
5907
- ...this.options?.dialectConfig
5908
- };
5909
- return new import_kysely16.SqliteDialect(mergedConfig);
6691
+ // implementation
6692
+ async $transaction(input, options) {
6693
+ (0, import_common_helpers13.invariant)(typeof input === "function" || Array.isArray(input) && input.every((p) => p.then && p.cb), "Invalid transaction input, expected a function or an array of ZenStackPromise");
6694
+ if (typeof input === "function") {
6695
+ return this.interactiveTransaction(input, options);
6696
+ } else {
6697
+ return this.sequentialTransaction(input, options);
6698
+ }
6699
+ }
6700
+ async interactiveTransaction(callback, options) {
6701
+ if (this.kysely.isTransaction) {
6702
+ return callback(this);
6703
+ } else {
6704
+ let txBuilder = this.kysely.transaction();
6705
+ if (options?.isolationLevel) {
6706
+ txBuilder = txBuilder.setIsolationLevel(options.isolationLevel);
6707
+ }
6708
+ return txBuilder.execute((tx) => {
6709
+ const txClient = new _ClientImpl(this.schema, this.$options, this);
6710
+ txClient.kysely = tx;
6711
+ return callback(txClient);
6712
+ });
6713
+ }
5910
6714
  }
5911
- async $transaction(callback) {
5912
- return this.kysely.transaction().execute((tx) => {
5913
- const txClient = new _ClientImpl(this.schema, this.$options);
6715
+ async sequentialTransaction(arg, options) {
6716
+ const execute = /* @__PURE__ */ __name(async (tx) => {
6717
+ const txClient = new _ClientImpl(this.schema, this.$options, this);
5914
6718
  txClient.kysely = tx;
5915
- return callback(txClient);
5916
- });
6719
+ const result = [];
6720
+ for (const promise of arg) {
6721
+ result.push(await promise.cb(txClient));
6722
+ }
6723
+ return result;
6724
+ }, "execute");
6725
+ if (this.kysely.isTransaction) {
6726
+ return execute(this.kysely);
6727
+ } else {
6728
+ let txBuilder = this.kysely.transaction();
6729
+ if (options?.isolationLevel) {
6730
+ txBuilder = txBuilder.setIsolationLevel(options.isolationLevel);
6731
+ }
6732
+ return txBuilder.execute((tx) => execute(tx));
6733
+ }
5917
6734
  }
5918
6735
  get $procedures() {
5919
6736
  return Object.keys(this.$schema.procedures ?? {}).reduce((acc, name) => {
@@ -5941,12 +6758,26 @@ var ClientImpl = class _ClientImpl {
5941
6758
  await new SchemaDbPusher(this.schema, this.kysely).push();
5942
6759
  }
5943
6760
  $use(plugin) {
6761
+ const newPlugins = [
6762
+ ...this.$options.plugins ?? [],
6763
+ plugin
6764
+ ];
5944
6765
  const newOptions = {
5945
6766
  ...this.options,
5946
- plugins: [
5947
- ...this.options?.plugins ?? [],
5948
- plugin
5949
- ]
6767
+ plugins: newPlugins
6768
+ };
6769
+ return new _ClientImpl(this.schema, newOptions, this);
6770
+ }
6771
+ $unuse(pluginId) {
6772
+ const newPlugins = [];
6773
+ for (const plugin of this.options.plugins ?? []) {
6774
+ if (plugin.id !== pluginId) {
6775
+ newPlugins.push(plugin);
6776
+ }
6777
+ }
6778
+ const newOptions = {
6779
+ ...this.options,
6780
+ plugins: newPlugins
5950
6781
  };
5951
6782
  return new _ClientImpl(this.schema, newOptions, this);
5952
6783
  }
@@ -5968,6 +6799,39 @@ var ClientImpl = class _ClientImpl {
5968
6799
  get $auth() {
5969
6800
  return this.auth;
5970
6801
  }
6802
+ $executeRaw(query, ...values) {
6803
+ return createZenStackPromise(async () => {
6804
+ const result = await (0, import_kysely16.sql)(query, ...values).execute(this.kysely);
6805
+ return Number(result.numAffectedRows ?? 0);
6806
+ });
6807
+ }
6808
+ $executeRawUnsafe(query, ...values) {
6809
+ return createZenStackPromise(async () => {
6810
+ const compiledQuery = this.createRawCompiledQuery(query, values);
6811
+ const result = await this.kysely.executeQuery(compiledQuery);
6812
+ return Number(result.numAffectedRows ?? 0);
6813
+ });
6814
+ }
6815
+ $queryRaw(query, ...values) {
6816
+ return createZenStackPromise(async () => {
6817
+ const result = await (0, import_kysely16.sql)(query, ...values).execute(this.kysely);
6818
+ return result.rows;
6819
+ });
6820
+ }
6821
+ $queryRawUnsafe(query, ...values) {
6822
+ return createZenStackPromise(async () => {
6823
+ const compiledQuery = this.createRawCompiledQuery(query, values);
6824
+ const result = await this.kysely.executeQuery(compiledQuery);
6825
+ return result.rows;
6826
+ });
6827
+ }
6828
+ createRawCompiledQuery(query, values) {
6829
+ const q = import_kysely16.CompiledQuery.raw(query, values);
6830
+ return {
6831
+ ...q,
6832
+ $raw: true
6833
+ };
6834
+ }
5971
6835
  };
5972
6836
  function createClientProxy(client) {
5973
6837
  const inputValidator = new InputValidator(client.$schema);
@@ -5990,9 +6854,9 @@ function createClientProxy(client) {
5990
6854
  __name(createClientProxy, "createClientProxy");
5991
6855
  function createModelCrudHandler(client, model, inputValidator, resultProcessor) {
5992
6856
  const createPromise = /* @__PURE__ */ __name((operation, args, handler, postProcess = false, throwIfNoResult = false) => {
5993
- return createDeferredPromise(async () => {
5994
- let proceed = /* @__PURE__ */ __name(async (_args, tx) => {
5995
- const _handler = tx ? handler.withClient(tx) : handler;
6857
+ return createZenStackPromise(async (txClient) => {
6858
+ let proceed = /* @__PURE__ */ __name(async (_args) => {
6859
+ const _handler = txClient ? handler.withClient(txClient) : handler;
5996
6860
  const r = await _handler.handle(operation, _args ?? args);
5997
6861
  if (!r && throwIfNoResult) {
5998
6862
  throw new NotFoundError(model);
@@ -6005,22 +6869,31 @@ function createModelCrudHandler(client, model, inputValidator, resultProcessor)
6005
6869
  }
6006
6870
  return result;
6007
6871
  }, "proceed");
6008
- const context = {
6009
- client,
6010
- model,
6011
- operation,
6012
- queryArgs: args
6013
- };
6014
6872
  const plugins = [
6015
6873
  ...client.$options.plugins ?? []
6016
6874
  ];
6017
6875
  for (const plugin of plugins) {
6018
- if (plugin.onQuery) {
6019
- const _proceed = proceed;
6020
- proceed = /* @__PURE__ */ __name(() => plugin.onQuery({
6021
- ...context,
6022
- proceed: _proceed
6023
- }), "proceed");
6876
+ if (plugin.onQuery && typeof plugin.onQuery === "object") {
6877
+ for (const [_model, modelHooks] of Object.entries(plugin.onQuery)) {
6878
+ if (_model === (0, import_common_helpers13.lowerCaseFirst)(model) || _model === "$allModels") {
6879
+ if (modelHooks && typeof modelHooks === "object") {
6880
+ for (const [op, opHooks] of Object.entries(modelHooks)) {
6881
+ if (op === operation || op === "$allOperations") {
6882
+ if (typeof opHooks === "function") {
6883
+ const _proceed = proceed;
6884
+ proceed = /* @__PURE__ */ __name(() => opHooks({
6885
+ client,
6886
+ model,
6887
+ operation,
6888
+ args,
6889
+ query: _proceed
6890
+ }), "proceed");
6891
+ }
6892
+ }
6893
+ }
6894
+ }
6895
+ }
6896
+ }
6024
6897
  }
6025
6898
  }
6026
6899
  return proceed(args);
@@ -6076,13 +6949,24 @@ function createModelCrudHandler(client, model, inputValidator, resultProcessor)
6076
6949
  return createPromise("aggregate", args, new AggregateOperationHandler(client, model, inputValidator), false);
6077
6950
  }, "aggregate"),
6078
6951
  groupBy: /* @__PURE__ */ __name((args) => {
6079
- return createPromise("groupBy", args, new GroupByeOperationHandler(client, model, inputValidator));
6952
+ return createPromise("groupBy", args, new GroupByOperationHandler(client, model, inputValidator), true);
6080
6953
  }, "groupBy")
6081
6954
  };
6082
6955
  }
6083
6956
  __name(createModelCrudHandler, "createModelCrudHandler");
6957
+
6958
+ // src/client/plugin.ts
6959
+ function definePlugin(plugin) {
6960
+ return plugin;
6961
+ }
6962
+ __name(definePlugin, "definePlugin");
6084
6963
  // Annotate the CommonJS export names for ESM import in node:
6085
6964
  0 && (module.exports = {
6086
- ZenStackClient
6965
+ InputValidationError,
6966
+ InternalError,
6967
+ NotFoundError,
6968
+ QueryError,
6969
+ ZenStackClient,
6970
+ definePlugin
6087
6971
  });
6088
6972
  //# sourceMappingURL=index.cjs.map