@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.
@@ -41,18 +41,33 @@ var RejectedByPolicyError = class extends Error {
41
41
  // src/plugins/policy/policy-handler.ts
42
42
  var import_common_helpers6 = require("@zenstackhq/common-helpers");
43
43
  var import_kysely7 = require("kysely");
44
- var import_ts_pattern7 = require("ts-pattern");
44
+ var import_ts_pattern8 = require("ts-pattern");
45
45
 
46
46
  // src/client/crud/dialects/index.ts
47
- var import_ts_pattern4 = require("ts-pattern");
47
+ var import_ts_pattern5 = require("ts-pattern");
48
48
 
49
49
  // src/client/crud/dialects/postgresql.ts
50
50
  var import_common_helpers2 = require("@zenstackhq/common-helpers");
51
51
  var import_kysely2 = require("kysely");
52
- var import_ts_pattern2 = require("ts-pattern");
52
+ var import_ts_pattern3 = require("ts-pattern");
53
53
 
54
54
  // src/client/constants.ts
55
55
  var DELEGATE_JOINED_FIELD_PREFIX = "$delegate$";
56
+ var LOGICAL_COMBINATORS = [
57
+ "AND",
58
+ "OR",
59
+ "NOT"
60
+ ];
61
+ var AGGREGATE_OPERATORS = [
62
+ "_count",
63
+ "_sum",
64
+ "_avg",
65
+ "_min",
66
+ "_max"
67
+ ];
68
+
69
+ // src/client/query-utils.ts
70
+ var import_ts_pattern = require("ts-pattern");
56
71
 
57
72
  // src/schema/expression.ts
58
73
  var ExpressionUtils = {
@@ -357,11 +372,15 @@ function getDelegateDescendantModels(schema, model, collected = /* @__PURE__ */
357
372
  ];
358
373
  }
359
374
  __name(getDelegateDescendantModels, "getDelegateDescendantModels");
375
+ function aggregate(eb, expr2, op) {
376
+ return (0, import_ts_pattern.match)(op).with("_count", () => eb.fn.count(expr2)).with("_sum", () => eb.fn.sum(expr2)).with("_avg", () => eb.fn.avg(expr2)).with("_min", () => eb.fn.min(expr2)).with("_max", () => eb.fn.max(expr2)).exhaustive();
377
+ }
378
+ __name(aggregate, "aggregate");
360
379
 
361
380
  // src/client/crud/dialects/base.ts
362
381
  var import_common_helpers = require("@zenstackhq/common-helpers");
363
382
  var import_kysely = require("kysely");
364
- var import_ts_pattern = require("ts-pattern");
383
+ var import_ts_pattern2 = require("ts-pattern");
365
384
 
366
385
  // src/utils/enumerate.ts
367
386
  function enumerate(x) {
@@ -418,7 +437,7 @@ var BaseCrudDialect = class {
418
437
  if (key.startsWith("$")) {
419
438
  continue;
420
439
  }
421
- if (key === "AND" || key === "OR" || key === "NOT") {
440
+ if (this.isLogicalCombinator(key)) {
422
441
  result = this.and(eb, result, this.buildCompositeFilter(eb, model, modelAlias, key, payload));
423
442
  continue;
424
443
  }
@@ -439,8 +458,11 @@ var BaseCrudDialect = class {
439
458
  }
440
459
  return result;
441
460
  }
461
+ isLogicalCombinator(key) {
462
+ return LOGICAL_COMBINATORS.includes(key);
463
+ }
442
464
  buildCompositeFilter(eb, model, modelAlias, key, payload) {
443
- return (0, import_ts_pattern.match)(key).with("AND", () => this.and(eb, ...enumerate(payload).map((subPayload) => this.buildFilter(eb, model, modelAlias, subPayload)))).with("OR", () => this.or(eb, ...enumerate(payload).map((subPayload) => this.buildFilter(eb, model, modelAlias, subPayload)))).with("NOT", () => eb.not(this.buildCompositeFilter(eb, model, modelAlias, "AND", payload))).exhaustive();
465
+ return (0, import_ts_pattern2.match)(key).with("AND", () => this.and(eb, ...enumerate(payload).map((subPayload) => this.buildFilter(eb, model, modelAlias, subPayload)))).with("OR", () => this.or(eb, ...enumerate(payload).map((subPayload) => this.buildFilter(eb, model, modelAlias, subPayload)))).with("NOT", () => eb.not(this.buildCompositeFilter(eb, model, modelAlias, "AND", payload))).exhaustive();
444
466
  }
445
467
  buildRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
446
468
  if (!fieldDef.array) {
@@ -589,7 +611,7 @@ var BaseCrudDialect = class {
589
611
  if (isEnum(this.schema, fieldDef.type)) {
590
612
  return this.buildEnumFilter(eb, fieldRef, fieldDef, payload);
591
613
  }
592
- 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", () => {
614
+ return (0, import_ts_pattern2.match)(fieldDef.type).with("String", () => this.buildStringFilter(eb, fieldRef, payload)).with(import_ts_pattern2.P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.buildNumberFilter(eb, fieldRef, type, payload)).with("Boolean", () => this.buildBooleanFilter(eb, fieldRef, payload)).with("DateTime", () => this.buildDateTimeFilter(eb, fieldRef, payload)).with("Bytes", () => this.buildBytesFilter(eb, fieldRef, payload)).with("Json", () => {
593
615
  throw new InternalError("JSON filters are not supported yet");
594
616
  }).with("Unsupported", () => {
595
617
  throw new QueryError(`Unsupported field cannot be used in filters`);
@@ -617,7 +639,7 @@ var BaseCrudDialect = class {
617
639
  continue;
618
640
  }
619
641
  const rhs = Array.isArray(value) ? value.map(getRhs) : getRhs(value);
620
- const condition = (0, import_ts_pattern.match)(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
642
+ const condition = (0, import_ts_pattern2.match)(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
621
643
  (0, import_common_helpers.invariant)(Array.isArray(rhs), "right hand side must be an array");
622
644
  if (rhs.length === 0) {
623
645
  return this.false(eb);
@@ -631,7 +653,11 @@ var BaseCrudDialect = class {
631
653
  } else {
632
654
  return eb.not(eb(lhs, "in", rhs));
633
655
  }
634
- }).with("lt", () => eb(lhs, "<", rhs)).with("lte", () => eb(lhs, "<=", rhs)).with("gt", () => eb(lhs, ">", rhs)).with("gte", () => eb(lhs, ">=", rhs)).with("not", () => eb.not(recurse(value))).otherwise(() => {
656
+ }).with("lt", () => eb(lhs, "<", rhs)).with("lte", () => eb(lhs, "<=", rhs)).with("gt", () => eb(lhs, ">", rhs)).with("gte", () => eb(lhs, ">=", rhs)).with("not", () => eb.not(recurse(value))).with(import_ts_pattern2.P.union(...AGGREGATE_OPERATORS), (op2) => {
657
+ const innerResult = this.buildStandardFilter(eb, type, value, aggregate(eb, lhs, op2), getRhs, recurse, throwIfInvalid);
658
+ consumedKeys.push(...innerResult.consumedKeys);
659
+ return this.and(eb, ...innerResult.conditions);
660
+ }).otherwise(() => {
635
661
  if (throwIfInvalid) {
636
662
  throw new QueryError(`Invalid filter key: ${op}`);
637
663
  } else {
@@ -661,7 +687,7 @@ var BaseCrudDialect = class {
661
687
  if (key === "mode" || consumedKeys.includes(key)) {
662
688
  continue;
663
689
  }
664
- 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(() => {
690
+ const condition = (0, import_ts_pattern2.match)(key).with("contains", () => mode === "insensitive" ? eb(fieldRef, "ilike", import_kysely.sql.val(`%${value}%`)) : eb(fieldRef, "like", import_kysely.sql.val(`%${value}%`))).with("startsWith", () => mode === "insensitive" ? eb(fieldRef, "ilike", import_kysely.sql.val(`${value}%`)) : eb(fieldRef, "like", import_kysely.sql.val(`${value}%`))).with("endsWith", () => mode === "insensitive" ? eb(fieldRef, "ilike", import_kysely.sql.val(`%${value}`)) : eb(fieldRef, "like", import_kysely.sql.val(`%${value}`))).otherwise(() => {
665
691
  throw new QueryError(`Invalid string filter key: ${key}`);
666
692
  });
667
693
  if (condition) {
@@ -742,9 +768,7 @@ var BaseCrudDialect = class {
742
768
  (0, import_common_helpers.invariant)(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
743
769
  for (const [k, v] of Object.entries(value)) {
744
770
  (0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
745
- result = result.orderBy((eb) => eb.fn(field.slice(1), [
746
- import_kysely.sql.ref(k)
747
- ]), import_kysely.sql.raw(this.negateSort(v, negated)));
771
+ result = result.orderBy((eb) => aggregate(eb, import_kysely.sql.ref(`${modelAlias}.${k}`), field), import_kysely.sql.raw(this.negateSort(v, negated)));
748
772
  }
749
773
  continue;
750
774
  }
@@ -939,7 +963,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
939
963
  return value.map((v) => this.transformPrimitive(v, type, false));
940
964
  }
941
965
  } else {
942
- 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);
966
+ return (0, import_ts_pattern3.match)(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).with("Decimal", () => value !== null ? value.toString() : value).otherwise(() => value);
943
967
  }
944
968
  }
945
969
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
@@ -1096,7 +1120,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1096
1120
  // src/client/crud/dialects/sqlite.ts
1097
1121
  var import_common_helpers3 = require("@zenstackhq/common-helpers");
1098
1122
  var import_kysely3 = require("kysely");
1099
- var import_ts_pattern3 = require("ts-pattern");
1123
+ var import_ts_pattern4 = require("ts-pattern");
1100
1124
  var SqliteCrudDialect = class extends BaseCrudDialect {
1101
1125
  static {
1102
1126
  __name(this, "SqliteCrudDialect");
@@ -1114,7 +1138,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1114
1138
  if (this.schema.typeDefs && type in this.schema.typeDefs) {
1115
1139
  return JSON.stringify(value);
1116
1140
  } else {
1117
- 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);
1141
+ return (0, import_ts_pattern4.match)(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => value instanceof Date ? value.toISOString() : value).with("Decimal", () => value.toString()).with("Bytes", () => Buffer.from(value)).with("Json", () => JSON.stringify(value)).otherwise(() => value);
1118
1142
  }
1119
1143
  }
1120
1144
  }
@@ -1260,7 +1284,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1260
1284
 
1261
1285
  // src/client/crud/dialects/index.ts
1262
1286
  function getCrudDialect(schema, options) {
1263
- return (0, import_ts_pattern4.match)(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
1287
+ return (0, import_ts_pattern5.match)(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
1264
1288
  }
1265
1289
  __name(getCrudDialect, "getCrudDialect");
1266
1290
 
@@ -1585,17 +1609,17 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
1585
1609
  // src/plugins/policy/expression-transformer.ts
1586
1610
  var import_common_helpers5 = require("@zenstackhq/common-helpers");
1587
1611
  var import_kysely6 = require("kysely");
1588
- var import_ts_pattern6 = require("ts-pattern");
1612
+ var import_ts_pattern7 = require("ts-pattern");
1589
1613
 
1590
1614
  // src/plugins/policy/expression-evaluator.ts
1591
1615
  var import_common_helpers4 = require("@zenstackhq/common-helpers");
1592
- var import_ts_pattern5 = require("ts-pattern");
1616
+ var import_ts_pattern6 = require("ts-pattern");
1593
1617
  var ExpressionEvaluator = class {
1594
1618
  static {
1595
1619
  __name(this, "ExpressionEvaluator");
1596
1620
  }
1597
1621
  evaluate(expression, context) {
1598
- const result = (0, import_ts_pattern5.match)(expression).when(ExpressionUtils.isArray, (expr2) => this.evaluateArray(expr2, context)).when(ExpressionUtils.isBinary, (expr2) => this.evaluateBinary(expr2, context)).when(ExpressionUtils.isField, (expr2) => this.evaluateField(expr2, context)).when(ExpressionUtils.isLiteral, (expr2) => this.evaluateLiteral(expr2)).when(ExpressionUtils.isMember, (expr2) => this.evaluateMember(expr2, context)).when(ExpressionUtils.isUnary, (expr2) => this.evaluateUnary(expr2, context)).when(ExpressionUtils.isCall, (expr2) => this.evaluateCall(expr2, context)).when(ExpressionUtils.isThis, () => context.thisValue).when(ExpressionUtils.isNull, () => null).exhaustive();
1622
+ const result = (0, import_ts_pattern6.match)(expression).when(ExpressionUtils.isArray, (expr2) => this.evaluateArray(expr2, context)).when(ExpressionUtils.isBinary, (expr2) => this.evaluateBinary(expr2, context)).when(ExpressionUtils.isField, (expr2) => this.evaluateField(expr2, context)).when(ExpressionUtils.isLiteral, (expr2) => this.evaluateLiteral(expr2)).when(ExpressionUtils.isMember, (expr2) => this.evaluateMember(expr2, context)).when(ExpressionUtils.isUnary, (expr2) => this.evaluateUnary(expr2, context)).when(ExpressionUtils.isCall, (expr2) => this.evaluateCall(expr2, context)).when(ExpressionUtils.isThis, () => context.thisValue).when(ExpressionUtils.isNull, () => null).exhaustive();
1599
1623
  return result ?? null;
1600
1624
  }
1601
1625
  evaluateCall(expr2, context) {
@@ -1606,7 +1630,7 @@ var ExpressionEvaluator = class {
1606
1630
  }
1607
1631
  }
1608
1632
  evaluateUnary(expr2, context) {
1609
- return (0, import_ts_pattern5.match)(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1633
+ return (0, import_ts_pattern6.match)(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1610
1634
  }
1611
1635
  evaluateMember(expr2, context) {
1612
1636
  let val = this.evaluate(expr2.receiver, context);
@@ -1630,7 +1654,7 @@ var ExpressionEvaluator = class {
1630
1654
  }
1631
1655
  const left = this.evaluate(expr2.left, context);
1632
1656
  const right = this.evaluate(expr2.right, context);
1633
- return (0, import_ts_pattern5.match)(expr2.op).with("==", () => left === right).with("!=", () => left !== right).with(">", () => left > right).with(">=", () => left >= right).with("<", () => left < right).with("<=", () => left <= right).with("&&", () => left && right).with("||", () => left || right).with("in", () => {
1657
+ return (0, import_ts_pattern6.match)(expr2.op).with("==", () => left === right).with("!=", () => left !== right).with(">", () => left > right).with(">=", () => left >= right).with("<", () => left < right).with("<=", () => left <= right).with("&&", () => left && right).with("||", () => left || right).with("in", () => {
1634
1658
  const _right = right ?? [];
1635
1659
  (0, import_common_helpers4.invariant)(Array.isArray(_right), 'expected array for "in" operator');
1636
1660
  return _right.includes(left);
@@ -1644,7 +1668,7 @@ var ExpressionEvaluator = class {
1644
1668
  return false;
1645
1669
  }
1646
1670
  (0, import_common_helpers4.invariant)(Array.isArray(left), "expected array");
1647
- return (0, import_ts_pattern5.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1671
+ return (0, import_ts_pattern6.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1648
1672
  ...context,
1649
1673
  thisValue: item
1650
1674
  }))).with("!", () => left.every((item) => this.evaluate(expr2.right, {
@@ -1898,7 +1922,7 @@ var ExpressionTransformer = class {
1898
1922
  const count = import_kysely6.FunctionNode.create("count", [
1899
1923
  import_kysely6.ValueNode.createImmediate(1)
1900
1924
  ]);
1901
- const predicateResult = (0, import_ts_pattern6.match)(expr2.op).with("?", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create(">"), import_kysely6.ValueNode.createImmediate(0))).with("!", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create("="), import_kysely6.ValueNode.createImmediate(0))).with("^", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create("="), import_kysely6.ValueNode.createImmediate(0))).exhaustive();
1925
+ const predicateResult = (0, import_ts_pattern7.match)(expr2.op).with("?", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create(">"), import_kysely6.ValueNode.createImmediate(0))).with("!", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create("="), import_kysely6.ValueNode.createImmediate(0))).with("^", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create("="), import_kysely6.ValueNode.createImmediate(0))).exhaustive();
1902
1926
  return this.transform(expr2.left, {
1903
1927
  ...context,
1904
1928
  memberSelect: import_kysely6.SelectionNode.create(import_kysely6.AliasNode.create(predicateResult, import_kysely6.IdentifierNode.create("$t"))),
@@ -1929,7 +1953,7 @@ var ExpressionTransformer = class {
1929
1953
  return import_kysely6.BinaryOperationNode.create(this.transform(expr2.operand, context), this.transformOperator("!="), trueNode(this.dialect));
1930
1954
  }
1931
1955
  transformOperator(op) {
1932
- const mappedOp = (0, import_ts_pattern6.match)(op).with("==", () => "=").otherwise(() => op);
1956
+ const mappedOp = (0, import_ts_pattern7.match)(op).with("==", () => "=").otherwise(() => op);
1933
1957
  return import_kysely6.OperatorNode.create(mappedOp);
1934
1958
  }
1935
1959
  _call(expr2, context) {
@@ -2332,7 +2356,7 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2332
2356
  return disjunction(this.dialect, rows.map((row) => conjunction(this.dialect, idFields.map((field) => import_kysely7.BinaryOperationNode.create(import_kysely7.ColumnNode.create(field), import_kysely7.OperatorNode.create("="), import_kysely7.ValueNode.create(row[field]))))));
2333
2357
  }
2334
2358
  getMutationModel(node) {
2335
- const r = (0, import_ts_pattern7.match)(node).when(import_kysely7.InsertQueryNode.is, (node2) => getTableName(node2.into)).when(import_kysely7.UpdateQueryNode.is, (node2) => getTableName(node2.table)).when(import_kysely7.DeleteQueryNode.is, (node2) => {
2359
+ const r = (0, import_ts_pattern8.match)(node).when(import_kysely7.InsertQueryNode.is, (node2) => getTableName(node2.into)).when(import_kysely7.UpdateQueryNode.is, (node2) => getTableName(node2.table)).when(import_kysely7.DeleteQueryNode.is, (node2) => {
2336
2360
  if (node2.from.froms.length !== 1) {
2337
2361
  throw new InternalError("Only one from table is supported for delete");
2338
2362
  }