@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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as kysely from 'kysely';
|
|
2
|
-
import { R as RuntimePlugin, V as OnKyselyQueryArgs } from '../../contract-
|
|
2
|
+
import { R as RuntimePlugin, V as OnKyselyQueryArgs } from '../../contract-XFKcwhq7.cjs';
|
|
3
3
|
import { SchemaDef } from '@zenstackhq/sdk/schema';
|
|
4
4
|
import 'decimal.js';
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as kysely from 'kysely';
|
|
2
|
-
import { R as RuntimePlugin, V as OnKyselyQueryArgs } from '../../contract-
|
|
2
|
+
import { R as RuntimePlugin, V as OnKyselyQueryArgs } from '../../contract-XFKcwhq7.js';
|
|
3
3
|
import { SchemaDef } from '@zenstackhq/sdk/schema';
|
|
4
4
|
import 'decimal.js';
|
|
5
5
|
|
|
@@ -16,18 +16,33 @@ var RejectedByPolicyError = class extends Error {
|
|
|
16
16
|
// src/plugins/policy/policy-handler.ts
|
|
17
17
|
import { invariant as invariant6 } from "@zenstackhq/common-helpers";
|
|
18
18
|
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";
|
|
19
|
-
import { match as
|
|
19
|
+
import { match as match8 } from "ts-pattern";
|
|
20
20
|
|
|
21
21
|
// src/client/crud/dialects/index.ts
|
|
22
|
-
import { match as
|
|
22
|
+
import { match as match5 } from "ts-pattern";
|
|
23
23
|
|
|
24
24
|
// src/client/crud/dialects/postgresql.ts
|
|
25
25
|
import { invariant as invariant2 } from "@zenstackhq/common-helpers";
|
|
26
26
|
import { sql as sql2 } from "kysely";
|
|
27
|
-
import { match as
|
|
27
|
+
import { match as match3 } from "ts-pattern";
|
|
28
28
|
|
|
29
29
|
// src/client/constants.ts
|
|
30
30
|
var DELEGATE_JOINED_FIELD_PREFIX = "$delegate$";
|
|
31
|
+
var LOGICAL_COMBINATORS = [
|
|
32
|
+
"AND",
|
|
33
|
+
"OR",
|
|
34
|
+
"NOT"
|
|
35
|
+
];
|
|
36
|
+
var AGGREGATE_OPERATORS = [
|
|
37
|
+
"_count",
|
|
38
|
+
"_sum",
|
|
39
|
+
"_avg",
|
|
40
|
+
"_min",
|
|
41
|
+
"_max"
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
// src/client/query-utils.ts
|
|
45
|
+
import { match } from "ts-pattern";
|
|
31
46
|
|
|
32
47
|
// src/schema/expression.ts
|
|
33
48
|
var ExpressionUtils = {
|
|
@@ -332,11 +347,15 @@ function getDelegateDescendantModels(schema, model, collected = /* @__PURE__ */
|
|
|
332
347
|
];
|
|
333
348
|
}
|
|
334
349
|
__name(getDelegateDescendantModels, "getDelegateDescendantModels");
|
|
350
|
+
function aggregate(eb, expr2, op) {
|
|
351
|
+
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();
|
|
352
|
+
}
|
|
353
|
+
__name(aggregate, "aggregate");
|
|
335
354
|
|
|
336
355
|
// src/client/crud/dialects/base.ts
|
|
337
356
|
import { invariant, isPlainObject } from "@zenstackhq/common-helpers";
|
|
338
357
|
import { sql } from "kysely";
|
|
339
|
-
import { match, P } from "ts-pattern";
|
|
358
|
+
import { match as match2, P } from "ts-pattern";
|
|
340
359
|
|
|
341
360
|
// src/utils/enumerate.ts
|
|
342
361
|
function enumerate(x) {
|
|
@@ -393,7 +412,7 @@ var BaseCrudDialect = class {
|
|
|
393
412
|
if (key.startsWith("$")) {
|
|
394
413
|
continue;
|
|
395
414
|
}
|
|
396
|
-
if (key
|
|
415
|
+
if (this.isLogicalCombinator(key)) {
|
|
397
416
|
result = this.and(eb, result, this.buildCompositeFilter(eb, model, modelAlias, key, payload));
|
|
398
417
|
continue;
|
|
399
418
|
}
|
|
@@ -414,8 +433,11 @@ var BaseCrudDialect = class {
|
|
|
414
433
|
}
|
|
415
434
|
return result;
|
|
416
435
|
}
|
|
436
|
+
isLogicalCombinator(key) {
|
|
437
|
+
return LOGICAL_COMBINATORS.includes(key);
|
|
438
|
+
}
|
|
417
439
|
buildCompositeFilter(eb, model, modelAlias, key, payload) {
|
|
418
|
-
return
|
|
440
|
+
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();
|
|
419
441
|
}
|
|
420
442
|
buildRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
|
|
421
443
|
if (!fieldDef.array) {
|
|
@@ -564,7 +586,7 @@ var BaseCrudDialect = class {
|
|
|
564
586
|
if (isEnum(this.schema, fieldDef.type)) {
|
|
565
587
|
return this.buildEnumFilter(eb, fieldRef, fieldDef, payload);
|
|
566
588
|
}
|
|
567
|
-
return
|
|
589
|
+
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", () => {
|
|
568
590
|
throw new InternalError("JSON filters are not supported yet");
|
|
569
591
|
}).with("Unsupported", () => {
|
|
570
592
|
throw new QueryError(`Unsupported field cannot be used in filters`);
|
|
@@ -592,7 +614,7 @@ var BaseCrudDialect = class {
|
|
|
592
614
|
continue;
|
|
593
615
|
}
|
|
594
616
|
const rhs = Array.isArray(value) ? value.map(getRhs) : getRhs(value);
|
|
595
|
-
const condition =
|
|
617
|
+
const condition = match2(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
|
|
596
618
|
invariant(Array.isArray(rhs), "right hand side must be an array");
|
|
597
619
|
if (rhs.length === 0) {
|
|
598
620
|
return this.false(eb);
|
|
@@ -606,7 +628,11 @@ var BaseCrudDialect = class {
|
|
|
606
628
|
} else {
|
|
607
629
|
return eb.not(eb(lhs, "in", rhs));
|
|
608
630
|
}
|
|
609
|
-
}).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))).
|
|
631
|
+
}).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) => {
|
|
632
|
+
const innerResult = this.buildStandardFilter(eb, type, value, aggregate(eb, lhs, op2), getRhs, recurse, throwIfInvalid);
|
|
633
|
+
consumedKeys.push(...innerResult.consumedKeys);
|
|
634
|
+
return this.and(eb, ...innerResult.conditions);
|
|
635
|
+
}).otherwise(() => {
|
|
610
636
|
if (throwIfInvalid) {
|
|
611
637
|
throw new QueryError(`Invalid filter key: ${op}`);
|
|
612
638
|
} else {
|
|
@@ -636,7 +662,7 @@ var BaseCrudDialect = class {
|
|
|
636
662
|
if (key === "mode" || consumedKeys.includes(key)) {
|
|
637
663
|
continue;
|
|
638
664
|
}
|
|
639
|
-
const condition =
|
|
665
|
+
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(() => {
|
|
640
666
|
throw new QueryError(`Invalid string filter key: ${key}`);
|
|
641
667
|
});
|
|
642
668
|
if (condition) {
|
|
@@ -717,9 +743,7 @@ var BaseCrudDialect = class {
|
|
|
717
743
|
invariant(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
|
|
718
744
|
for (const [k, v] of Object.entries(value)) {
|
|
719
745
|
invariant(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
|
|
720
|
-
result = result.orderBy((eb) => eb.
|
|
721
|
-
sql.ref(k)
|
|
722
|
-
]), sql.raw(this.negateSort(v, negated)));
|
|
746
|
+
result = result.orderBy((eb) => aggregate(eb, sql.ref(`${modelAlias}.${k}`), field), sql.raw(this.negateSort(v, negated)));
|
|
723
747
|
}
|
|
724
748
|
continue;
|
|
725
749
|
}
|
|
@@ -914,7 +938,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
914
938
|
return value.map((v) => this.transformPrimitive(v, type, false));
|
|
915
939
|
}
|
|
916
940
|
} else {
|
|
917
|
-
return
|
|
941
|
+
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);
|
|
918
942
|
}
|
|
919
943
|
}
|
|
920
944
|
buildRelationSelection(query, model, relationField, parentAlias, payload) {
|
|
@@ -1071,7 +1095,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
1071
1095
|
// src/client/crud/dialects/sqlite.ts
|
|
1072
1096
|
import { invariant as invariant3 } from "@zenstackhq/common-helpers";
|
|
1073
1097
|
import { sql as sql3 } from "kysely";
|
|
1074
|
-
import { match as
|
|
1098
|
+
import { match as match4 } from "ts-pattern";
|
|
1075
1099
|
var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
1076
1100
|
static {
|
|
1077
1101
|
__name(this, "SqliteCrudDialect");
|
|
@@ -1089,7 +1113,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1089
1113
|
if (this.schema.typeDefs && type in this.schema.typeDefs) {
|
|
1090
1114
|
return JSON.stringify(value);
|
|
1091
1115
|
} else {
|
|
1092
|
-
return
|
|
1116
|
+
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);
|
|
1093
1117
|
}
|
|
1094
1118
|
}
|
|
1095
1119
|
}
|
|
@@ -1235,7 +1259,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1235
1259
|
|
|
1236
1260
|
// src/client/crud/dialects/index.ts
|
|
1237
1261
|
function getCrudDialect(schema, options) {
|
|
1238
|
-
return
|
|
1262
|
+
return match5(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
|
|
1239
1263
|
}
|
|
1240
1264
|
__name(getCrudDialect, "getCrudDialect");
|
|
1241
1265
|
|
|
@@ -1560,17 +1584,17 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
|
|
|
1560
1584
|
// src/plugins/policy/expression-transformer.ts
|
|
1561
1585
|
import { invariant as invariant5 } from "@zenstackhq/common-helpers";
|
|
1562
1586
|
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";
|
|
1563
|
-
import { match as
|
|
1587
|
+
import { match as match7 } from "ts-pattern";
|
|
1564
1588
|
|
|
1565
1589
|
// src/plugins/policy/expression-evaluator.ts
|
|
1566
1590
|
import { invariant as invariant4 } from "@zenstackhq/common-helpers";
|
|
1567
|
-
import { match as
|
|
1591
|
+
import { match as match6 } from "ts-pattern";
|
|
1568
1592
|
var ExpressionEvaluator = class {
|
|
1569
1593
|
static {
|
|
1570
1594
|
__name(this, "ExpressionEvaluator");
|
|
1571
1595
|
}
|
|
1572
1596
|
evaluate(expression, context) {
|
|
1573
|
-
const result =
|
|
1597
|
+
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();
|
|
1574
1598
|
return result ?? null;
|
|
1575
1599
|
}
|
|
1576
1600
|
evaluateCall(expr2, context) {
|
|
@@ -1581,7 +1605,7 @@ var ExpressionEvaluator = class {
|
|
|
1581
1605
|
}
|
|
1582
1606
|
}
|
|
1583
1607
|
evaluateUnary(expr2, context) {
|
|
1584
|
-
return
|
|
1608
|
+
return match6(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
|
|
1585
1609
|
}
|
|
1586
1610
|
evaluateMember(expr2, context) {
|
|
1587
1611
|
let val = this.evaluate(expr2.receiver, context);
|
|
@@ -1605,7 +1629,7 @@ var ExpressionEvaluator = class {
|
|
|
1605
1629
|
}
|
|
1606
1630
|
const left = this.evaluate(expr2.left, context);
|
|
1607
1631
|
const right = this.evaluate(expr2.right, context);
|
|
1608
|
-
return
|
|
1632
|
+
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", () => {
|
|
1609
1633
|
const _right = right ?? [];
|
|
1610
1634
|
invariant4(Array.isArray(_right), 'expected array for "in" operator');
|
|
1611
1635
|
return _right.includes(left);
|
|
@@ -1619,7 +1643,7 @@ var ExpressionEvaluator = class {
|
|
|
1619
1643
|
return false;
|
|
1620
1644
|
}
|
|
1621
1645
|
invariant4(Array.isArray(left), "expected array");
|
|
1622
|
-
return
|
|
1646
|
+
return match6(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
|
|
1623
1647
|
...context,
|
|
1624
1648
|
thisValue: item
|
|
1625
1649
|
}))).with("!", () => left.every((item) => this.evaluate(expr2.right, {
|
|
@@ -1873,7 +1897,7 @@ var ExpressionTransformer = class {
|
|
|
1873
1897
|
const count = FunctionNode2.create("count", [
|
|
1874
1898
|
ValueNode2.createImmediate(1)
|
|
1875
1899
|
]);
|
|
1876
|
-
const predicateResult =
|
|
1900
|
+
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();
|
|
1877
1901
|
return this.transform(expr2.left, {
|
|
1878
1902
|
...context,
|
|
1879
1903
|
memberSelect: SelectionNode.create(AliasNode2.create(predicateResult, IdentifierNode.create("$t"))),
|
|
@@ -1904,7 +1928,7 @@ var ExpressionTransformer = class {
|
|
|
1904
1928
|
return BinaryOperationNode2.create(this.transform(expr2.operand, context), this.transformOperator("!="), trueNode(this.dialect));
|
|
1905
1929
|
}
|
|
1906
1930
|
transformOperator(op) {
|
|
1907
|
-
const mappedOp =
|
|
1931
|
+
const mappedOp = match7(op).with("==", () => "=").otherwise(() => op);
|
|
1908
1932
|
return OperatorNode2.create(mappedOp);
|
|
1909
1933
|
}
|
|
1910
1934
|
_call(expr2, context) {
|
|
@@ -2307,7 +2331,7 @@ var PolicyHandler = class extends OperationNodeTransformer {
|
|
|
2307
2331
|
return disjunction(this.dialect, rows.map((row) => conjunction(this.dialect, idFields.map((field) => BinaryOperationNode3.create(ColumnNode2.create(field), OperatorNode3.create("="), ValueNode3.create(row[field]))))));
|
|
2308
2332
|
}
|
|
2309
2333
|
getMutationModel(node) {
|
|
2310
|
-
const r =
|
|
2334
|
+
const r = match8(node).when(InsertQueryNode.is, (node2) => getTableName(node2.into)).when(UpdateQueryNode.is, (node2) => getTableName(node2.table)).when(DeleteQueryNode.is, (node2) => {
|
|
2311
2335
|
if (node2.from.froms.length !== 1) {
|
|
2312
2336
|
throw new InternalError("Only one from table is supported for delete");
|
|
2313
2337
|
}
|