@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/{contract-CxX20JtH.d.cts → contract-XFKcwhq7.d.cts} +67 -38
- package/dist/{contract-CxX20JtH.d.ts → contract-XFKcwhq7.d.ts} +67 -38
- package/dist/index.cjs +229 -134
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +229 -134
- package/dist/index.js.map +1 -1
- package/dist/plugins/policy/index.cjs +50 -26
- package/dist/plugins/policy/index.cjs.map +1 -1
- package/dist/plugins/policy/index.d.cts +1 -1
- package/dist/plugins/policy/index.d.ts +1 -1
- package/dist/plugins/policy/index.js +50 -26
- package/dist/plugins/policy/index.js.map +1 -1
- package/package.json +9 -9
|
@@ -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
|
|
44
|
+
var import_ts_pattern8 = require("ts-pattern");
|
|
45
45
|
|
|
46
46
|
// src/client/crud/dialects/index.ts
|
|
47
|
-
var
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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))).
|
|
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,
|
|
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.
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
}
|