@zenstackhq/language 3.1.1 → 3.2.1

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 CHANGED
@@ -4057,7 +4057,8 @@ var ZModelGrammar = /* @__PURE__ */ __name(() => loadedZModelGrammar ?? (loadedZ
4057
4057
  "terminal": {
4058
4058
  "$type": "Keyword",
4059
4059
  "value": "mutation"
4060
- }
4060
+ },
4061
+ "cardinality": "?"
4061
4062
  },
4062
4063
  {
4063
4064
  "$type": "Keyword",
@@ -4108,7 +4109,7 @@ var ZModelGrammar = /* @__PURE__ */ __name(() => loadedZModelGrammar ?? (loadedZ
4108
4109
  "terminal": {
4109
4110
  "$type": "RuleCall",
4110
4111
  "rule": {
4111
- "$ref": "#/rules@47"
4112
+ "$ref": "#/rules@49"
4112
4113
  },
4113
4114
  "arguments": []
4114
4115
  }
@@ -4286,6 +4287,10 @@ var ZModelGrammar = /* @__PURE__ */ __name(() => loadedZModelGrammar ?? (loadedZ
4286
4287
  "$type": "Keyword",
4287
4288
  "value": "Any"
4288
4289
  },
4290
+ {
4291
+ "$type": "Keyword",
4292
+ "value": "Void"
4293
+ },
4289
4294
  {
4290
4295
  "$type": "Keyword",
4291
4296
  "value": "Unsupported"
@@ -4896,10 +4901,26 @@ var ZModelGrammar = /* @__PURE__ */ __name(() => loadedZModelGrammar ?? (loadedZ
4896
4901
  "$type": "Keyword",
4897
4902
  "value": "Boolean"
4898
4903
  },
4904
+ {
4905
+ "$type": "Keyword",
4906
+ "value": "BigInt"
4907
+ },
4908
+ {
4909
+ "$type": "Keyword",
4910
+ "value": "Decimal"
4911
+ },
4899
4912
  {
4900
4913
  "$type": "Keyword",
4901
4914
  "value": "DateTime"
4902
4915
  },
4916
+ {
4917
+ "$type": "Keyword",
4918
+ "value": "Json"
4919
+ },
4920
+ {
4921
+ "$type": "Keyword",
4922
+ "value": "Bytes"
4923
+ },
4903
4924
  {
4904
4925
  "$type": "Keyword",
4905
4926
  "value": "Null"
@@ -4912,6 +4933,14 @@ var ZModelGrammar = /* @__PURE__ */ __name(() => loadedZModelGrammar ?? (loadedZ
4912
4933
  "$type": "Keyword",
4913
4934
  "value": "Any"
4914
4935
  },
4936
+ {
4937
+ "$type": "Keyword",
4938
+ "value": "Void"
4939
+ },
4940
+ {
4941
+ "$type": "Keyword",
4942
+ "value": "Undefined"
4943
+ },
4915
4944
  {
4916
4945
  "$type": "Keyword",
4917
4946
  "value": "Unsupported"
@@ -5248,6 +5277,10 @@ function mapBuiltinTypeToExpressionType(type) {
5248
5277
  case "Int":
5249
5278
  case "Float":
5250
5279
  case "Null":
5280
+ case "Object":
5281
+ case "Unsupported":
5282
+ case "Void":
5283
+ case "Undefined":
5251
5284
  return type;
5252
5285
  case "BigInt":
5253
5286
  return "Int";
@@ -5256,10 +5289,6 @@ function mapBuiltinTypeToExpressionType(type) {
5256
5289
  case "Json":
5257
5290
  case "Bytes":
5258
5291
  return "Any";
5259
- case "Object":
5260
- return "Object";
5261
- case "Unsupported":
5262
- return "Unsupported";
5263
5292
  }
5264
5293
  }
5265
5294
  __name(mapBuiltinTypeToExpressionType, "mapBuiltinTypeToExpressionType");
@@ -5279,6 +5308,10 @@ function isRelationshipField(field) {
5279
5308
  return isDataModel(field.type.reference?.ref);
5280
5309
  }
5281
5310
  __name(isRelationshipField, "isRelationshipField");
5311
+ function isComputedField(field) {
5312
+ return hasAttribute(field, "@computed");
5313
+ }
5314
+ __name(isComputedField, "isComputedField");
5282
5315
  function isDelegateModel(node) {
5283
5316
  return isDataModel(node) && hasAttribute(node, "@@delegate");
5284
5317
  }
@@ -5775,8 +5808,9 @@ var AttributeApplicationValidator = class {
5775
5808
  return;
5776
5809
  }
5777
5810
  }
5778
- if (!assignableToAttributeParam(arg, paramDecl, attr)) {
5779
- accept("error", `Value is not assignable to parameter`, {
5811
+ const argAssignable = assignableToAttributeParam(arg, paramDecl, attr);
5812
+ if (!argAssignable.result) {
5813
+ accept("error", argAssignable.error, {
5780
5814
  node: arg
5781
5815
  });
5782
5816
  return;
@@ -5900,24 +5934,27 @@ var AttributeApplicationValidator = class {
5900
5934
  });
5901
5935
  return;
5902
5936
  }
5903
- const kindItems = this.validatePolicyKinds(kind, [
5937
+ this.validatePolicyKinds(kind, [
5904
5938
  "read",
5905
5939
  "update",
5906
5940
  "all"
5907
5941
  ], attr, accept);
5908
5942
  const expr = attr.args[1]?.value;
5909
5943
  if (expr && import_langium3.AstUtils.streamAst(expr).some((node) => isBeforeInvocation(node))) {
5910
- accept("error", `"before()" is not allowed in field-level policy rules`, {
5944
+ accept("error", `"before()" is not allowed in field-level policies`, {
5911
5945
  node: expr
5912
5946
  });
5913
5947
  }
5914
- if (kindItems.includes("update") || kindItems.includes("all")) {
5915
- const field = attr.$container;
5916
- if (isRelationshipField(field)) {
5917
- accept("error", `Field-level policy rules with "update" or "all" kind are not allowed for relation fields. Put rules on foreign-key fields instead.`, {
5918
- node: attr
5919
- });
5920
- }
5948
+ const field = attr.$container;
5949
+ if (isRelationshipField(field)) {
5950
+ accept("error", `Field-level policies are not allowed for relation fields.`, {
5951
+ node: attr
5952
+ });
5953
+ }
5954
+ if (isComputedField(field)) {
5955
+ accept("error", `Field-level policies are not allowed for computed fields.`, {
5956
+ node: attr
5957
+ });
5921
5958
  }
5922
5959
  }
5923
5960
  _checkValidate(attr, accept) {
@@ -6072,37 +6109,86 @@ _ts_decorate([
6072
6109
  _ts_metadata("design:returntype", void 0)
6073
6110
  ], AttributeApplicationValidator.prototype, "_checkSchema", null);
6074
6111
  function assignableToAttributeParam(arg, param, attr) {
6112
+ const genericError = {
6113
+ result: false,
6114
+ error: "invalid argument type"
6115
+ };
6116
+ const success = {
6117
+ result: true
6118
+ };
6075
6119
  const argResolvedType = arg.$resolvedType;
6076
6120
  if (!argResolvedType) {
6077
- return false;
6121
+ return {
6122
+ result: false,
6123
+ error: "unable to resolve argument type"
6124
+ };
6078
6125
  }
6079
6126
  let dstType = param.type.type;
6080
6127
  let dstIsArray = param.type.array;
6081
6128
  if (dstType === "ContextType") {
6082
6129
  if (isDataField(attr.$container)) {
6083
- const dstIsTypedJson = hasAttribute(attr.$container, "@json");
6084
- if (dstIsTypedJson && attr.decl.ref?.name === "@default") {
6085
- return argResolvedType.decl === "String";
6130
+ const dstIsJson = attr.$container.type.type === "Json" || hasAttribute(attr.$container, "@json");
6131
+ if (dstIsJson && attr.decl.ref?.name === "@default") {
6132
+ if (attr.$container.type.array && attr.$container.type.type === "Json") {
6133
+ if (isArrayExpr(arg.value) && arg.value.items.every((item) => isLiteralJsonString(item))) {
6134
+ return success;
6135
+ } else {
6136
+ return {
6137
+ result: false,
6138
+ error: "expected an array of JSON string literals"
6139
+ };
6140
+ }
6141
+ } else {
6142
+ if (isLiteralJsonString(arg.value)) {
6143
+ return success;
6144
+ } else {
6145
+ return {
6146
+ result: false,
6147
+ error: "expected a JSON string literal"
6148
+ };
6149
+ }
6150
+ }
6086
6151
  }
6087
6152
  dstIsArray = attr.$container.type.array;
6088
6153
  }
6089
6154
  }
6090
6155
  const dstRef = param.type.reference;
6091
6156
  if (dstType === "Any" && !dstIsArray) {
6092
- return true;
6157
+ return success;
6093
6158
  }
6094
6159
  if (argResolvedType.decl === "Any") {
6095
6160
  if (!argResolvedType.array) {
6096
- return true;
6161
+ return success;
6097
6162
  } else {
6098
- return argResolvedType.array === dstIsArray;
6163
+ if (argResolvedType.array === dstIsArray) {
6164
+ return success;
6165
+ } else {
6166
+ return {
6167
+ result: false,
6168
+ error: `expected ${dstIsArray ? "array" : "non-array"}`
6169
+ };
6170
+ }
6099
6171
  }
6100
6172
  }
6101
6173
  if (dstType === "FieldReference" || dstType === "TransitiveFieldReference") {
6102
6174
  if (dstIsArray) {
6103
- return isArrayExpr(arg.value) && !arg.value.items.find((item) => !isReferenceExpr(item) || !isDataField(item.target.ref));
6175
+ if (isArrayExpr(arg.value) && !arg.value.items.some((item) => !isReferenceExpr(item) || !isDataField(item.target.ref))) {
6176
+ return success;
6177
+ } else {
6178
+ return {
6179
+ result: false,
6180
+ error: "expected an array of field references"
6181
+ };
6182
+ }
6104
6183
  } else {
6105
- return isReferenceExpr(arg.value) && isDataField(arg.value.target.ref);
6184
+ if (isReferenceExpr(arg.value) && isDataField(arg.value.target.ref)) {
6185
+ return success;
6186
+ } else {
6187
+ return {
6188
+ result: false,
6189
+ error: "expected a field reference"
6190
+ };
6191
+ }
6106
6192
  }
6107
6193
  }
6108
6194
  if (isEnum(argResolvedType.decl)) {
@@ -6111,15 +6197,24 @@ function assignableToAttributeParam(arg, param, attr) {
6111
6197
  attrArgDeclType = resolved(attr.$container.type.reference);
6112
6198
  dstIsArray = attr.$container.type.array;
6113
6199
  }
6114
- return attrArgDeclType === argResolvedType.decl && dstIsArray === argResolvedType.array;
6200
+ if (attrArgDeclType !== argResolvedType.decl) {
6201
+ return genericError;
6202
+ }
6203
+ if (dstIsArray !== argResolvedType.array) {
6204
+ return {
6205
+ result: false,
6206
+ error: `expected ${dstIsArray ? "array" : "non-array"}`
6207
+ };
6208
+ }
6209
+ return success;
6115
6210
  } else if (dstType) {
6116
6211
  if (typeof argResolvedType?.decl !== "string") {
6117
- return false;
6212
+ return genericError;
6118
6213
  }
6119
6214
  if (dstType === "ContextType") {
6120
6215
  if (isDataField(attr.$container)) {
6121
6216
  if (!attr.$container?.type?.type) {
6122
- return false;
6217
+ return genericError;
6123
6218
  }
6124
6219
  dstType = mapBuiltinTypeToExpressionType(attr.$container.type.type);
6125
6220
  dstIsArray = attr.$container.type.array;
@@ -6127,9 +6222,17 @@ function assignableToAttributeParam(arg, param, attr) {
6127
6222
  dstType = "Any";
6128
6223
  }
6129
6224
  }
6130
- return typeAssignable(dstType, argResolvedType.decl, arg.value) && dstIsArray === argResolvedType.array;
6225
+ if (typeAssignable(dstType, argResolvedType.decl, arg.value) && dstIsArray === argResolvedType.array) {
6226
+ return success;
6227
+ } else {
6228
+ return genericError;
6229
+ }
6131
6230
  } else {
6132
- return (dstRef?.ref === argResolvedType.decl || dstType === "Any") && dstIsArray === argResolvedType.array;
6231
+ if ((dstRef?.ref === argResolvedType.decl || dstType === "Any") && dstIsArray === argResolvedType.array) {
6232
+ return success;
6233
+ } else {
6234
+ return genericError;
6235
+ }
6133
6236
  }
6134
6237
  }
6135
6238
  __name(assignableToAttributeParam, "assignableToAttributeParam");
@@ -6192,6 +6295,18 @@ function validateAttributeApplication(attr, accept, contextDataModel) {
6192
6295
  new AttributeApplicationValidator().validate(attr, accept, contextDataModel);
6193
6296
  }
6194
6297
  __name(validateAttributeApplication, "validateAttributeApplication");
6298
+ function isLiteralJsonString(value) {
6299
+ if (!isStringLiteral(value)) {
6300
+ return false;
6301
+ }
6302
+ try {
6303
+ JSON.parse(value.value);
6304
+ return true;
6305
+ } catch {
6306
+ return false;
6307
+ }
6308
+ }
6309
+ __name(isLiteralJsonString, "isLiteralJsonString");
6195
6310
 
6196
6311
  // src/validators/attribute-validator.ts
6197
6312
  var AttributeValidator = class {
@@ -6213,7 +6328,7 @@ function validateDuplicatedDeclarations(container, decls, accept) {
6213
6328
  group[decl.name] = group[decl.name] ?? [];
6214
6329
  group[decl.name].push(decl);
6215
6330
  return group;
6216
- }, {});
6331
+ }, /* @__PURE__ */ Object.create(null));
6217
6332
  for (const [name, decls2] of Object.entries(groupByName)) {
6218
6333
  if (decls2.length > 1) {
6219
6334
  let errorField = decls2[1];
@@ -7096,7 +7211,9 @@ var FunctionInvocationValidator = class {
7096
7211
  return true;
7097
7212
  }
7098
7213
  if (typeof argResolvedType.decl === "string") {
7099
- if (!typeAssignable(dstType, argResolvedType.decl, arg.value) || dstIsArray !== argResolvedType.array) {
7214
+ const dstScalarType = mapBuiltinTypeToExpressionType(dstType);
7215
+ const srcScalarType = mapBuiltinTypeToExpressionType(argResolvedType.decl);
7216
+ if (!typeAssignable(dstScalarType, srcScalarType, arg.value) || dstIsArray !== argResolvedType.array) {
7100
7217
  accept("error", `argument is not assignable to parameter`, {
7101
7218
  node: arg
7102
7219
  });
@@ -7325,6 +7442,30 @@ _ts_decorate2([
7325
7442
  _ts_metadata2("design:returntype", void 0)
7326
7443
  ], FunctionInvocationValidator.prototype, "_checkCheck", null);
7327
7444
 
7445
+ // src/validators/procedure-validator.ts
7446
+ var RESERVED_PROCEDURE_NAMES = /* @__PURE__ */ new Set([
7447
+ "__proto__",
7448
+ "prototype",
7449
+ "constructor"
7450
+ ]);
7451
+ var ProcedureValidator = class {
7452
+ static {
7453
+ __name(this, "ProcedureValidator");
7454
+ }
7455
+ validate(proc, accept) {
7456
+ this.validateName(proc, accept);
7457
+ proc.attributes.forEach((attr) => validateAttributeApplication(attr, accept));
7458
+ }
7459
+ validateName(proc, accept) {
7460
+ if (RESERVED_PROCEDURE_NAMES.has(proc.name)) {
7461
+ accept("error", `Procedure name "${proc.name}" is reserved`, {
7462
+ node: proc,
7463
+ property: "name"
7464
+ });
7465
+ }
7466
+ }
7467
+ };
7468
+
7328
7469
  // src/validators/schema-validator.ts
7329
7470
  var SchemaValidator = class {
7330
7471
  static {
@@ -7412,7 +7553,8 @@ function registerValidationChecks(services) {
7412
7553
  Attribute: validator.checkAttribute,
7413
7554
  Expression: validator.checkExpression,
7414
7555
  InvocationExpr: validator.checkFunctionInvocation,
7415
- FunctionDecl: validator.checkFunctionDecl
7556
+ FunctionDecl: validator.checkFunctionDecl,
7557
+ Procedure: validator.checkProcedure
7416
7558
  };
7417
7559
  registry.register(checks, validator);
7418
7560
  }
@@ -7457,6 +7599,9 @@ var ZModelValidator = class {
7457
7599
  checkFunctionDecl(node, accept) {
7458
7600
  new FunctionDeclValidator().validate(node, accept);
7459
7601
  }
7602
+ checkProcedure(node, accept) {
7603
+ new ProcedureValidator().validate(node, accept);
7604
+ }
7460
7605
  };
7461
7606
 
7462
7607
  // src/zmodel-comment-provider.ts