@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.js CHANGED
@@ -11,7 +11,10 @@ import { CompiledQuery, DefaultConnectionProvider, DefaultQueryExecutor as Defau
11
11
 
12
12
  // src/client/crud/operations/aggregate.ts
13
13
  import { sql as sql5 } from "kysely";
14
- import { match as match9 } from "ts-pattern";
14
+ import { match as match10 } from "ts-pattern";
15
+
16
+ // src/client/query-utils.ts
17
+ import { match } from "ts-pattern";
15
18
 
16
19
  // src/schema/expression.ts
17
20
  var ExpressionUtils = {
@@ -92,6 +95,19 @@ var ExpressionUtils = {
92
95
  isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
93
96
  };
94
97
 
98
+ // src/utils/object-utils.ts
99
+ function extractFields(obj, fields) {
100
+ return Object.fromEntries(Object.entries(obj).filter(([key]) => fields.includes(key)));
101
+ }
102
+ __name(extractFields, "extractFields");
103
+ function fieldsToSelectObject(fields) {
104
+ return Object.fromEntries(fields.map((f) => [
105
+ f,
106
+ true
107
+ ]));
108
+ }
109
+ __name(fieldsToSelectObject, "fieldsToSelectObject");
110
+
95
111
  // src/client/errors.ts
96
112
  var InputValidationError = class extends Error {
97
113
  static {
@@ -370,15 +386,6 @@ function safeJSONStringify(value) {
370
386
  });
371
387
  }
372
388
  __name(safeJSONStringify, "safeJSONStringify");
373
- function extractFields(object, fields) {
374
- return fields.reduce((acc, field) => {
375
- if (field in object) {
376
- acc[field] = object[field];
377
- }
378
- return acc;
379
- }, {});
380
- }
381
- __name(extractFields, "extractFields");
382
389
  function extractIdFields(entity, schema, model) {
383
390
  const idFields = getIdFields(schema, model);
384
391
  return extractFields(entity, idFields);
@@ -410,6 +417,10 @@ function getDelegateDescendantModels(schema, model, collected = /* @__PURE__ */
410
417
  ];
411
418
  }
412
419
  __name(getDelegateDescendantModels, "getDelegateDescendantModels");
420
+ function aggregate(eb, expr2, op) {
421
+ return 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();
422
+ }
423
+ __name(aggregate, "aggregate");
413
424
 
414
425
  // src/client/crud/operations/base.ts
415
426
  import { createId } from "@paralleldrive/cuid2";
@@ -417,7 +428,7 @@ import { invariant as invariant7, isPlainObject as isPlainObject3 } from "@zenst
417
428
  import { expressionBuilder as expressionBuilder2, sql as sql4 } from "kysely";
418
429
  import { nanoid } from "nanoid";
419
430
  import { inspect } from "util";
420
- import { match as match8 } from "ts-pattern";
431
+ import { match as match9 } from "ts-pattern";
421
432
  import { ulid } from "ulid";
422
433
  import * as uuid from "uuid";
423
434
 
@@ -436,15 +447,15 @@ var RejectedByPolicyError = class extends Error {
436
447
  // src/plugins/policy/policy-handler.ts
437
448
  import { invariant as invariant6 } from "@zenstackhq/common-helpers";
438
449
  import { AliasNode as AliasNode3, BinaryOperationNode as BinaryOperationNode3, ColumnNode as ColumnNode2, DeleteQueryNode, FromNode as FromNode2, IdentifierNode as IdentifierNode2, InsertQueryNode, OperationNodeTransformer, OperatorNode as OperatorNode3, PrimitiveValueListNode, RawNode, ReturningNode, SelectionNode as SelectionNode2, SelectQueryNode as SelectQueryNode2, TableNode as TableNode3, UpdateQueryNode, ValueNode as ValueNode3, ValuesNode, WhereNode as WhereNode2 } from "kysely";
439
- import { match as match7 } from "ts-pattern";
450
+ import { match as match8 } from "ts-pattern";
440
451
 
441
452
  // src/client/crud/dialects/index.ts
442
- import { match as match4 } from "ts-pattern";
453
+ import { match as match5 } from "ts-pattern";
443
454
 
444
455
  // src/client/crud/dialects/postgresql.ts
445
456
  import { invariant as invariant2 } from "@zenstackhq/common-helpers";
446
457
  import { sql as sql2 } from "kysely";
447
- import { match as match2 } from "ts-pattern";
458
+ import { match as match3 } from "ts-pattern";
448
459
 
449
460
  // src/client/constants.ts
450
461
  var CONTEXT_COMMENT_PREFIX = "-- $$context:";
@@ -455,11 +466,23 @@ var NUMERIC_FIELD_TYPES = [
455
466
  "Decimal"
456
467
  ];
457
468
  var DELEGATE_JOINED_FIELD_PREFIX = "$delegate$";
469
+ var LOGICAL_COMBINATORS = [
470
+ "AND",
471
+ "OR",
472
+ "NOT"
473
+ ];
474
+ var AGGREGATE_OPERATORS = [
475
+ "_count",
476
+ "_sum",
477
+ "_avg",
478
+ "_min",
479
+ "_max"
480
+ ];
458
481
 
459
482
  // src/client/crud/dialects/base.ts
460
483
  import { invariant, isPlainObject } from "@zenstackhq/common-helpers";
461
484
  import { sql } from "kysely";
462
- import { match, P } from "ts-pattern";
485
+ import { match as match2, P } from "ts-pattern";
463
486
 
464
487
  // src/utils/enumerate.ts
465
488
  function enumerate(x) {
@@ -516,7 +539,7 @@ var BaseCrudDialect = class {
516
539
  if (key.startsWith("$")) {
517
540
  continue;
518
541
  }
519
- if (key === "AND" || key === "OR" || key === "NOT") {
542
+ if (this.isLogicalCombinator(key)) {
520
543
  result = this.and(eb, result, this.buildCompositeFilter(eb, model, modelAlias, key, payload));
521
544
  continue;
522
545
  }
@@ -537,8 +560,11 @@ var BaseCrudDialect = class {
537
560
  }
538
561
  return result;
539
562
  }
563
+ isLogicalCombinator(key) {
564
+ return LOGICAL_COMBINATORS.includes(key);
565
+ }
540
566
  buildCompositeFilter(eb, model, modelAlias, key, payload) {
541
- return 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();
567
+ return match2(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();
542
568
  }
543
569
  buildRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
544
570
  if (!fieldDef.array) {
@@ -687,7 +713,7 @@ var BaseCrudDialect = class {
687
713
  if (isEnum(this.schema, fieldDef.type)) {
688
714
  return this.buildEnumFilter(eb, fieldRef, fieldDef, payload);
689
715
  }
690
- return match(fieldDef.type).with("String", () => this.buildStringFilter(eb, fieldRef, payload)).with(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", () => {
716
+ return match2(fieldDef.type).with("String", () => this.buildStringFilter(eb, fieldRef, payload)).with(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", () => {
691
717
  throw new InternalError("JSON filters are not supported yet");
692
718
  }).with("Unsupported", () => {
693
719
  throw new QueryError(`Unsupported field cannot be used in filters`);
@@ -715,7 +741,7 @@ var BaseCrudDialect = class {
715
741
  continue;
716
742
  }
717
743
  const rhs = Array.isArray(value) ? value.map(getRhs) : getRhs(value);
718
- const condition = match(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
744
+ const condition = match2(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
719
745
  invariant(Array.isArray(rhs), "right hand side must be an array");
720
746
  if (rhs.length === 0) {
721
747
  return this.false(eb);
@@ -729,7 +755,11 @@ var BaseCrudDialect = class {
729
755
  } else {
730
756
  return eb.not(eb(lhs, "in", rhs));
731
757
  }
732
- }).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(() => {
758
+ }).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(P.union(...AGGREGATE_OPERATORS), (op2) => {
759
+ const innerResult = this.buildStandardFilter(eb, type, value, aggregate(eb, lhs, op2), getRhs, recurse, throwIfInvalid);
760
+ consumedKeys.push(...innerResult.consumedKeys);
761
+ return this.and(eb, ...innerResult.conditions);
762
+ }).otherwise(() => {
733
763
  if (throwIfInvalid) {
734
764
  throw new QueryError(`Invalid filter key: ${op}`);
735
765
  } else {
@@ -759,7 +789,7 @@ var BaseCrudDialect = class {
759
789
  if (key === "mode" || consumedKeys.includes(key)) {
760
790
  continue;
761
791
  }
762
- const condition = match(key).with("contains", () => mode === "insensitive" ? eb(fieldRef, "ilike", sql.val(`%${value}%`)) : eb(fieldRef, "like", sql.val(`%${value}%`))).with("startsWith", () => mode === "insensitive" ? eb(fieldRef, "ilike", sql.val(`${value}%`)) : eb(fieldRef, "like", sql.val(`${value}%`))).with("endsWith", () => mode === "insensitive" ? eb(fieldRef, "ilike", sql.val(`%${value}`)) : eb(fieldRef, "like", sql.val(`%${value}`))).otherwise(() => {
792
+ const condition = match2(key).with("contains", () => mode === "insensitive" ? eb(fieldRef, "ilike", sql.val(`%${value}%`)) : eb(fieldRef, "like", sql.val(`%${value}%`))).with("startsWith", () => mode === "insensitive" ? eb(fieldRef, "ilike", sql.val(`${value}%`)) : eb(fieldRef, "like", sql.val(`${value}%`))).with("endsWith", () => mode === "insensitive" ? eb(fieldRef, "ilike", sql.val(`%${value}`)) : eb(fieldRef, "like", sql.val(`%${value}`))).otherwise(() => {
763
793
  throw new QueryError(`Invalid string filter key: ${key}`);
764
794
  });
765
795
  if (condition) {
@@ -840,9 +870,7 @@ var BaseCrudDialect = class {
840
870
  invariant(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
841
871
  for (const [k, v] of Object.entries(value)) {
842
872
  invariant(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
843
- result = result.orderBy((eb) => eb.fn(field.slice(1), [
844
- sql.ref(k)
845
- ]), sql.raw(this.negateSort(v, negated)));
873
+ result = result.orderBy((eb) => aggregate(eb, sql.ref(`${modelAlias}.${k}`), field), sql.raw(this.negateSort(v, negated)));
846
874
  }
847
875
  continue;
848
876
  }
@@ -1037,7 +1065,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1037
1065
  return value.map((v) => this.transformPrimitive(v, type, false));
1038
1066
  }
1039
1067
  } else {
1040
- return match2(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).with("Decimal", () => value !== null ? value.toString() : value).otherwise(() => value);
1068
+ return match3(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).with("Decimal", () => value !== null ? value.toString() : value).otherwise(() => value);
1041
1069
  }
1042
1070
  }
1043
1071
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
@@ -1194,7 +1222,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1194
1222
  // src/client/crud/dialects/sqlite.ts
1195
1223
  import { invariant as invariant3 } from "@zenstackhq/common-helpers";
1196
1224
  import { sql as sql3 } from "kysely";
1197
- import { match as match3 } from "ts-pattern";
1225
+ import { match as match4 } from "ts-pattern";
1198
1226
  var SqliteCrudDialect = class extends BaseCrudDialect {
1199
1227
  static {
1200
1228
  __name(this, "SqliteCrudDialect");
@@ -1212,7 +1240,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1212
1240
  if (this.schema.typeDefs && type in this.schema.typeDefs) {
1213
1241
  return JSON.stringify(value);
1214
1242
  } else {
1215
- return match3(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);
1243
+ return match4(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);
1216
1244
  }
1217
1245
  }
1218
1246
  }
@@ -1358,7 +1386,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1358
1386
 
1359
1387
  // src/client/crud/dialects/index.ts
1360
1388
  function getCrudDialect(schema, options) {
1361
- return match4(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
1389
+ return match5(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
1362
1390
  }
1363
1391
  __name(getCrudDialect, "getCrudDialect");
1364
1392
 
@@ -1683,17 +1711,17 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
1683
1711
  // src/plugins/policy/expression-transformer.ts
1684
1712
  import { invariant as invariant5 } from "@zenstackhq/common-helpers";
1685
1713
  import { AliasNode as AliasNode2, BinaryOperationNode as BinaryOperationNode2, ColumnNode, expressionBuilder, FromNode, FunctionNode as FunctionNode2, IdentifierNode, OperatorNode as OperatorNode2, ReferenceNode as ReferenceNode2, SelectionNode, SelectQueryNode, TableNode as TableNode2, ValueListNode, ValueNode as ValueNode2, WhereNode } from "kysely";
1686
- import { match as match6 } from "ts-pattern";
1714
+ import { match as match7 } from "ts-pattern";
1687
1715
 
1688
1716
  // src/plugins/policy/expression-evaluator.ts
1689
1717
  import { invariant as invariant4 } from "@zenstackhq/common-helpers";
1690
- import { match as match5 } from "ts-pattern";
1718
+ import { match as match6 } from "ts-pattern";
1691
1719
  var ExpressionEvaluator = class {
1692
1720
  static {
1693
1721
  __name(this, "ExpressionEvaluator");
1694
1722
  }
1695
1723
  evaluate(expression, context) {
1696
- const result = match5(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();
1724
+ const result = match6(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();
1697
1725
  return result ?? null;
1698
1726
  }
1699
1727
  evaluateCall(expr2, context) {
@@ -1704,7 +1732,7 @@ var ExpressionEvaluator = class {
1704
1732
  }
1705
1733
  }
1706
1734
  evaluateUnary(expr2, context) {
1707
- return match5(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1735
+ return match6(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1708
1736
  }
1709
1737
  evaluateMember(expr2, context) {
1710
1738
  let val = this.evaluate(expr2.receiver, context);
@@ -1728,7 +1756,7 @@ var ExpressionEvaluator = class {
1728
1756
  }
1729
1757
  const left = this.evaluate(expr2.left, context);
1730
1758
  const right = this.evaluate(expr2.right, context);
1731
- return match5(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", () => {
1759
+ return match6(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", () => {
1732
1760
  const _right = right ?? [];
1733
1761
  invariant4(Array.isArray(_right), 'expected array for "in" operator');
1734
1762
  return _right.includes(left);
@@ -1742,7 +1770,7 @@ var ExpressionEvaluator = class {
1742
1770
  return false;
1743
1771
  }
1744
1772
  invariant4(Array.isArray(left), "expected array");
1745
- return match5(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1773
+ return match6(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1746
1774
  ...context,
1747
1775
  thisValue: item
1748
1776
  }))).with("!", () => left.every((item) => this.evaluate(expr2.right, {
@@ -1996,7 +2024,7 @@ var ExpressionTransformer = class {
1996
2024
  const count = FunctionNode2.create("count", [
1997
2025
  ValueNode2.createImmediate(1)
1998
2026
  ]);
1999
- const predicateResult = match6(expr2.op).with("?", () => BinaryOperationNode2.create(count, OperatorNode2.create(">"), ValueNode2.createImmediate(0))).with("!", () => BinaryOperationNode2.create(count, OperatorNode2.create("="), ValueNode2.createImmediate(0))).with("^", () => BinaryOperationNode2.create(count, OperatorNode2.create("="), ValueNode2.createImmediate(0))).exhaustive();
2027
+ const predicateResult = match7(expr2.op).with("?", () => BinaryOperationNode2.create(count, OperatorNode2.create(">"), ValueNode2.createImmediate(0))).with("!", () => BinaryOperationNode2.create(count, OperatorNode2.create("="), ValueNode2.createImmediate(0))).with("^", () => BinaryOperationNode2.create(count, OperatorNode2.create("="), ValueNode2.createImmediate(0))).exhaustive();
2000
2028
  return this.transform(expr2.left, {
2001
2029
  ...context,
2002
2030
  memberSelect: SelectionNode.create(AliasNode2.create(predicateResult, IdentifierNode.create("$t"))),
@@ -2027,7 +2055,7 @@ var ExpressionTransformer = class {
2027
2055
  return BinaryOperationNode2.create(this.transform(expr2.operand, context), this.transformOperator("!="), trueNode(this.dialect));
2028
2056
  }
2029
2057
  transformOperator(op) {
2030
- const mappedOp = match6(op).with("==", () => "=").otherwise(() => op);
2058
+ const mappedOp = match7(op).with("==", () => "=").otherwise(() => op);
2031
2059
  return OperatorNode2.create(mappedOp);
2032
2060
  }
2033
2061
  _call(expr2, context) {
@@ -2430,7 +2458,7 @@ var PolicyHandler = class extends OperationNodeTransformer {
2430
2458
  return disjunction(this.dialect, rows.map((row) => conjunction(this.dialect, idFields.map((field) => BinaryOperationNode3.create(ColumnNode2.create(field), OperatorNode3.create("="), ValueNode3.create(row[field]))))));
2431
2459
  }
2432
2460
  getMutationModel(node) {
2433
- const r = match7(node).when(InsertQueryNode.is, (node2) => getTableName(node2.into)).when(UpdateQueryNode.is, (node2) => getTableName(node2.table)).when(DeleteQueryNode.is, (node2) => {
2461
+ const r = match8(node).when(InsertQueryNode.is, (node2) => getTableName(node2.into)).when(UpdateQueryNode.is, (node2) => getTableName(node2.table)).when(DeleteQueryNode.is, (node2) => {
2434
2462
  if (node2.from.froms.length !== 1) {
2435
2463
  throw new InternalError("Only one from table is supported for delete");
2436
2464
  }
@@ -2627,19 +2655,6 @@ function clone(value) {
2627
2655
  }
2628
2656
  __name(clone, "clone");
2629
2657
 
2630
- // src/utils/object-utils.ts
2631
- function extractFields2(obj, fields) {
2632
- return Object.fromEntries(Object.entries(obj).filter(([key]) => fields.includes(key)));
2633
- }
2634
- __name(extractFields2, "extractFields");
2635
- function fieldsToSelectObject(fields) {
2636
- return Object.fromEntries(fields.map((f) => [
2637
- f,
2638
- true
2639
- ]));
2640
- }
2641
- __name(fieldsToSelectObject, "fieldsToSelectObject");
2642
-
2643
2658
  // src/client/crud/operations/base.ts
2644
2659
  var BaseOperationHandler = class {
2645
2660
  static {
@@ -2996,7 +3011,7 @@ ${compiled.parameters.map((p) => inspect(p)).join("\n")}`;
2996
3011
  case "connect": {
2997
3012
  const referencedPkFields = relationField.relation.references;
2998
3013
  invariant7(referencedPkFields, "relation must have fields info");
2999
- const extractedFks = extractFields2(subPayload, referencedPkFields);
3014
+ const extractedFks = extractFields(subPayload, referencedPkFields);
3000
3015
  if (Object.keys(extractedFks).length === referencedPkFields.length) {
3001
3016
  result = extractedFks;
3002
3017
  } else {
@@ -3205,7 +3220,7 @@ ${compiled.parameters.map((p) => inspect(p)).join("\n")}`;
3205
3220
  }
3206
3221
  evalGenerator(defaultValue) {
3207
3222
  if (ExpressionUtils.isCall(defaultValue)) {
3208
- return match8(defaultValue.function).with("cuid", () => 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" ? nanoid(defaultValue.args[0].value) : nanoid()).with("ulid", () => ulid()).otherwise(() => void 0);
3223
+ return match9(defaultValue.function).with("cuid", () => 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" ? nanoid(defaultValue.args[0].value) : nanoid()).with("ulid", () => ulid()).otherwise(() => void 0);
3209
3224
  } else if (ExpressionUtils.isMember(defaultValue) && ExpressionUtils.isCall(defaultValue.receiver) && defaultValue.receiver.function === "auth") {
3210
3225
  let val = this.client.$auth;
3211
3226
  for (const member of defaultValue.members) {
@@ -3387,7 +3402,7 @@ ${compiled.parameters.map((p) => inspect(p)).join("\n")}`;
3387
3402
  const value = this.dialect.transformPrimitive(payload[key], fieldDef.type, false);
3388
3403
  const eb = expressionBuilder2();
3389
3404
  const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb);
3390
- return match8(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(() => {
3405
+ return match9(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(() => {
3391
3406
  throw new InternalError(`Invalid incremental update operation: ${key}`);
3392
3407
  });
3393
3408
  }
@@ -3397,7 +3412,7 @@ ${compiled.parameters.map((p) => inspect(p)).join("\n")}`;
3397
3412
  const value = this.dialect.transformPrimitive(payload[key], fieldDef.type, true);
3398
3413
  const eb = expressionBuilder2();
3399
3414
  const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb);
3400
- return match8(key).with("set", () => value).with("push", () => {
3415
+ return match9(key).with("set", () => value).with("push", () => {
3401
3416
  return eb(fieldRef, "||", eb.val(ensureArray(value)));
3402
3417
  }).otherwise(() => {
3403
3418
  throw new InternalError(`Invalid array update operation: ${key}`);
@@ -4060,7 +4075,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
4060
4075
  Object.entries(value).forEach(([field, val]) => {
4061
4076
  if (val === true) {
4062
4077
  query = query.select((eb) => {
4063
- const fn = match9(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
4078
+ const fn = match10(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
4064
4079
  return fn(sql5.ref(`$sub.${field}`)).as(`${key}.${field}`);
4065
4080
  });
4066
4081
  }
@@ -4093,7 +4108,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
4093
4108
  val = parseFloat(val);
4094
4109
  } else {
4095
4110
  if (op === "_sum" || op === "_min" || op === "_max") {
4096
- val = match9(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
4111
+ val = match10(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
4097
4112
  }
4098
4113
  }
4099
4114
  }
@@ -4144,14 +4159,14 @@ var CountOperationHandler = class extends BaseOperationHandler {
4144
4159
  };
4145
4160
 
4146
4161
  // src/client/crud/operations/create.ts
4147
- import { match as match10 } from "ts-pattern";
4162
+ import { match as match11 } from "ts-pattern";
4148
4163
  var CreateOperationHandler = class extends BaseOperationHandler {
4149
4164
  static {
4150
4165
  __name(this, "CreateOperationHandler");
4151
4166
  }
4152
4167
  async handle(operation, args) {
4153
4168
  const normalizedArgs = this.normalizeArgs(args);
4154
- return match10(operation).with("create", () => this.runCreate(this.inputValidator.validateCreateArgs(this.model, normalizedArgs))).with("createMany", () => {
4169
+ return match11(operation).with("create", () => this.runCreate(this.inputValidator.validateCreateArgs(this.model, normalizedArgs))).with("createMany", () => {
4155
4170
  return this.runCreateMany(this.inputValidator.validateCreateManyArgs(this.model, normalizedArgs));
4156
4171
  }).with("createManyAndReturn", () => {
4157
4172
  return this.runCreateManyAndReturn(this.inputValidator.validateCreateManyAndReturnArgs(this.model, normalizedArgs));
@@ -4198,14 +4213,14 @@ var CreateOperationHandler = class extends BaseOperationHandler {
4198
4213
  };
4199
4214
 
4200
4215
  // src/client/crud/operations/delete.ts
4201
- import { match as match11 } from "ts-pattern";
4216
+ import { match as match12 } from "ts-pattern";
4202
4217
  var DeleteOperationHandler = class extends BaseOperationHandler {
4203
4218
  static {
4204
4219
  __name(this, "DeleteOperationHandler");
4205
4220
  }
4206
4221
  async handle(operation, args) {
4207
4222
  const normalizedArgs = this.normalizeArgs(args);
4208
- return match11(operation).with("delete", () => this.runDelete(this.inputValidator.validateDeleteArgs(this.model, normalizedArgs))).with("deleteMany", () => this.runDeleteMany(this.inputValidator.validateDeleteManyArgs(this.model, normalizedArgs))).exhaustive();
4223
+ return match12(operation).with("delete", () => this.runDelete(this.inputValidator.validateDeleteArgs(this.model, normalizedArgs))).with("deleteMany", () => this.runDeleteMany(this.inputValidator.validateDeleteManyArgs(this.model, normalizedArgs))).exhaustive();
4209
4224
  }
4210
4225
  async runDelete(args) {
4211
4226
  const existing = await this.readUnique(this.kysely, this.model, {
@@ -4249,7 +4264,7 @@ var FindOperationHandler = class extends BaseOperationHandler {
4249
4264
 
4250
4265
  // src/client/crud/operations/group-by.ts
4251
4266
  import { sql as sql7 } from "kysely";
4252
- import { match as match12 } from "ts-pattern";
4267
+ import { match as match13 } from "ts-pattern";
4253
4268
  var GroupByOperationHandler = class extends BaseOperationHandler {
4254
4269
  static {
4255
4270
  __name(this, "GroupByOperationHandler");
@@ -4273,12 +4288,12 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
4273
4288
  const bys = typeof parsedArgs.by === "string" ? [
4274
4289
  parsedArgs.by
4275
4290
  ] : parsedArgs.by;
4276
- query = query.groupBy(bys);
4291
+ query = query.groupBy(bys.map((by) => sql7.ref(`$sub.${by}`)));
4277
4292
  if (parsedArgs.orderBy) {
4278
4293
  query = this.dialect.buildOrderBy(query, this.model, "$sub", parsedArgs.orderBy, false, false);
4279
4294
  }
4280
4295
  if (parsedArgs.having) {
4281
- query = query.having((eb1) => this.dialect.buildFilter(eb1, this.model, "$sub", parsedArgs.having));
4296
+ query = query.having((eb) => this.dialect.buildFilter(eb, this.model, "$sub", parsedArgs.having));
4282
4297
  }
4283
4298
  for (const by of bys) {
4284
4299
  query = query.select(() => sql7.ref(`$sub.${by}`).as(by));
@@ -4308,7 +4323,7 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
4308
4323
  Object.entries(value).forEach(([field, val]) => {
4309
4324
  if (val === true) {
4310
4325
  query = query.select((eb) => {
4311
- const fn = match12(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
4326
+ const fn = match13(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
4312
4327
  return fn(sql7.ref(`$sub.${field}`)).as(`${key}.${field}`);
4313
4328
  });
4314
4329
  }
@@ -4345,7 +4360,7 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
4345
4360
  val = parseFloat(val);
4346
4361
  } else {
4347
4362
  if (op === "_sum" || op === "_min" || op === "_max") {
4348
- val = match12(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
4363
+ val = match13(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
4349
4364
  }
4350
4365
  }
4351
4366
  }
@@ -4360,14 +4375,14 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
4360
4375
  };
4361
4376
 
4362
4377
  // src/client/crud/operations/update.ts
4363
- import { match as match13 } from "ts-pattern";
4378
+ import { match as match14 } from "ts-pattern";
4364
4379
  var UpdateOperationHandler = class extends BaseOperationHandler {
4365
4380
  static {
4366
4381
  __name(this, "UpdateOperationHandler");
4367
4382
  }
4368
4383
  async handle(operation, args) {
4369
4384
  const normalizedArgs = this.normalizeArgs(args);
4370
- return match13(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();
4385
+ return match14(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();
4371
4386
  }
4372
4387
  async runUpdate(args) {
4373
4388
  const readBackResult = await this.safeTransaction(async (tx) => {
@@ -4439,7 +4454,7 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4439
4454
  import { invariant as invariant8 } from "@zenstackhq/common-helpers";
4440
4455
  import Decimal from "decimal.js";
4441
4456
  import stableStringify from "json-stable-stringify";
4442
- import { match as match14, P as P2 } from "ts-pattern";
4457
+ import { match as match15, P as P2 } from "ts-pattern";
4443
4458
  import { z } from "zod";
4444
4459
  var InputValidator = class {
4445
4460
  static {
@@ -4540,8 +4555,8 @@ var InputValidator = class {
4540
4555
  if (this.schema.typeDefs && type in this.schema.typeDefs) {
4541
4556
  return this.makeTypeDefSchema(type);
4542
4557
  } else {
4543
- return match14(type).with("String", () => z.string()).with("Int", () => z.number()).with("Float", () => z.number()).with("Boolean", () => z.boolean()).with("BigInt", () => z.union([
4544
- z.number(),
4558
+ return match15(type).with("String", () => z.string()).with("Int", () => z.int()).with("Float", () => z.number()).with("Boolean", () => z.boolean()).with("BigInt", () => z.union([
4559
+ z.int(),
4545
4560
  z.bigint()
4546
4561
  ])).with("Decimal", () => z.union([
4547
4562
  z.number(),
@@ -4577,7 +4592,7 @@ var InputValidator = class {
4577
4592
  this.schemaCache.set(key, schema);
4578
4593
  return schema;
4579
4594
  }
4580
- makeWhereSchema(model, unique, withoutRelationFields = false) {
4595
+ makeWhereSchema(model, unique, withoutRelationFields = false, withAggregations = false) {
4581
4596
  const modelDef = getModel(this.schema, model);
4582
4597
  if (!modelDef) {
4583
4598
  throw new QueryError(`Model "${model}" not found in schema`);
@@ -4614,12 +4629,12 @@ var InputValidator = class {
4614
4629
  const enumDef = getEnum(this.schema, fieldDef.type);
4615
4630
  if (enumDef) {
4616
4631
  if (Object.keys(enumDef).length > 0) {
4617
- fieldSchema = this.makeEnumFilterSchema(enumDef, !!fieldDef.optional);
4632
+ fieldSchema = this.makeEnumFilterSchema(enumDef, !!fieldDef.optional, withAggregations);
4618
4633
  }
4619
4634
  } else if (fieldDef.array) {
4620
4635
  fieldSchema = this.makeArrayFilterSchema(fieldDef.type);
4621
4636
  } else {
4622
- fieldSchema = this.makePrimitiveFilterSchema(fieldDef.type, !!fieldDef.optional);
4637
+ fieldSchema = this.makePrimitiveFilterSchema(fieldDef.type, !!fieldDef.optional, withAggregations);
4623
4638
  }
4624
4639
  }
4625
4640
  if (fieldSchema) {
@@ -4636,12 +4651,12 @@ var InputValidator = class {
4636
4651
  const enumDef = getEnum(this.schema, def.type);
4637
4652
  if (enumDef) {
4638
4653
  if (Object.keys(enumDef).length > 0) {
4639
- fieldSchema = this.makeEnumFilterSchema(enumDef, !!def.optional);
4654
+ fieldSchema = this.makeEnumFilterSchema(enumDef, !!def.optional, false);
4640
4655
  } else {
4641
4656
  fieldSchema = z.never();
4642
4657
  }
4643
4658
  } else {
4644
- fieldSchema = this.makePrimitiveFilterSchema(def.type, !!def.optional);
4659
+ fieldSchema = this.makePrimitiveFilterSchema(def.type, !!def.optional, false);
4645
4660
  }
4646
4661
  return [
4647
4662
  key,
@@ -4674,17 +4689,21 @@ var InputValidator = class {
4674
4689
  }
4675
4690
  return result;
4676
4691
  }
4677
- makeEnumFilterSchema(enumDef, optional) {
4692
+ makeEnumFilterSchema(enumDef, optional, withAggregations) {
4678
4693
  const baseSchema = z.enum(Object.keys(enumDef));
4679
- const components = this.makeCommonPrimitiveFilterComponents(baseSchema, optional, () => z.lazy(() => this.makeEnumFilterSchema(enumDef, optional)));
4694
+ const components = this.makeCommonPrimitiveFilterComponents(baseSchema, optional, () => z.lazy(() => this.makeEnumFilterSchema(enumDef, optional, withAggregations)), [
4695
+ "equals",
4696
+ "in",
4697
+ "notIn",
4698
+ "not"
4699
+ ], withAggregations ? [
4700
+ "_count",
4701
+ "_min",
4702
+ "_max"
4703
+ ] : void 0);
4680
4704
  return z.union([
4681
4705
  this.nullableIf(baseSchema, optional),
4682
- z.strictObject({
4683
- equals: components.equals,
4684
- in: components.in,
4685
- notIn: components.notIn,
4686
- not: components.not
4687
- })
4706
+ z.strictObject(components)
4688
4707
  ]);
4689
4708
  }
4690
4709
  makeArrayFilterSchema(type) {
@@ -4696,45 +4715,59 @@ var InputValidator = class {
4696
4715
  isEmpty: z.boolean().optional()
4697
4716
  });
4698
4717
  }
4699
- makePrimitiveFilterSchema(type, optional) {
4718
+ makePrimitiveFilterSchema(type, optional, withAggregations) {
4700
4719
  if (this.schema.typeDefs && type in this.schema.typeDefs) {
4701
4720
  return this.makeTypeDefFilterSchema(type, optional);
4702
4721
  }
4703
- return match14(type).with("String", () => this.makeStringFilterSchema(optional)).with(P2.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", () => z.any()).with("Unsupported", () => z.never()).exhaustive();
4722
+ return match15(type).with("String", () => this.makeStringFilterSchema(optional, withAggregations)).with(P2.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", () => z.any()).with("Unsupported", () => z.never()).exhaustive();
4704
4723
  }
4705
4724
  makeTypeDefFilterSchema(_type, _optional) {
4706
4725
  return z.never();
4707
4726
  }
4708
- makeDateTimeFilterSchema(optional) {
4727
+ makeDateTimeFilterSchema(optional, withAggregations) {
4709
4728
  return this.makeCommonPrimitiveFilterSchema(z.union([
4710
- z.string().datetime(),
4729
+ z.iso.datetime(),
4711
4730
  z.date()
4712
- ]), optional, () => z.lazy(() => this.makeDateTimeFilterSchema(optional)));
4713
- }
4714
- makeBooleanFilterSchema(optional) {
4731
+ ]), optional, () => z.lazy(() => this.makeDateTimeFilterSchema(optional, withAggregations)), withAggregations ? [
4732
+ "_count",
4733
+ "_min",
4734
+ "_max"
4735
+ ] : void 0);
4736
+ }
4737
+ makeBooleanFilterSchema(optional, withAggregations) {
4738
+ const components = this.makeCommonPrimitiveFilterComponents(z.boolean(), optional, () => z.lazy(() => this.makeBooleanFilterSchema(optional, withAggregations)), [
4739
+ "equals",
4740
+ "not"
4741
+ ], withAggregations ? [
4742
+ "_count",
4743
+ "_min",
4744
+ "_max"
4745
+ ] : void 0);
4715
4746
  return z.union([
4716
4747
  this.nullableIf(z.boolean(), optional),
4717
- z.strictObject({
4718
- equals: this.nullableIf(z.boolean(), optional).optional(),
4719
- not: z.lazy(() => this.makeBooleanFilterSchema(optional)).optional()
4720
- })
4748
+ z.strictObject(components)
4721
4749
  ]);
4722
4750
  }
4723
- makeBytesFilterSchema(optional) {
4751
+ makeBytesFilterSchema(optional, withAggregations) {
4724
4752
  const baseSchema = z.instanceof(Uint8Array);
4725
- const components = this.makeCommonPrimitiveFilterComponents(baseSchema, optional, () => z.instanceof(Uint8Array));
4753
+ const components = this.makeCommonPrimitiveFilterComponents(baseSchema, optional, () => z.instanceof(Uint8Array), [
4754
+ "equals",
4755
+ "in",
4756
+ "notIn",
4757
+ "not"
4758
+ ], withAggregations ? [
4759
+ "_count",
4760
+ "_min",
4761
+ "_max"
4762
+ ] : void 0);
4726
4763
  return z.union([
4727
4764
  this.nullableIf(baseSchema, optional),
4728
- z.strictObject({
4729
- equals: components.equals,
4730
- in: components.in,
4731
- notIn: components.notIn,
4732
- not: components.not
4733
- })
4765
+ z.strictObject(components)
4734
4766
  ]);
4735
4767
  }
4736
- makeCommonPrimitiveFilterComponents(baseSchema, optional, makeThis) {
4737
- return {
4768
+ makeCommonPrimitiveFilterComponents(baseSchema, optional, makeThis, supportedOperators = void 0, withAggregations = void 0) {
4769
+ const commonAggSchema = /* @__PURE__ */ __name(() => this.makeCommonPrimitiveFilterSchema(baseSchema, false, makeThis, void 0).optional(), "commonAggSchema");
4770
+ let result = {
4738
4771
  equals: this.nullableIf(baseSchema.optional(), optional),
4739
4772
  notEquals: this.nullableIf(baseSchema.optional(), optional),
4740
4773
  in: baseSchema.array().optional(),
@@ -4743,23 +4776,56 @@ var InputValidator = class {
4743
4776
  lte: baseSchema.optional(),
4744
4777
  gt: baseSchema.optional(),
4745
4778
  gte: baseSchema.optional(),
4746
- not: makeThis().optional()
4779
+ not: makeThis().optional(),
4780
+ ...withAggregations?.includes("_count") ? {
4781
+ _count: this.makeNumberFilterSchema(z.int(), false, false).optional()
4782
+ } : {},
4783
+ ...withAggregations?.includes("_avg") ? {
4784
+ _avg: commonAggSchema()
4785
+ } : {},
4786
+ ...withAggregations?.includes("_sum") ? {
4787
+ _sum: commonAggSchema()
4788
+ } : {},
4789
+ ...withAggregations?.includes("_min") ? {
4790
+ _min: commonAggSchema()
4791
+ } : {},
4792
+ ...withAggregations?.includes("_max") ? {
4793
+ _max: commonAggSchema()
4794
+ } : {}
4747
4795
  };
4796
+ if (supportedOperators) {
4797
+ const keys = [
4798
+ ...supportedOperators,
4799
+ ...withAggregations ?? []
4800
+ ];
4801
+ result = extractFields(result, keys);
4802
+ }
4803
+ return result;
4748
4804
  }
4749
- makeCommonPrimitiveFilterSchema(baseSchema, optional, makeThis) {
4805
+ makeCommonPrimitiveFilterSchema(baseSchema, optional, makeThis, withAggregations = void 0) {
4750
4806
  return z.union([
4751
4807
  this.nullableIf(baseSchema, optional),
4752
- z.strictObject(this.makeCommonPrimitiveFilterComponents(baseSchema, optional, makeThis))
4808
+ z.strictObject(this.makeCommonPrimitiveFilterComponents(baseSchema, optional, makeThis, void 0, withAggregations))
4753
4809
  ]);
4754
4810
  }
4755
- makeNumberFilterSchema(baseSchema, optional) {
4756
- return this.makeCommonPrimitiveFilterSchema(baseSchema, optional, () => z.lazy(() => this.makeNumberFilterSchema(baseSchema, optional)));
4811
+ makeNumberFilterSchema(baseSchema, optional, withAggregations) {
4812
+ return this.makeCommonPrimitiveFilterSchema(baseSchema, optional, () => z.lazy(() => this.makeNumberFilterSchema(baseSchema, optional, withAggregations)), withAggregations ? [
4813
+ "_count",
4814
+ "_avg",
4815
+ "_sum",
4816
+ "_min",
4817
+ "_max"
4818
+ ] : void 0);
4757
4819
  }
4758
- makeStringFilterSchema(optional) {
4820
+ makeStringFilterSchema(optional, withAggregations) {
4759
4821
  return z.union([
4760
4822
  this.nullableIf(z.string(), optional),
4761
4823
  z.strictObject({
4762
- ...this.makeCommonPrimitiveFilterComponents(z.string(), optional, () => z.lazy(() => this.makeStringFilterSchema(optional))),
4824
+ ...this.makeCommonPrimitiveFilterComponents(z.string(), optional, () => z.lazy(() => this.makeStringFilterSchema(optional, withAggregations)), void 0, withAggregations ? [
4825
+ "_count",
4826
+ "_min",
4827
+ "_max"
4828
+ ] : void 0),
4763
4829
  startsWith: z.string().optional(),
4764
4830
  endsWith: z.string().optional(),
4765
4831
  contains: z.string().optional(),
@@ -5117,7 +5183,7 @@ var InputValidator = class {
5117
5183
  return z.object({
5118
5184
  where: this.makeWhereSchema(model, false).optional(),
5119
5185
  data: this.makeUpdateDataSchema(model, [], true),
5120
- limit: z.number().int().nonnegative().optional()
5186
+ limit: z.int().nonnegative().optional()
5121
5187
  });
5122
5188
  }
5123
5189
  makeUpdateManyAndReturnSchema(model) {
@@ -5224,7 +5290,7 @@ var InputValidator = class {
5224
5290
  makeDeleteManySchema(model) {
5225
5291
  return z.object({
5226
5292
  where: this.makeWhereSchema(model, false).optional(),
5227
- limit: z.number().int().nonnegative().optional()
5293
+ limit: z.int().nonnegative().optional()
5228
5294
  }).optional();
5229
5295
  }
5230
5296
  // #endregion
@@ -5293,7 +5359,7 @@ var InputValidator = class {
5293
5359
  where: this.makeWhereSchema(model, false).optional(),
5294
5360
  orderBy: this.orArray(this.makeOrderBySchema(model, false, true), true).optional(),
5295
5361
  by: this.orArray(z.enum(nonRelationFields), true),
5296
- having: this.makeWhereSchema(model, false, true).optional(),
5362
+ having: this.makeHavingSchema(model).optional(),
5297
5363
  skip: this.makeSkipSchema().optional(),
5298
5364
  take: this.makeTakeSchema().optional(),
5299
5365
  _count: this.makeCountAggregateInputSchema(model).optional(),
@@ -5306,17 +5372,29 @@ var InputValidator = class {
5306
5372
  const bys = typeof value.by === "string" ? [
5307
5373
  value.by
5308
5374
  ] : value.by;
5309
- if (value.having && Object.keys(value.having).filter((f) => !f.startsWith("_")).some((key) => !bys.includes(key))) {
5310
- return false;
5311
- } else {
5312
- return true;
5375
+ if (value.having && typeof value.having === "object") {
5376
+ for (const [key, val] of Object.entries(value.having)) {
5377
+ if (AGGREGATE_OPERATORS.includes(key)) {
5378
+ continue;
5379
+ }
5380
+ if (bys.includes(key)) {
5381
+ continue;
5382
+ }
5383
+ if (!val || typeof val !== "object") {
5384
+ return false;
5385
+ }
5386
+ if (!this.onlyAggregationFields(val)) {
5387
+ return false;
5388
+ }
5389
+ }
5313
5390
  }
5391
+ return true;
5314
5392
  }, 'fields in "having" must be in "by"');
5315
5393
  schema = schema.refine((value) => {
5316
5394
  const bys = typeof value.by === "string" ? [
5317
5395
  value.by
5318
5396
  ] : value.by;
5319
- if (value.orderBy && Object.keys(value.orderBy).filter((f) => !f.startsWith("_")).some((key) => !bys.includes(key))) {
5397
+ if (value.orderBy && Object.keys(value.orderBy).filter((f) => !AGGREGATE_OPERATORS.includes(f)).some((key) => !bys.includes(key))) {
5320
5398
  return false;
5321
5399
  } else {
5322
5400
  return true;
@@ -5324,13 +5402,30 @@ var InputValidator = class {
5324
5402
  }, 'fields in "orderBy" must be in "by"');
5325
5403
  return schema;
5326
5404
  }
5405
+ onlyAggregationFields(val) {
5406
+ for (const [key, value] of Object.entries(val)) {
5407
+ if (AGGREGATE_OPERATORS.includes(key)) {
5408
+ continue;
5409
+ }
5410
+ if (LOGICAL_COMBINATORS.includes(key)) {
5411
+ if (enumerate(value).every((v) => this.onlyAggregationFields(v))) {
5412
+ continue;
5413
+ }
5414
+ }
5415
+ return false;
5416
+ }
5417
+ return true;
5418
+ }
5419
+ makeHavingSchema(model) {
5420
+ return this.makeWhereSchema(model, false, true, true);
5421
+ }
5327
5422
  // #endregion
5328
5423
  // #region Helpers
5329
5424
  makeSkipSchema() {
5330
- return z.number().int().nonnegative();
5425
+ return z.int().nonnegative();
5331
5426
  }
5332
5427
  makeTakeSchema() {
5333
- return z.number().int();
5428
+ return z.int();
5334
5429
  }
5335
5430
  refineForSelectIncludeMutuallyExclusive(schema) {
5336
5431
  return schema.refine((value) => !(value["select"] && value["include"]), '"select" and "include" cannot be used together');
@@ -5538,7 +5633,7 @@ __name(performanceNow, "performanceNow");
5538
5633
  import { AndNode as AndNode2, DefaultQueryExecutor, DeleteQueryNode as DeleteQueryNode2, InsertQueryNode as InsertQueryNode2, ReturningNode as ReturningNode3, SelectionNode as SelectionNode4, UpdateQueryNode as UpdateQueryNode2, WhereNode as WhereNode3 } from "kysely";
5539
5634
  import { nanoid as nanoid2 } from "nanoid";
5540
5635
  import { inspect as inspect2 } from "util";
5541
- import { match as match15 } from "ts-pattern";
5636
+ import { match as match16 } from "ts-pattern";
5542
5637
 
5543
5638
  // src/client/executor/name-mapper.ts
5544
5639
  import { AliasNode as AliasNode4, ColumnNode as ColumnNode3, IdentifierNode as IdentifierNode3, OperationNodeTransformer as OperationNodeTransformer2, ReferenceNode as ReferenceNode3, ReturningNode as ReturningNode2, SelectAllNode, SelectionNode as SelectionNode3, TableNode as TableNode4 } from "kysely";
@@ -5886,7 +5981,7 @@ ${compiled.parameters.map((p) => inspect2(p)).join("\n")}`;
5886
5981
  return this.client.$options.plugins?.some((plugin) => plugin.beforeEntityMutation || plugin.afterEntityMutation);
5887
5982
  }
5888
5983
  getMutationModel(queryNode) {
5889
- return match15(queryNode).when(InsertQueryNode2.is, (node) => node.into.table.identifier.name).when(UpdateQueryNode2.is, (node) => node.table.table.identifier.name).when(DeleteQueryNode2.is, (node) => {
5984
+ return match16(queryNode).when(InsertQueryNode2.is, (node) => node.into.table.identifier.name).when(UpdateQueryNode2.is, (node) => node.table.table.identifier.name).when(DeleteQueryNode2.is, (node) => {
5890
5985
  if (node.from.froms.length !== 1) {
5891
5986
  throw new InternalError(`Delete query must have exactly one from table`);
5892
5987
  }
@@ -5902,7 +5997,7 @@ ${compiled.parameters.map((p) => inspect2(p)).join("\n")}`;
5902
5997
  const result = {
5903
5998
  intercept: false
5904
5999
  };
5905
- const { action, where } = match15(queryNode).when(InsertQueryNode2.is, () => ({
6000
+ const { action, where } = match16(queryNode).when(InsertQueryNode2.is, () => ({
5906
6001
  action: "create",
5907
6002
  where: void 0
5908
6003
  })).when(UpdateQueryNode2.is, (node) => ({
@@ -6042,7 +6137,7 @@ __export(functions_exports, {
6042
6137
  });
6043
6138
  import { invariant as invariant9, lowerCaseFirst, upperCaseFirst } from "@zenstackhq/common-helpers";
6044
6139
  import { sql as sql8, ValueNode as ValueNode4 } from "kysely";
6045
- import { match as match16 } from "ts-pattern";
6140
+ import { match as match17 } from "ts-pattern";
6046
6141
  var contains = /* @__PURE__ */ __name((eb, args) => {
6047
6142
  const [field, search2, caseInsensitive = false] = args;
6048
6143
  if (!field) {
@@ -6127,7 +6222,7 @@ var isEmpty = /* @__PURE__ */ __name((eb, args, { dialect }) => {
6127
6222
  return eb(dialect.buildArrayLength(eb, field), "=", sql8.lit(0));
6128
6223
  }, "isEmpty");
6129
6224
  var now = /* @__PURE__ */ __name((eb, _args, { dialect }) => {
6130
- return match16(dialect.provider).with("postgresql", () => eb.fn("now")).with("sqlite", () => sql8.raw("CURRENT_TIMESTAMP")).exhaustive();
6225
+ return match17(dialect.provider).with("postgresql", () => eb.fn("now")).with("sqlite", () => sql8.raw("CURRENT_TIMESTAMP")).exhaustive();
6131
6226
  }, "now");
6132
6227
  var currentModel = /* @__PURE__ */ __name((_eb, args, { model }) => {
6133
6228
  let result = model;
@@ -6148,7 +6243,7 @@ var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
6148
6243
  function processCasing(casing, result, model) {
6149
6244
  const opNode = casing.toOperationNode();
6150
6245
  invariant9(ValueNode4.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
6151
- result = match16(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => upperCaseFirst(result)).with("uncapitalize", () => lowerCaseFirst(result)).otherwise(() => {
6246
+ result = match17(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => upperCaseFirst(result)).with("uncapitalize", () => lowerCaseFirst(result)).otherwise(() => {
6152
6247
  throw new Error(`Invalid casing value: ${opNode.value}. Must be "original", "upper", "lower", "capitalize", or "uncapitalize".`);
6153
6248
  });
6154
6249
  return result;
@@ -6158,7 +6253,7 @@ __name(processCasing, "processCasing");
6158
6253
  // src/client/helpers/schema-db-pusher.ts
6159
6254
  import { invariant as invariant10 } from "@zenstackhq/common-helpers";
6160
6255
  import { sql as sql9 } from "kysely";
6161
- import { match as match17 } from "ts-pattern";
6256
+ import { match as match18 } from "ts-pattern";
6162
6257
  var SchemaDbPusher = class {
6163
6258
  static {
6164
6259
  __name(this, "SchemaDbPusher");
@@ -6262,7 +6357,7 @@ var SchemaDbPusher = class {
6262
6357
  return "serial";
6263
6358
  }
6264
6359
  const type = fieldDef.type;
6265
- const result = match17(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(() => {
6360
+ const result = match18(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(() => {
6266
6361
  throw new Error(`Unsupported field type: ${type}`);
6267
6362
  });
6268
6363
  if (fieldDef.array) {
@@ -6291,7 +6386,7 @@ var SchemaDbPusher = class {
6291
6386
  return table;
6292
6387
  }
6293
6388
  mapCascadeAction(action) {
6294
- return match17(action).with("SetNull", () => "set null").with("Cascade", () => "cascade").with("Restrict", () => "restrict").with("NoAction", () => "no action").with("SetDefault", () => "set default").exhaustive();
6389
+ return match18(action).with("SetNull", () => "set null").with("Cascade", () => "cascade").with("Restrict", () => "restrict").with("NoAction", () => "no action").with("SetDefault", () => "set default").exhaustive();
6295
6390
  }
6296
6391
  };
6297
6392
 
@@ -6332,7 +6427,7 @@ __name(valueToPromise, "valueToPromise");
6332
6427
  // src/client/result-processor.ts
6333
6428
  import { invariant as invariant11 } from "@zenstackhq/common-helpers";
6334
6429
  import Decimal2 from "decimal.js";
6335
- import { match as match18 } from "ts-pattern";
6430
+ import { match as match19 } from "ts-pattern";
6336
6431
  var ResultProcessor = class {
6337
6432
  static {
6338
6433
  __name(this, "ResultProcessor");
@@ -6423,7 +6518,7 @@ var ResultProcessor = class {
6423
6518
  if (this.schema.typeDefs && type in this.schema.typeDefs) {
6424
6519
  return this.transformJson(value);
6425
6520
  } else {
6426
- return match18(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);
6521
+ return match19(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);
6427
6522
  }
6428
6523
  }
6429
6524
  transformDecimal(value) {
@@ -6480,7 +6575,7 @@ var ResultProcessor = class {
6480
6575
  }
6481
6576
  }
6482
6577
  transformJson(value) {
6483
- return match18(this.schema.provider.type).with("sqlite", () => {
6578
+ return match19(this.schema.provider.type).with("sqlite", () => {
6484
6579
  invariant11(typeof value === "string", "Expected string, got " + typeof value);
6485
6580
  return JSON.parse(value);
6486
6581
  }).otherwise(() => value);
@@ -6817,7 +6912,7 @@ function createModelCrudHandler(client, model, inputValidator, resultProcessor)
6817
6912
  return createPromise("aggregate", args, new AggregateOperationHandler(client, model, inputValidator), false);
6818
6913
  }, "aggregate"),
6819
6914
  groupBy: /* @__PURE__ */ __name((args) => {
6820
- return createPromise("groupBy", args, new GroupByOperationHandler(client, model, inputValidator));
6915
+ return createPromise("groupBy", args, new GroupByOperationHandler(client, model, inputValidator), true);
6821
6916
  }, "groupBy")
6822
6917
  };
6823
6918
  }