@zenstackhq/language 3.0.0-beta.3 → 3.0.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +53 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +53 -18
- package/dist/index.js.map +1 -1
- package/dist/utils.cjs +1 -1
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.js +1 -1
- package/dist/utils.js.map +1 -1
- package/package.json +7 -6
- package/res/stdlib.zmodel +14 -16
package/dist/index.js
CHANGED
|
@@ -5354,7 +5354,7 @@ function getFunctionExpressionContext(funcDecl) {
|
|
|
5354
5354
|
}
|
|
5355
5355
|
__name(getFunctionExpressionContext, "getFunctionExpressionContext");
|
|
5356
5356
|
function isCheckInvocation(node) {
|
|
5357
|
-
return isInvocationExpr(node) && node.function.ref?.name === "check"
|
|
5357
|
+
return isInvocationExpr(node) && node.function.ref?.name === "check";
|
|
5358
5358
|
}
|
|
5359
5359
|
__name(isCheckInvocation, "isCheckInvocation");
|
|
5360
5360
|
function resolveTransitiveImports(documents, model) {
|
|
@@ -5649,6 +5649,7 @@ var AttributeApplicationValidator = class {
|
|
|
5649
5649
|
});
|
|
5650
5650
|
}
|
|
5651
5651
|
}
|
|
5652
|
+
// TODO: design a way to let plugin register validation
|
|
5652
5653
|
_checkModelLevelPolicy(attr, accept) {
|
|
5653
5654
|
const kind = getStringLiteral(attr.args[0]?.value);
|
|
5654
5655
|
if (!kind) {
|
|
@@ -5664,8 +5665,49 @@ var AttributeApplicationValidator = class {
|
|
|
5664
5665
|
"delete",
|
|
5665
5666
|
"all"
|
|
5666
5667
|
], attr, accept);
|
|
5667
|
-
|
|
5668
|
+
if ((kind === "create" || kind === "all") && attr.args[1]?.value) {
|
|
5669
|
+
this.rejectNonOwnedRelationInExpression(attr.args[1].value, accept);
|
|
5670
|
+
}
|
|
5671
|
+
}
|
|
5672
|
+
rejectNonOwnedRelationInExpression(expr, accept) {
|
|
5673
|
+
const contextModel = AstUtils2.getContainerOfType(expr, isDataModel);
|
|
5674
|
+
if (!contextModel) {
|
|
5675
|
+
return;
|
|
5676
|
+
}
|
|
5677
|
+
if (AstUtils2.streamAst(expr).some((node) => {
|
|
5678
|
+
if (!isDataFieldReference(node)) {
|
|
5679
|
+
return false;
|
|
5680
|
+
}
|
|
5681
|
+
if (node.target.ref?.$container !== contextModel) {
|
|
5682
|
+
return false;
|
|
5683
|
+
}
|
|
5684
|
+
const field = node.target.ref;
|
|
5685
|
+
if (!isRelationshipField(field)) {
|
|
5686
|
+
return false;
|
|
5687
|
+
}
|
|
5688
|
+
if (isAuthOrAuthMemberAccess(node)) {
|
|
5689
|
+
return false;
|
|
5690
|
+
}
|
|
5691
|
+
const startNode = isCollectionPredicate(node.$container) && node.$container.left === node ? node.$container : node;
|
|
5692
|
+
const collectionPredicate = AstUtils2.getContainerOfType(startNode.$container, isCollectionPredicate);
|
|
5693
|
+
if (collectionPredicate && isAuthOrAuthMemberAccess(collectionPredicate.left)) {
|
|
5694
|
+
return false;
|
|
5695
|
+
}
|
|
5696
|
+
const relationAttr = field.attributes.find((attr) => attr.decl.ref?.name === "@relation");
|
|
5697
|
+
if (!relationAttr) {
|
|
5698
|
+
return true;
|
|
5699
|
+
}
|
|
5700
|
+
if (!relationAttr.args.some((arg) => arg.name === "fields")) {
|
|
5701
|
+
return true;
|
|
5702
|
+
}
|
|
5703
|
+
return false;
|
|
5704
|
+
})) {
|
|
5705
|
+
accept("error", `non-owned relation fields are not allowed in "create" rules`, {
|
|
5706
|
+
node: expr
|
|
5707
|
+
});
|
|
5708
|
+
}
|
|
5668
5709
|
}
|
|
5710
|
+
// TODO: design a way to let plugin register validation
|
|
5669
5711
|
_checkFieldLevelPolicy(attr, accept) {
|
|
5670
5712
|
const kind = getStringLiteral(attr.args[0]?.value);
|
|
5671
5713
|
if (!kind) {
|
|
@@ -5693,7 +5735,6 @@ var AttributeApplicationValidator = class {
|
|
|
5693
5735
|
});
|
|
5694
5736
|
}
|
|
5695
5737
|
}
|
|
5696
|
-
this.rejectEncryptedFields(attr, accept);
|
|
5697
5738
|
}
|
|
5698
5739
|
_checkValidate(attr, accept) {
|
|
5699
5740
|
const condition = attr.args[0]?.value;
|
|
@@ -5743,15 +5784,6 @@ var AttributeApplicationValidator = class {
|
|
|
5743
5784
|
});
|
|
5744
5785
|
}
|
|
5745
5786
|
}
|
|
5746
|
-
rejectEncryptedFields(attr, accept) {
|
|
5747
|
-
AstUtils2.streamAllContents(attr).forEach((node) => {
|
|
5748
|
-
if (isDataFieldReference(node) && hasAttribute(node.target.ref, "@encrypted")) {
|
|
5749
|
-
accept("error", `Encrypted fields cannot be used in policy rules`, {
|
|
5750
|
-
node
|
|
5751
|
-
});
|
|
5752
|
-
}
|
|
5753
|
-
});
|
|
5754
|
-
}
|
|
5755
5787
|
validatePolicyKinds(kind, candidates, attr, accept) {
|
|
5756
5788
|
const items = kind.split(",").map((x) => x.trim());
|
|
5757
5789
|
items.forEach((item) => {
|
|
@@ -6509,23 +6541,25 @@ var ExpressionValidator = class {
|
|
|
6509
6541
|
"Any"
|
|
6510
6542
|
];
|
|
6511
6543
|
}
|
|
6512
|
-
|
|
6544
|
+
const leftResolvedDecl = expr.left.$resolvedType?.decl;
|
|
6545
|
+
const rightResolvedDecl = expr.right.$resolvedType?.decl;
|
|
6546
|
+
if (leftResolvedDecl && (typeof leftResolvedDecl !== "string" || !supportedShapes.includes(leftResolvedDecl))) {
|
|
6513
6547
|
accept("error", `invalid operand type for "${expr.operator}" operator`, {
|
|
6514
6548
|
node: expr.left
|
|
6515
6549
|
});
|
|
6516
6550
|
return;
|
|
6517
6551
|
}
|
|
6518
|
-
if (typeof
|
|
6552
|
+
if (rightResolvedDecl && (typeof rightResolvedDecl !== "string" || !supportedShapes.includes(rightResolvedDecl))) {
|
|
6519
6553
|
accept("error", `invalid operand type for "${expr.operator}" operator`, {
|
|
6520
6554
|
node: expr.right
|
|
6521
6555
|
});
|
|
6522
6556
|
return;
|
|
6523
6557
|
}
|
|
6524
|
-
if (
|
|
6558
|
+
if (leftResolvedDecl === "DateTime" && rightResolvedDecl && rightResolvedDecl !== "DateTime") {
|
|
6525
6559
|
accept("error", "incompatible operand types", {
|
|
6526
6560
|
node: expr
|
|
6527
6561
|
});
|
|
6528
|
-
} else if (
|
|
6562
|
+
} else if (rightResolvedDecl === "DateTime" && leftResolvedDecl && leftResolvedDecl !== "DateTime") {
|
|
6529
6563
|
accept("error", "incompatible operand types", {
|
|
6530
6564
|
node: expr
|
|
6531
6565
|
});
|
|
@@ -6565,11 +6599,11 @@ var ExpressionValidator = class {
|
|
|
6565
6599
|
});
|
|
6566
6600
|
}
|
|
6567
6601
|
if (isDataFieldReference(expr.left) && (isThisExpr(expr.right) || isDataFieldReference(expr.right))) {
|
|
6568
|
-
accept("error", "comparison between
|
|
6602
|
+
accept("error", "comparison between models is not supported", {
|
|
6569
6603
|
node: expr
|
|
6570
6604
|
});
|
|
6571
6605
|
} else if (isDataFieldReference(expr.right) && (isThisExpr(expr.left) || isDataFieldReference(expr.left))) {
|
|
6572
|
-
accept("error", "comparison between
|
|
6606
|
+
accept("error", "comparison between models is not supported", {
|
|
6573
6607
|
node: expr
|
|
6574
6608
|
});
|
|
6575
6609
|
}
|
|
@@ -6761,6 +6795,7 @@ var FunctionInvocationValidator = class {
|
|
|
6761
6795
|
}
|
|
6762
6796
|
return true;
|
|
6763
6797
|
}
|
|
6798
|
+
// TODO: move this to policy plugin
|
|
6764
6799
|
_checkCheck(expr, accept) {
|
|
6765
6800
|
let valid = true;
|
|
6766
6801
|
const fieldArg = expr.args[0].value;
|