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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -46,7 +46,10 @@ var import_kysely16 = require("kysely");
46
46
 
47
47
  // src/client/crud/operations/aggregate.ts
48
48
  var import_kysely9 = require("kysely");
49
- 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");
50
53
 
51
54
  // src/schema/expression.ts
52
55
  var ExpressionUtils = {
@@ -127,6 +130,19 @@ var ExpressionUtils = {
127
130
  isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
128
131
  };
129
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");
145
+
130
146
  // src/client/errors.ts
131
147
  var InputValidationError = class extends Error {
132
148
  static {
@@ -405,15 +421,6 @@ function safeJSONStringify(value) {
405
421
  });
406
422
  }
407
423
  __name(safeJSONStringify, "safeJSONStringify");
408
- function extractFields(object, fields) {
409
- return fields.reduce((acc, field) => {
410
- if (field in object) {
411
- acc[field] = object[field];
412
- }
413
- return acc;
414
- }, {});
415
- }
416
- __name(extractFields, "extractFields");
417
424
  function extractIdFields(entity, schema, model) {
418
425
  const idFields = getIdFields(schema, model);
419
426
  return extractFields(entity, idFields);
@@ -445,6 +452,10 @@ function getDelegateDescendantModels(schema, model, collected = /* @__PURE__ */
445
452
  ];
446
453
  }
447
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");
448
459
 
449
460
  // src/client/crud/operations/base.ts
450
461
  var import_cuid2 = require("@paralleldrive/cuid2");
@@ -452,7 +463,7 @@ var import_common_helpers8 = require("@zenstackhq/common-helpers");
452
463
  var import_kysely8 = require("kysely");
453
464
  var import_nanoid = require("nanoid");
454
465
  var import_node_util = require("util");
455
- var import_ts_pattern8 = require("ts-pattern");
466
+ var import_ts_pattern9 = require("ts-pattern");
456
467
  var import_ulid = require("ulid");
457
468
  var uuid = __toESM(require("uuid"), 1);
458
469
 
@@ -471,15 +482,15 @@ var RejectedByPolicyError = class extends Error {
471
482
  // src/plugins/policy/policy-handler.ts
472
483
  var import_common_helpers6 = require("@zenstackhq/common-helpers");
473
484
  var import_kysely7 = require("kysely");
474
- var import_ts_pattern7 = require("ts-pattern");
485
+ var import_ts_pattern8 = require("ts-pattern");
475
486
 
476
487
  // src/client/crud/dialects/index.ts
477
- var import_ts_pattern4 = require("ts-pattern");
488
+ var import_ts_pattern5 = require("ts-pattern");
478
489
 
479
490
  // src/client/crud/dialects/postgresql.ts
480
491
  var import_common_helpers2 = require("@zenstackhq/common-helpers");
481
492
  var import_kysely2 = require("kysely");
482
- var import_ts_pattern2 = require("ts-pattern");
493
+ var import_ts_pattern3 = require("ts-pattern");
483
494
 
484
495
  // src/client/constants.ts
485
496
  var CONTEXT_COMMENT_PREFIX = "-- $$context:";
@@ -490,11 +501,23 @@ var NUMERIC_FIELD_TYPES = [
490
501
  "Decimal"
491
502
  ];
492
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
+ ];
493
516
 
494
517
  // src/client/crud/dialects/base.ts
495
518
  var import_common_helpers = require("@zenstackhq/common-helpers");
496
519
  var import_kysely = require("kysely");
497
- var import_ts_pattern = require("ts-pattern");
520
+ var import_ts_pattern2 = require("ts-pattern");
498
521
 
499
522
  // src/utils/enumerate.ts
500
523
  function enumerate(x) {
@@ -551,7 +574,7 @@ var BaseCrudDialect = class {
551
574
  if (key.startsWith("$")) {
552
575
  continue;
553
576
  }
554
- if (key === "AND" || key === "OR" || key === "NOT") {
577
+ if (this.isLogicalCombinator(key)) {
555
578
  result = this.and(eb, result, this.buildCompositeFilter(eb, model, modelAlias, key, payload));
556
579
  continue;
557
580
  }
@@ -572,8 +595,11 @@ var BaseCrudDialect = class {
572
595
  }
573
596
  return result;
574
597
  }
598
+ isLogicalCombinator(key) {
599
+ return LOGICAL_COMBINATORS.includes(key);
600
+ }
575
601
  buildCompositeFilter(eb, model, modelAlias, key, payload) {
576
- 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();
577
603
  }
578
604
  buildRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
579
605
  if (!fieldDef.array) {
@@ -722,7 +748,7 @@ var BaseCrudDialect = class {
722
748
  if (isEnum(this.schema, fieldDef.type)) {
723
749
  return this.buildEnumFilter(eb, fieldRef, fieldDef, payload);
724
750
  }
725
- return (0, import_ts_pattern.match)(fieldDef.type).with("String", () => this.buildStringFilter(eb, fieldRef, payload)).with(import_ts_pattern.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", () => {
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", () => {
726
752
  throw new InternalError("JSON filters are not supported yet");
727
753
  }).with("Unsupported", () => {
728
754
  throw new QueryError(`Unsupported field cannot be used in filters`);
@@ -750,7 +776,7 @@ var BaseCrudDialect = class {
750
776
  continue;
751
777
  }
752
778
  const rhs = Array.isArray(value) ? value.map(getRhs) : getRhs(value);
753
- const condition = (0, import_ts_pattern.match)(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
779
+ const condition = (0, import_ts_pattern2.match)(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
754
780
  (0, import_common_helpers.invariant)(Array.isArray(rhs), "right hand side must be an array");
755
781
  if (rhs.length === 0) {
756
782
  return this.false(eb);
@@ -764,7 +790,11 @@ var BaseCrudDialect = class {
764
790
  } else {
765
791
  return eb.not(eb(lhs, "in", rhs));
766
792
  }
767
- }).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(() => {
768
798
  if (throwIfInvalid) {
769
799
  throw new QueryError(`Invalid filter key: ${op}`);
770
800
  } else {
@@ -794,7 +824,7 @@ var BaseCrudDialect = class {
794
824
  if (key === "mode" || consumedKeys.includes(key)) {
795
825
  continue;
796
826
  }
797
- const condition = (0, import_ts_pattern.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(() => {
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(() => {
798
828
  throw new QueryError(`Invalid string filter key: ${key}`);
799
829
  });
800
830
  if (condition) {
@@ -875,9 +905,7 @@ var BaseCrudDialect = class {
875
905
  (0, import_common_helpers.invariant)(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
876
906
  for (const [k, v] of Object.entries(value)) {
877
907
  (0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
878
- result = result.orderBy((eb) => eb.fn(field.slice(1), [
879
- import_kysely.sql.ref(k)
880
- ]), import_kysely.sql.raw(this.negateSort(v, negated)));
908
+ result = result.orderBy((eb) => aggregate(eb, import_kysely.sql.ref(`${modelAlias}.${k}`), field), import_kysely.sql.raw(this.negateSort(v, negated)));
881
909
  }
882
910
  continue;
883
911
  }
@@ -1072,7 +1100,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1072
1100
  return value.map((v) => this.transformPrimitive(v, type, false));
1073
1101
  }
1074
1102
  } else {
1075
- return (0, import_ts_pattern2.match)(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).with("Decimal", () => value !== null ? value.toString() : value).otherwise(() => value);
1103
+ 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);
1076
1104
  }
1077
1105
  }
1078
1106
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
@@ -1229,7 +1257,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1229
1257
  // src/client/crud/dialects/sqlite.ts
1230
1258
  var import_common_helpers3 = require("@zenstackhq/common-helpers");
1231
1259
  var import_kysely3 = require("kysely");
1232
- var import_ts_pattern3 = require("ts-pattern");
1260
+ var import_ts_pattern4 = require("ts-pattern");
1233
1261
  var SqliteCrudDialect = class extends BaseCrudDialect {
1234
1262
  static {
1235
1263
  __name(this, "SqliteCrudDialect");
@@ -1247,7 +1275,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1247
1275
  if (this.schema.typeDefs && type in this.schema.typeDefs) {
1248
1276
  return JSON.stringify(value);
1249
1277
  } else {
1250
- return (0, import_ts_pattern3.match)(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => value instanceof Date ? value.toISOString() : value).with("Decimal", () => value.toString()).with("Bytes", () => Buffer.from(value)).with("Json", () => JSON.stringify(value)).otherwise(() => value);
1278
+ 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);
1251
1279
  }
1252
1280
  }
1253
1281
  }
@@ -1393,7 +1421,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1393
1421
 
1394
1422
  // src/client/crud/dialects/index.ts
1395
1423
  function getCrudDialect(schema, options) {
1396
- return (0, import_ts_pattern4.match)(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
1424
+ return (0, import_ts_pattern5.match)(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
1397
1425
  }
1398
1426
  __name(getCrudDialect, "getCrudDialect");
1399
1427
 
@@ -1718,17 +1746,17 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
1718
1746
  // src/plugins/policy/expression-transformer.ts
1719
1747
  var import_common_helpers5 = require("@zenstackhq/common-helpers");
1720
1748
  var import_kysely6 = require("kysely");
1721
- var import_ts_pattern6 = require("ts-pattern");
1749
+ var import_ts_pattern7 = require("ts-pattern");
1722
1750
 
1723
1751
  // src/plugins/policy/expression-evaluator.ts
1724
1752
  var import_common_helpers4 = require("@zenstackhq/common-helpers");
1725
- var import_ts_pattern5 = require("ts-pattern");
1753
+ var import_ts_pattern6 = require("ts-pattern");
1726
1754
  var ExpressionEvaluator = class {
1727
1755
  static {
1728
1756
  __name(this, "ExpressionEvaluator");
1729
1757
  }
1730
1758
  evaluate(expression, context) {
1731
- 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();
1759
+ 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();
1732
1760
  return result ?? null;
1733
1761
  }
1734
1762
  evaluateCall(expr2, context) {
@@ -1739,7 +1767,7 @@ var ExpressionEvaluator = class {
1739
1767
  }
1740
1768
  }
1741
1769
  evaluateUnary(expr2, context) {
1742
- return (0, import_ts_pattern5.match)(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1770
+ return (0, import_ts_pattern6.match)(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1743
1771
  }
1744
1772
  evaluateMember(expr2, context) {
1745
1773
  let val = this.evaluate(expr2.receiver, context);
@@ -1763,7 +1791,7 @@ var ExpressionEvaluator = class {
1763
1791
  }
1764
1792
  const left = this.evaluate(expr2.left, context);
1765
1793
  const right = this.evaluate(expr2.right, context);
1766
- 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", () => {
1794
+ 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", () => {
1767
1795
  const _right = right ?? [];
1768
1796
  (0, import_common_helpers4.invariant)(Array.isArray(_right), 'expected array for "in" operator');
1769
1797
  return _right.includes(left);
@@ -1777,7 +1805,7 @@ var ExpressionEvaluator = class {
1777
1805
  return false;
1778
1806
  }
1779
1807
  (0, import_common_helpers4.invariant)(Array.isArray(left), "expected array");
1780
- return (0, import_ts_pattern5.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1808
+ return (0, import_ts_pattern6.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1781
1809
  ...context,
1782
1810
  thisValue: item
1783
1811
  }))).with("!", () => left.every((item) => this.evaluate(expr2.right, {
@@ -2031,7 +2059,7 @@ var ExpressionTransformer = class {
2031
2059
  const count = import_kysely6.FunctionNode.create("count", [
2032
2060
  import_kysely6.ValueNode.createImmediate(1)
2033
2061
  ]);
2034
- 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();
2062
+ 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();
2035
2063
  return this.transform(expr2.left, {
2036
2064
  ...context,
2037
2065
  memberSelect: import_kysely6.SelectionNode.create(import_kysely6.AliasNode.create(predicateResult, import_kysely6.IdentifierNode.create("$t"))),
@@ -2062,7 +2090,7 @@ var ExpressionTransformer = class {
2062
2090
  return import_kysely6.BinaryOperationNode.create(this.transform(expr2.operand, context), this.transformOperator("!="), trueNode(this.dialect));
2063
2091
  }
2064
2092
  transformOperator(op) {
2065
- const mappedOp = (0, import_ts_pattern6.match)(op).with("==", () => "=").otherwise(() => op);
2093
+ const mappedOp = (0, import_ts_pattern7.match)(op).with("==", () => "=").otherwise(() => op);
2066
2094
  return import_kysely6.OperatorNode.create(mappedOp);
2067
2095
  }
2068
2096
  _call(expr2, context) {
@@ -2465,7 +2493,7 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2465
2493
  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]))))));
2466
2494
  }
2467
2495
  getMutationModel(node) {
2468
- 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) => {
2496
+ 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) => {
2469
2497
  if (node2.from.froms.length !== 1) {
2470
2498
  throw new InternalError("Only one from table is supported for delete");
2471
2499
  }
@@ -2662,19 +2690,6 @@ function clone(value) {
2662
2690
  }
2663
2691
  __name(clone, "clone");
2664
2692
 
2665
- // src/utils/object-utils.ts
2666
- function extractFields2(obj, fields) {
2667
- return Object.fromEntries(Object.entries(obj).filter(([key]) => fields.includes(key)));
2668
- }
2669
- __name(extractFields2, "extractFields");
2670
- function fieldsToSelectObject(fields) {
2671
- return Object.fromEntries(fields.map((f) => [
2672
- f,
2673
- true
2674
- ]));
2675
- }
2676
- __name(fieldsToSelectObject, "fieldsToSelectObject");
2677
-
2678
2693
  // src/client/crud/operations/base.ts
2679
2694
  var BaseOperationHandler = class {
2680
2695
  static {
@@ -3031,7 +3046,7 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3031
3046
  case "connect": {
3032
3047
  const referencedPkFields = relationField.relation.references;
3033
3048
  (0, import_common_helpers8.invariant)(referencedPkFields, "relation must have fields info");
3034
- const extractedFks = extractFields2(subPayload, referencedPkFields);
3049
+ const extractedFks = extractFields(subPayload, referencedPkFields);
3035
3050
  if (Object.keys(extractedFks).length === referencedPkFields.length) {
3036
3051
  result = extractedFks;
3037
3052
  } else {
@@ -3240,7 +3255,7 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3240
3255
  }
3241
3256
  evalGenerator(defaultValue) {
3242
3257
  if (ExpressionUtils.isCall(defaultValue)) {
3243
- 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);
3258
+ 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);
3244
3259
  } else if (ExpressionUtils.isMember(defaultValue) && ExpressionUtils.isCall(defaultValue.receiver) && defaultValue.receiver.function === "auth") {
3245
3260
  let val = this.client.$auth;
3246
3261
  for (const member of defaultValue.members) {
@@ -3422,7 +3437,7 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3422
3437
  const value = this.dialect.transformPrimitive(payload[key], fieldDef.type, false);
3423
3438
  const eb = (0, import_kysely8.expressionBuilder)();
3424
3439
  const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb);
3425
- 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(() => {
3440
+ 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(() => {
3426
3441
  throw new InternalError(`Invalid incremental update operation: ${key}`);
3427
3442
  });
3428
3443
  }
@@ -3432,7 +3447,7 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3432
3447
  const value = this.dialect.transformPrimitive(payload[key], fieldDef.type, true);
3433
3448
  const eb = (0, import_kysely8.expressionBuilder)();
3434
3449
  const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb);
3435
- return (0, import_ts_pattern8.match)(key).with("set", () => value).with("push", () => {
3450
+ return (0, import_ts_pattern9.match)(key).with("set", () => value).with("push", () => {
3436
3451
  return eb(fieldRef, "||", eb.val(ensureArray(value)));
3437
3452
  }).otherwise(() => {
3438
3453
  throw new InternalError(`Invalid array update operation: ${key}`);
@@ -4095,7 +4110,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
4095
4110
  Object.entries(value).forEach(([field, val]) => {
4096
4111
  if (val === true) {
4097
4112
  query = query.select((eb) => {
4098
- 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();
4113
+ 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();
4099
4114
  return fn(import_kysely9.sql.ref(`$sub.${field}`)).as(`${key}.${field}`);
4100
4115
  });
4101
4116
  }
@@ -4128,7 +4143,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
4128
4143
  val = parseFloat(val);
4129
4144
  } else {
4130
4145
  if (op === "_sum" || op === "_min" || op === "_max") {
4131
- 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);
4146
+ 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);
4132
4147
  }
4133
4148
  }
4134
4149
  }
@@ -4179,14 +4194,14 @@ var CountOperationHandler = class extends BaseOperationHandler {
4179
4194
  };
4180
4195
 
4181
4196
  // src/client/crud/operations/create.ts
4182
- var import_ts_pattern10 = require("ts-pattern");
4197
+ var import_ts_pattern11 = require("ts-pattern");
4183
4198
  var CreateOperationHandler = class extends BaseOperationHandler {
4184
4199
  static {
4185
4200
  __name(this, "CreateOperationHandler");
4186
4201
  }
4187
4202
  async handle(operation, args) {
4188
4203
  const normalizedArgs = this.normalizeArgs(args);
4189
- return (0, import_ts_pattern10.match)(operation).with("create", () => this.runCreate(this.inputValidator.validateCreateArgs(this.model, normalizedArgs))).with("createMany", () => {
4204
+ return (0, import_ts_pattern11.match)(operation).with("create", () => this.runCreate(this.inputValidator.validateCreateArgs(this.model, normalizedArgs))).with("createMany", () => {
4190
4205
  return this.runCreateMany(this.inputValidator.validateCreateManyArgs(this.model, normalizedArgs));
4191
4206
  }).with("createManyAndReturn", () => {
4192
4207
  return this.runCreateManyAndReturn(this.inputValidator.validateCreateManyAndReturnArgs(this.model, normalizedArgs));
@@ -4233,14 +4248,14 @@ var CreateOperationHandler = class extends BaseOperationHandler {
4233
4248
  };
4234
4249
 
4235
4250
  // src/client/crud/operations/delete.ts
4236
- var import_ts_pattern11 = require("ts-pattern");
4251
+ var import_ts_pattern12 = require("ts-pattern");
4237
4252
  var DeleteOperationHandler = class extends BaseOperationHandler {
4238
4253
  static {
4239
4254
  __name(this, "DeleteOperationHandler");
4240
4255
  }
4241
4256
  async handle(operation, args) {
4242
4257
  const normalizedArgs = this.normalizeArgs(args);
4243
- return (0, import_ts_pattern11.match)(operation).with("delete", () => this.runDelete(this.inputValidator.validateDeleteArgs(this.model, normalizedArgs))).with("deleteMany", () => this.runDeleteMany(this.inputValidator.validateDeleteManyArgs(this.model, normalizedArgs))).exhaustive();
4258
+ 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();
4244
4259
  }
4245
4260
  async runDelete(args) {
4246
4261
  const existing = await this.readUnique(this.kysely, this.model, {
@@ -4284,7 +4299,7 @@ var FindOperationHandler = class extends BaseOperationHandler {
4284
4299
 
4285
4300
  // src/client/crud/operations/group-by.ts
4286
4301
  var import_kysely11 = require("kysely");
4287
- var import_ts_pattern12 = require("ts-pattern");
4302
+ var import_ts_pattern13 = require("ts-pattern");
4288
4303
  var GroupByOperationHandler = class extends BaseOperationHandler {
4289
4304
  static {
4290
4305
  __name(this, "GroupByOperationHandler");
@@ -4308,12 +4323,12 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
4308
4323
  const bys = typeof parsedArgs.by === "string" ? [
4309
4324
  parsedArgs.by
4310
4325
  ] : parsedArgs.by;
4311
- query = query.groupBy(bys);
4326
+ query = query.groupBy(bys.map((by) => import_kysely11.sql.ref(`$sub.${by}`)));
4312
4327
  if (parsedArgs.orderBy) {
4313
4328
  query = this.dialect.buildOrderBy(query, this.model, "$sub", parsedArgs.orderBy, false, false);
4314
4329
  }
4315
4330
  if (parsedArgs.having) {
4316
- query = query.having((eb1) => this.dialect.buildFilter(eb1, this.model, "$sub", parsedArgs.having));
4331
+ query = query.having((eb) => this.dialect.buildFilter(eb, this.model, "$sub", parsedArgs.having));
4317
4332
  }
4318
4333
  for (const by of bys) {
4319
4334
  query = query.select(() => import_kysely11.sql.ref(`$sub.${by}`).as(by));
@@ -4343,7 +4358,7 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
4343
4358
  Object.entries(value).forEach(([field, val]) => {
4344
4359
  if (val === true) {
4345
4360
  query = query.select((eb) => {
4346
- 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();
4361
+ const fn = (0, import_ts_pattern13.match)(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
4347
4362
  return fn(import_kysely11.sql.ref(`$sub.${field}`)).as(`${key}.${field}`);
4348
4363
  });
4349
4364
  }
@@ -4380,7 +4395,7 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
4380
4395
  val = parseFloat(val);
4381
4396
  } else {
4382
4397
  if (op === "_sum" || op === "_min" || op === "_max") {
4383
- 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);
4398
+ 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);
4384
4399
  }
4385
4400
  }
4386
4401
  }
@@ -4395,14 +4410,14 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
4395
4410
  };
4396
4411
 
4397
4412
  // src/client/crud/operations/update.ts
4398
- var import_ts_pattern13 = require("ts-pattern");
4413
+ var import_ts_pattern14 = require("ts-pattern");
4399
4414
  var UpdateOperationHandler = class extends BaseOperationHandler {
4400
4415
  static {
4401
4416
  __name(this, "UpdateOperationHandler");
4402
4417
  }
4403
4418
  async handle(operation, args) {
4404
4419
  const normalizedArgs = this.normalizeArgs(args);
4405
- return (0, import_ts_pattern13.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();
4420
+ 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();
4406
4421
  }
4407
4422
  async runUpdate(args) {
4408
4423
  const readBackResult = await this.safeTransaction(async (tx) => {
@@ -4474,7 +4489,7 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4474
4489
  var import_common_helpers9 = require("@zenstackhq/common-helpers");
4475
4490
  var import_decimal = __toESM(require("decimal.js"), 1);
4476
4491
  var import_json_stable_stringify = __toESM(require("json-stable-stringify"), 1);
4477
- var import_ts_pattern14 = require("ts-pattern");
4492
+ var import_ts_pattern15 = require("ts-pattern");
4478
4493
  var import_zod = require("zod");
4479
4494
  var InputValidator = class {
4480
4495
  static {
@@ -4575,8 +4590,8 @@ var InputValidator = class {
4575
4590
  if (this.schema.typeDefs && type in this.schema.typeDefs) {
4576
4591
  return this.makeTypeDefSchema(type);
4577
4592
  } else {
4578
- 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([
4579
- import_zod.z.number(),
4593
+ 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([
4594
+ import_zod.z.int(),
4580
4595
  import_zod.z.bigint()
4581
4596
  ])).with("Decimal", () => import_zod.z.union([
4582
4597
  import_zod.z.number(),
@@ -4612,7 +4627,7 @@ var InputValidator = class {
4612
4627
  this.schemaCache.set(key, schema);
4613
4628
  return schema;
4614
4629
  }
4615
- makeWhereSchema(model, unique, withoutRelationFields = false) {
4630
+ makeWhereSchema(model, unique, withoutRelationFields = false, withAggregations = false) {
4616
4631
  const modelDef = getModel(this.schema, model);
4617
4632
  if (!modelDef) {
4618
4633
  throw new QueryError(`Model "${model}" not found in schema`);
@@ -4649,12 +4664,12 @@ var InputValidator = class {
4649
4664
  const enumDef = getEnum(this.schema, fieldDef.type);
4650
4665
  if (enumDef) {
4651
4666
  if (Object.keys(enumDef).length > 0) {
4652
- fieldSchema = this.makeEnumFilterSchema(enumDef, !!fieldDef.optional);
4667
+ fieldSchema = this.makeEnumFilterSchema(enumDef, !!fieldDef.optional, withAggregations);
4653
4668
  }
4654
4669
  } else if (fieldDef.array) {
4655
4670
  fieldSchema = this.makeArrayFilterSchema(fieldDef.type);
4656
4671
  } else {
4657
- fieldSchema = this.makePrimitiveFilterSchema(fieldDef.type, !!fieldDef.optional);
4672
+ fieldSchema = this.makePrimitiveFilterSchema(fieldDef.type, !!fieldDef.optional, withAggregations);
4658
4673
  }
4659
4674
  }
4660
4675
  if (fieldSchema) {
@@ -4671,12 +4686,12 @@ var InputValidator = class {
4671
4686
  const enumDef = getEnum(this.schema, def.type);
4672
4687
  if (enumDef) {
4673
4688
  if (Object.keys(enumDef).length > 0) {
4674
- fieldSchema = this.makeEnumFilterSchema(enumDef, !!def.optional);
4689
+ fieldSchema = this.makeEnumFilterSchema(enumDef, !!def.optional, false);
4675
4690
  } else {
4676
4691
  fieldSchema = import_zod.z.never();
4677
4692
  }
4678
4693
  } else {
4679
- fieldSchema = this.makePrimitiveFilterSchema(def.type, !!def.optional);
4694
+ fieldSchema = this.makePrimitiveFilterSchema(def.type, !!def.optional, false);
4680
4695
  }
4681
4696
  return [
4682
4697
  key,
@@ -4709,17 +4724,21 @@ var InputValidator = class {
4709
4724
  }
4710
4725
  return result;
4711
4726
  }
4712
- makeEnumFilterSchema(enumDef, optional) {
4727
+ makeEnumFilterSchema(enumDef, optional, withAggregations) {
4713
4728
  const baseSchema = import_zod.z.enum(Object.keys(enumDef));
4714
- const components = this.makeCommonPrimitiveFilterComponents(baseSchema, optional, () => import_zod.z.lazy(() => this.makeEnumFilterSchema(enumDef, optional)));
4729
+ const components = this.makeCommonPrimitiveFilterComponents(baseSchema, optional, () => import_zod.z.lazy(() => this.makeEnumFilterSchema(enumDef, optional, withAggregations)), [
4730
+ "equals",
4731
+ "in",
4732
+ "notIn",
4733
+ "not"
4734
+ ], withAggregations ? [
4735
+ "_count",
4736
+ "_min",
4737
+ "_max"
4738
+ ] : void 0);
4715
4739
  return import_zod.z.union([
4716
4740
  this.nullableIf(baseSchema, optional),
4717
- import_zod.z.strictObject({
4718
- equals: components.equals,
4719
- in: components.in,
4720
- notIn: components.notIn,
4721
- not: components.not
4722
- })
4741
+ import_zod.z.strictObject(components)
4723
4742
  ]);
4724
4743
  }
4725
4744
  makeArrayFilterSchema(type) {
@@ -4731,45 +4750,59 @@ var InputValidator = class {
4731
4750
  isEmpty: import_zod.z.boolean().optional()
4732
4751
  });
4733
4752
  }
4734
- makePrimitiveFilterSchema(type, optional) {
4753
+ makePrimitiveFilterSchema(type, optional, withAggregations) {
4735
4754
  if (this.schema.typeDefs && type in this.schema.typeDefs) {
4736
4755
  return this.makeTypeDefFilterSchema(type, optional);
4737
4756
  }
4738
- 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)).with("Json", () => import_zod.z.any()).with("Unsupported", () => import_zod.z.never()).exhaustive();
4757
+ 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();
4739
4758
  }
4740
4759
  makeTypeDefFilterSchema(_type, _optional) {
4741
4760
  return import_zod.z.never();
4742
4761
  }
4743
- makeDateTimeFilterSchema(optional) {
4762
+ makeDateTimeFilterSchema(optional, withAggregations) {
4744
4763
  return this.makeCommonPrimitiveFilterSchema(import_zod.z.union([
4745
- import_zod.z.string().datetime(),
4764
+ import_zod.z.iso.datetime(),
4746
4765
  import_zod.z.date()
4747
- ]), optional, () => import_zod.z.lazy(() => this.makeDateTimeFilterSchema(optional)));
4748
- }
4749
- makeBooleanFilterSchema(optional) {
4766
+ ]), optional, () => import_zod.z.lazy(() => this.makeDateTimeFilterSchema(optional, withAggregations)), withAggregations ? [
4767
+ "_count",
4768
+ "_min",
4769
+ "_max"
4770
+ ] : void 0);
4771
+ }
4772
+ makeBooleanFilterSchema(optional, withAggregations) {
4773
+ const components = this.makeCommonPrimitiveFilterComponents(import_zod.z.boolean(), optional, () => import_zod.z.lazy(() => this.makeBooleanFilterSchema(optional, withAggregations)), [
4774
+ "equals",
4775
+ "not"
4776
+ ], withAggregations ? [
4777
+ "_count",
4778
+ "_min",
4779
+ "_max"
4780
+ ] : void 0);
4750
4781
  return import_zod.z.union([
4751
4782
  this.nullableIf(import_zod.z.boolean(), optional),
4752
- import_zod.z.strictObject({
4753
- equals: this.nullableIf(import_zod.z.boolean(), optional).optional(),
4754
- not: import_zod.z.lazy(() => this.makeBooleanFilterSchema(optional)).optional()
4755
- })
4783
+ import_zod.z.strictObject(components)
4756
4784
  ]);
4757
4785
  }
4758
- makeBytesFilterSchema(optional) {
4786
+ makeBytesFilterSchema(optional, withAggregations) {
4759
4787
  const baseSchema = import_zod.z.instanceof(Uint8Array);
4760
- const components = this.makeCommonPrimitiveFilterComponents(baseSchema, optional, () => import_zod.z.instanceof(Uint8Array));
4788
+ const components = this.makeCommonPrimitiveFilterComponents(baseSchema, optional, () => import_zod.z.instanceof(Uint8Array), [
4789
+ "equals",
4790
+ "in",
4791
+ "notIn",
4792
+ "not"
4793
+ ], withAggregations ? [
4794
+ "_count",
4795
+ "_min",
4796
+ "_max"
4797
+ ] : void 0);
4761
4798
  return import_zod.z.union([
4762
4799
  this.nullableIf(baseSchema, optional),
4763
- import_zod.z.strictObject({
4764
- equals: components.equals,
4765
- in: components.in,
4766
- notIn: components.notIn,
4767
- not: components.not
4768
- })
4800
+ import_zod.z.strictObject(components)
4769
4801
  ]);
4770
4802
  }
4771
- makeCommonPrimitiveFilterComponents(baseSchema, optional, makeThis) {
4772
- return {
4803
+ makeCommonPrimitiveFilterComponents(baseSchema, optional, makeThis, supportedOperators = void 0, withAggregations = void 0) {
4804
+ const commonAggSchema = /* @__PURE__ */ __name(() => this.makeCommonPrimitiveFilterSchema(baseSchema, false, makeThis, void 0).optional(), "commonAggSchema");
4805
+ let result = {
4773
4806
  equals: this.nullableIf(baseSchema.optional(), optional),
4774
4807
  notEquals: this.nullableIf(baseSchema.optional(), optional),
4775
4808
  in: baseSchema.array().optional(),
@@ -4778,23 +4811,56 @@ var InputValidator = class {
4778
4811
  lte: baseSchema.optional(),
4779
4812
  gt: baseSchema.optional(),
4780
4813
  gte: baseSchema.optional(),
4781
- not: makeThis().optional()
4814
+ not: makeThis().optional(),
4815
+ ...withAggregations?.includes("_count") ? {
4816
+ _count: this.makeNumberFilterSchema(import_zod.z.int(), false, false).optional()
4817
+ } : {},
4818
+ ...withAggregations?.includes("_avg") ? {
4819
+ _avg: commonAggSchema()
4820
+ } : {},
4821
+ ...withAggregations?.includes("_sum") ? {
4822
+ _sum: commonAggSchema()
4823
+ } : {},
4824
+ ...withAggregations?.includes("_min") ? {
4825
+ _min: commonAggSchema()
4826
+ } : {},
4827
+ ...withAggregations?.includes("_max") ? {
4828
+ _max: commonAggSchema()
4829
+ } : {}
4782
4830
  };
4831
+ if (supportedOperators) {
4832
+ const keys = [
4833
+ ...supportedOperators,
4834
+ ...withAggregations ?? []
4835
+ ];
4836
+ result = extractFields(result, keys);
4837
+ }
4838
+ return result;
4783
4839
  }
4784
- makeCommonPrimitiveFilterSchema(baseSchema, optional, makeThis) {
4840
+ makeCommonPrimitiveFilterSchema(baseSchema, optional, makeThis, withAggregations = void 0) {
4785
4841
  return import_zod.z.union([
4786
4842
  this.nullableIf(baseSchema, optional),
4787
- import_zod.z.strictObject(this.makeCommonPrimitiveFilterComponents(baseSchema, optional, makeThis))
4843
+ import_zod.z.strictObject(this.makeCommonPrimitiveFilterComponents(baseSchema, optional, makeThis, void 0, withAggregations))
4788
4844
  ]);
4789
4845
  }
4790
- makeNumberFilterSchema(baseSchema, optional) {
4791
- return this.makeCommonPrimitiveFilterSchema(baseSchema, optional, () => import_zod.z.lazy(() => this.makeNumberFilterSchema(baseSchema, optional)));
4846
+ makeNumberFilterSchema(baseSchema, optional, withAggregations) {
4847
+ return this.makeCommonPrimitiveFilterSchema(baseSchema, optional, () => import_zod.z.lazy(() => this.makeNumberFilterSchema(baseSchema, optional, withAggregations)), withAggregations ? [
4848
+ "_count",
4849
+ "_avg",
4850
+ "_sum",
4851
+ "_min",
4852
+ "_max"
4853
+ ] : void 0);
4792
4854
  }
4793
- makeStringFilterSchema(optional) {
4855
+ makeStringFilterSchema(optional, withAggregations) {
4794
4856
  return import_zod.z.union([
4795
4857
  this.nullableIf(import_zod.z.string(), optional),
4796
4858
  import_zod.z.strictObject({
4797
- ...this.makeCommonPrimitiveFilterComponents(import_zod.z.string(), optional, () => import_zod.z.lazy(() => this.makeStringFilterSchema(optional))),
4859
+ ...this.makeCommonPrimitiveFilterComponents(import_zod.z.string(), optional, () => import_zod.z.lazy(() => this.makeStringFilterSchema(optional, withAggregations)), void 0, withAggregations ? [
4860
+ "_count",
4861
+ "_min",
4862
+ "_max"
4863
+ ] : void 0),
4798
4864
  startsWith: import_zod.z.string().optional(),
4799
4865
  endsWith: import_zod.z.string().optional(),
4800
4866
  contains: import_zod.z.string().optional(),
@@ -5152,7 +5218,7 @@ var InputValidator = class {
5152
5218
  return import_zod.z.object({
5153
5219
  where: this.makeWhereSchema(model, false).optional(),
5154
5220
  data: this.makeUpdateDataSchema(model, [], true),
5155
- limit: import_zod.z.number().int().nonnegative().optional()
5221
+ limit: import_zod.z.int().nonnegative().optional()
5156
5222
  });
5157
5223
  }
5158
5224
  makeUpdateManyAndReturnSchema(model) {
@@ -5259,7 +5325,7 @@ var InputValidator = class {
5259
5325
  makeDeleteManySchema(model) {
5260
5326
  return import_zod.z.object({
5261
5327
  where: this.makeWhereSchema(model, false).optional(),
5262
- limit: import_zod.z.number().int().nonnegative().optional()
5328
+ limit: import_zod.z.int().nonnegative().optional()
5263
5329
  }).optional();
5264
5330
  }
5265
5331
  // #endregion
@@ -5328,7 +5394,7 @@ var InputValidator = class {
5328
5394
  where: this.makeWhereSchema(model, false).optional(),
5329
5395
  orderBy: this.orArray(this.makeOrderBySchema(model, false, true), true).optional(),
5330
5396
  by: this.orArray(import_zod.z.enum(nonRelationFields), true),
5331
- having: this.makeWhereSchema(model, false, true).optional(),
5397
+ having: this.makeHavingSchema(model).optional(),
5332
5398
  skip: this.makeSkipSchema().optional(),
5333
5399
  take: this.makeTakeSchema().optional(),
5334
5400
  _count: this.makeCountAggregateInputSchema(model).optional(),
@@ -5341,17 +5407,29 @@ var InputValidator = class {
5341
5407
  const bys = typeof value.by === "string" ? [
5342
5408
  value.by
5343
5409
  ] : value.by;
5344
- if (value.having && Object.keys(value.having).filter((f) => !f.startsWith("_")).some((key) => !bys.includes(key))) {
5345
- return false;
5346
- } else {
5347
- return true;
5410
+ if (value.having && typeof value.having === "object") {
5411
+ for (const [key, val] of Object.entries(value.having)) {
5412
+ if (AGGREGATE_OPERATORS.includes(key)) {
5413
+ continue;
5414
+ }
5415
+ if (bys.includes(key)) {
5416
+ continue;
5417
+ }
5418
+ if (!val || typeof val !== "object") {
5419
+ return false;
5420
+ }
5421
+ if (!this.onlyAggregationFields(val)) {
5422
+ return false;
5423
+ }
5424
+ }
5348
5425
  }
5426
+ return true;
5349
5427
  }, 'fields in "having" must be in "by"');
5350
5428
  schema = schema.refine((value) => {
5351
5429
  const bys = typeof value.by === "string" ? [
5352
5430
  value.by
5353
5431
  ] : value.by;
5354
- if (value.orderBy && Object.keys(value.orderBy).filter((f) => !f.startsWith("_")).some((key) => !bys.includes(key))) {
5432
+ if (value.orderBy && Object.keys(value.orderBy).filter((f) => !AGGREGATE_OPERATORS.includes(f)).some((key) => !bys.includes(key))) {
5355
5433
  return false;
5356
5434
  } else {
5357
5435
  return true;
@@ -5359,13 +5437,30 @@ var InputValidator = class {
5359
5437
  }, 'fields in "orderBy" must be in "by"');
5360
5438
  return schema;
5361
5439
  }
5440
+ onlyAggregationFields(val) {
5441
+ for (const [key, value] of Object.entries(val)) {
5442
+ if (AGGREGATE_OPERATORS.includes(key)) {
5443
+ continue;
5444
+ }
5445
+ if (LOGICAL_COMBINATORS.includes(key)) {
5446
+ if (enumerate(value).every((v) => this.onlyAggregationFields(v))) {
5447
+ continue;
5448
+ }
5449
+ }
5450
+ return false;
5451
+ }
5452
+ return true;
5453
+ }
5454
+ makeHavingSchema(model) {
5455
+ return this.makeWhereSchema(model, false, true, true);
5456
+ }
5362
5457
  // #endregion
5363
5458
  // #region Helpers
5364
5459
  makeSkipSchema() {
5365
- return import_zod.z.number().int().nonnegative();
5460
+ return import_zod.z.int().nonnegative();
5366
5461
  }
5367
5462
  makeTakeSchema() {
5368
- return import_zod.z.number().int();
5463
+ return import_zod.z.int();
5369
5464
  }
5370
5465
  refineForSelectIncludeMutuallyExclusive(schema) {
5371
5466
  return schema.refine((value) => !(value["select"] && value["include"]), '"select" and "include" cannot be used together');
@@ -5573,7 +5668,7 @@ __name(performanceNow, "performanceNow");
5573
5668
  var import_kysely13 = require("kysely");
5574
5669
  var import_nanoid2 = require("nanoid");
5575
5670
  var import_node_util2 = require("util");
5576
- var import_ts_pattern15 = require("ts-pattern");
5671
+ var import_ts_pattern16 = require("ts-pattern");
5577
5672
 
5578
5673
  // src/client/executor/name-mapper.ts
5579
5674
  var import_kysely12 = require("kysely");
@@ -5921,7 +6016,7 @@ ${compiled.parameters.map((p) => (0, import_node_util2.inspect)(p)).join("\n")}`
5921
6016
  return this.client.$options.plugins?.some((plugin) => plugin.beforeEntityMutation || plugin.afterEntityMutation);
5922
6017
  }
5923
6018
  getMutationModel(queryNode) {
5924
- 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) => {
6019
+ 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) => {
5925
6020
  if (node.from.froms.length !== 1) {
5926
6021
  throw new InternalError(`Delete query must have exactly one from table`);
5927
6022
  }
@@ -5937,7 +6032,7 @@ ${compiled.parameters.map((p) => (0, import_node_util2.inspect)(p)).join("\n")}`
5937
6032
  const result = {
5938
6033
  intercept: false
5939
6034
  };
5940
- const { action, where } = (0, import_ts_pattern15.match)(queryNode).when(import_kysely13.InsertQueryNode.is, () => ({
6035
+ const { action, where } = (0, import_ts_pattern16.match)(queryNode).when(import_kysely13.InsertQueryNode.is, () => ({
5941
6036
  action: "create",
5942
6037
  where: void 0
5943
6038
  })).when(import_kysely13.UpdateQueryNode.is, (node) => ({
@@ -6077,7 +6172,7 @@ __export(functions_exports, {
6077
6172
  });
6078
6173
  var import_common_helpers10 = require("@zenstackhq/common-helpers");
6079
6174
  var import_kysely14 = require("kysely");
6080
- var import_ts_pattern16 = require("ts-pattern");
6175
+ var import_ts_pattern17 = require("ts-pattern");
6081
6176
  var contains = /* @__PURE__ */ __name((eb, args) => {
6082
6177
  const [field, search2, caseInsensitive = false] = args;
6083
6178
  if (!field) {
@@ -6162,7 +6257,7 @@ var isEmpty = /* @__PURE__ */ __name((eb, args, { dialect }) => {
6162
6257
  return eb(dialect.buildArrayLength(eb, field), "=", import_kysely14.sql.lit(0));
6163
6258
  }, "isEmpty");
6164
6259
  var now = /* @__PURE__ */ __name((eb, _args, { dialect }) => {
6165
- return (0, import_ts_pattern16.match)(dialect.provider).with("postgresql", () => eb.fn("now")).with("sqlite", () => import_kysely14.sql.raw("CURRENT_TIMESTAMP")).exhaustive();
6260
+ return (0, import_ts_pattern17.match)(dialect.provider).with("postgresql", () => eb.fn("now")).with("sqlite", () => import_kysely14.sql.raw("CURRENT_TIMESTAMP")).exhaustive();
6166
6261
  }, "now");
6167
6262
  var currentModel = /* @__PURE__ */ __name((_eb, args, { model }) => {
6168
6263
  let result = model;
@@ -6183,7 +6278,7 @@ var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
6183
6278
  function processCasing(casing, result, model) {
6184
6279
  const opNode = casing.toOperationNode();
6185
6280
  (0, import_common_helpers10.invariant)(import_kysely14.ValueNode.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
6186
- result = (0, import_ts_pattern16.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(() => {
6281
+ 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(() => {
6187
6282
  throw new Error(`Invalid casing value: ${opNode.value}. Must be "original", "upper", "lower", "capitalize", or "uncapitalize".`);
6188
6283
  });
6189
6284
  return result;
@@ -6193,7 +6288,7 @@ __name(processCasing, "processCasing");
6193
6288
  // src/client/helpers/schema-db-pusher.ts
6194
6289
  var import_common_helpers11 = require("@zenstackhq/common-helpers");
6195
6290
  var import_kysely15 = require("kysely");
6196
- var import_ts_pattern17 = require("ts-pattern");
6291
+ var import_ts_pattern18 = require("ts-pattern");
6197
6292
  var SchemaDbPusher = class {
6198
6293
  static {
6199
6294
  __name(this, "SchemaDbPusher");
@@ -6297,7 +6392,7 @@ var SchemaDbPusher = class {
6297
6392
  return "serial";
6298
6393
  }
6299
6394
  const type = fieldDef.type;
6300
- 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").with("Json", () => "jsonb").otherwise(() => {
6395
+ 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(() => {
6301
6396
  throw new Error(`Unsupported field type: ${type}`);
6302
6397
  });
6303
6398
  if (fieldDef.array) {
@@ -6326,7 +6421,7 @@ var SchemaDbPusher = class {
6326
6421
  return table;
6327
6422
  }
6328
6423
  mapCascadeAction(action) {
6329
- 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();
6424
+ 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();
6330
6425
  }
6331
6426
  };
6332
6427
 
@@ -6367,7 +6462,7 @@ __name(valueToPromise, "valueToPromise");
6367
6462
  // src/client/result-processor.ts
6368
6463
  var import_common_helpers12 = require("@zenstackhq/common-helpers");
6369
6464
  var import_decimal2 = __toESM(require("decimal.js"), 1);
6370
- var import_ts_pattern18 = require("ts-pattern");
6465
+ var import_ts_pattern19 = require("ts-pattern");
6371
6466
  var ResultProcessor = class {
6372
6467
  static {
6373
6468
  __name(this, "ResultProcessor");
@@ -6458,7 +6553,7 @@ var ResultProcessor = class {
6458
6553
  if (this.schema.typeDefs && type in this.schema.typeDefs) {
6459
6554
  return this.transformJson(value);
6460
6555
  } else {
6461
- 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)).with("Json", () => this.transformJson(value)).otherwise(() => value);
6556
+ 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);
6462
6557
  }
6463
6558
  }
6464
6559
  transformDecimal(value) {
@@ -6515,7 +6610,7 @@ var ResultProcessor = class {
6515
6610
  }
6516
6611
  }
6517
6612
  transformJson(value) {
6518
- return (0, import_ts_pattern18.match)(this.schema.provider.type).with("sqlite", () => {
6613
+ return (0, import_ts_pattern19.match)(this.schema.provider.type).with("sqlite", () => {
6519
6614
  (0, import_common_helpers12.invariant)(typeof value === "string", "Expected string, got " + typeof value);
6520
6615
  return JSON.parse(value);
6521
6616
  }).otherwise(() => value);
@@ -6852,7 +6947,7 @@ function createModelCrudHandler(client, model, inputValidator, resultProcessor)
6852
6947
  return createPromise("aggregate", args, new AggregateOperationHandler(client, model, inputValidator), false);
6853
6948
  }, "aggregate"),
6854
6949
  groupBy: /* @__PURE__ */ __name((args) => {
6855
- return createPromise("groupBy", args, new GroupByOperationHandler(client, model, inputValidator));
6950
+ return createPromise("groupBy", args, new GroupByOperationHandler(client, model, inputValidator), true);
6856
6951
  }, "groupBy")
6857
6952
  };
6858
6953
  }