@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.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { Model, DataSource, GeneratorDecl, DataModel, TypeDef, Enum, Attribute, Expression, InvocationExpr, FunctionDecl } from './ast.cjs';
1
+ import { Model, DataSource, GeneratorDecl, DataModel, TypeDef, Enum, Attribute, Expression, InvocationExpr, FunctionDecl, Procedure } from './ast.cjs';
2
2
  import { ValidationAcceptor, Module, DeepPartial, AstNode } from 'langium';
3
3
  import { LangiumServices, PartialLangiumServices, LangiumSharedServices, DefaultSharedModuleContext } from 'langium/lsp';
4
4
 
@@ -48,6 +48,7 @@ declare class ZModelValidator {
48
48
  checkExpression(node: Expression, accept: ValidationAcceptor): void;
49
49
  checkFunctionInvocation(node: InvocationExpr, accept: ValidationAcceptor): void;
50
50
  checkFunctionDecl(node: FunctionDecl, accept: ValidationAcceptor): void;
51
+ checkProcedure(node: Procedure, accept: ValidationAcceptor): void;
51
52
  }
52
53
 
53
54
  /**
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Model, DataSource, GeneratorDecl, DataModel, TypeDef, Enum, Attribute, Expression, InvocationExpr, FunctionDecl } from './ast.js';
1
+ import { Model, DataSource, GeneratorDecl, DataModel, TypeDef, Enum, Attribute, Expression, InvocationExpr, FunctionDecl, Procedure } from './ast.js';
2
2
  import { ValidationAcceptor, Module, DeepPartial, AstNode } from 'langium';
3
3
  import { LangiumServices, PartialLangiumServices, LangiumSharedServices, DefaultSharedModuleContext } from 'langium/lsp';
4
4
 
@@ -48,6 +48,7 @@ declare class ZModelValidator {
48
48
  checkExpression(node: Expression, accept: ValidationAcceptor): void;
49
49
  checkFunctionInvocation(node: InvocationExpr, accept: ValidationAcceptor): void;
50
50
  checkFunctionDecl(node: FunctionDecl, accept: ValidationAcceptor): void;
51
+ checkProcedure(node: Procedure, accept: ValidationAcceptor): void;
51
52
  }
52
53
 
53
54
  /**
package/dist/index.js CHANGED
@@ -4022,7 +4022,8 @@ var ZModelGrammar = /* @__PURE__ */ __name(() => loadedZModelGrammar ?? (loadedZ
4022
4022
  "terminal": {
4023
4023
  "$type": "Keyword",
4024
4024
  "value": "mutation"
4025
- }
4025
+ },
4026
+ "cardinality": "?"
4026
4027
  },
4027
4028
  {
4028
4029
  "$type": "Keyword",
@@ -4073,7 +4074,7 @@ var ZModelGrammar = /* @__PURE__ */ __name(() => loadedZModelGrammar ?? (loadedZ
4073
4074
  "terminal": {
4074
4075
  "$type": "RuleCall",
4075
4076
  "rule": {
4076
- "$ref": "#/rules@47"
4077
+ "$ref": "#/rules@49"
4077
4078
  },
4078
4079
  "arguments": []
4079
4080
  }
@@ -4251,6 +4252,10 @@ var ZModelGrammar = /* @__PURE__ */ __name(() => loadedZModelGrammar ?? (loadedZ
4251
4252
  "$type": "Keyword",
4252
4253
  "value": "Any"
4253
4254
  },
4255
+ {
4256
+ "$type": "Keyword",
4257
+ "value": "Void"
4258
+ },
4254
4259
  {
4255
4260
  "$type": "Keyword",
4256
4261
  "value": "Unsupported"
@@ -4861,10 +4866,26 @@ var ZModelGrammar = /* @__PURE__ */ __name(() => loadedZModelGrammar ?? (loadedZ
4861
4866
  "$type": "Keyword",
4862
4867
  "value": "Boolean"
4863
4868
  },
4869
+ {
4870
+ "$type": "Keyword",
4871
+ "value": "BigInt"
4872
+ },
4873
+ {
4874
+ "$type": "Keyword",
4875
+ "value": "Decimal"
4876
+ },
4864
4877
  {
4865
4878
  "$type": "Keyword",
4866
4879
  "value": "DateTime"
4867
4880
  },
4881
+ {
4882
+ "$type": "Keyword",
4883
+ "value": "Json"
4884
+ },
4885
+ {
4886
+ "$type": "Keyword",
4887
+ "value": "Bytes"
4888
+ },
4868
4889
  {
4869
4890
  "$type": "Keyword",
4870
4891
  "value": "Null"
@@ -4877,6 +4898,14 @@ var ZModelGrammar = /* @__PURE__ */ __name(() => loadedZModelGrammar ?? (loadedZ
4877
4898
  "$type": "Keyword",
4878
4899
  "value": "Any"
4879
4900
  },
4901
+ {
4902
+ "$type": "Keyword",
4903
+ "value": "Void"
4904
+ },
4905
+ {
4906
+ "$type": "Keyword",
4907
+ "value": "Undefined"
4908
+ },
4880
4909
  {
4881
4910
  "$type": "Keyword",
4882
4911
  "value": "Unsupported"
@@ -5212,6 +5241,10 @@ function mapBuiltinTypeToExpressionType(type) {
5212
5241
  case "Int":
5213
5242
  case "Float":
5214
5243
  case "Null":
5244
+ case "Object":
5245
+ case "Unsupported":
5246
+ case "Void":
5247
+ case "Undefined":
5215
5248
  return type;
5216
5249
  case "BigInt":
5217
5250
  return "Int";
@@ -5220,10 +5253,6 @@ function mapBuiltinTypeToExpressionType(type) {
5220
5253
  case "Json":
5221
5254
  case "Bytes":
5222
5255
  return "Any";
5223
- case "Object":
5224
- return "Object";
5225
- case "Unsupported":
5226
- return "Unsupported";
5227
5256
  }
5228
5257
  }
5229
5258
  __name(mapBuiltinTypeToExpressionType, "mapBuiltinTypeToExpressionType");
@@ -5243,6 +5272,10 @@ function isRelationshipField(field) {
5243
5272
  return isDataModel(field.type.reference?.ref);
5244
5273
  }
5245
5274
  __name(isRelationshipField, "isRelationshipField");
5275
+ function isComputedField(field) {
5276
+ return hasAttribute(field, "@computed");
5277
+ }
5278
+ __name(isComputedField, "isComputedField");
5246
5279
  function isDelegateModel(node) {
5247
5280
  return isDataModel(node) && hasAttribute(node, "@@delegate");
5248
5281
  }
@@ -5739,8 +5772,9 @@ var AttributeApplicationValidator = class {
5739
5772
  return;
5740
5773
  }
5741
5774
  }
5742
- if (!assignableToAttributeParam(arg, paramDecl, attr)) {
5743
- accept("error", `Value is not assignable to parameter`, {
5775
+ const argAssignable = assignableToAttributeParam(arg, paramDecl, attr);
5776
+ if (!argAssignable.result) {
5777
+ accept("error", argAssignable.error, {
5744
5778
  node: arg
5745
5779
  });
5746
5780
  return;
@@ -5864,24 +5898,27 @@ var AttributeApplicationValidator = class {
5864
5898
  });
5865
5899
  return;
5866
5900
  }
5867
- const kindItems = this.validatePolicyKinds(kind, [
5901
+ this.validatePolicyKinds(kind, [
5868
5902
  "read",
5869
5903
  "update",
5870
5904
  "all"
5871
5905
  ], attr, accept);
5872
5906
  const expr = attr.args[1]?.value;
5873
5907
  if (expr && AstUtils2.streamAst(expr).some((node) => isBeforeInvocation(node))) {
5874
- accept("error", `"before()" is not allowed in field-level policy rules`, {
5908
+ accept("error", `"before()" is not allowed in field-level policies`, {
5875
5909
  node: expr
5876
5910
  });
5877
5911
  }
5878
- if (kindItems.includes("update") || kindItems.includes("all")) {
5879
- const field = attr.$container;
5880
- if (isRelationshipField(field)) {
5881
- accept("error", `Field-level policy rules with "update" or "all" kind are not allowed for relation fields. Put rules on foreign-key fields instead.`, {
5882
- node: attr
5883
- });
5884
- }
5912
+ const field = attr.$container;
5913
+ if (isRelationshipField(field)) {
5914
+ accept("error", `Field-level policies are not allowed for relation fields.`, {
5915
+ node: attr
5916
+ });
5917
+ }
5918
+ if (isComputedField(field)) {
5919
+ accept("error", `Field-level policies are not allowed for computed fields.`, {
5920
+ node: attr
5921
+ });
5885
5922
  }
5886
5923
  }
5887
5924
  _checkValidate(attr, accept) {
@@ -6036,37 +6073,86 @@ _ts_decorate([
6036
6073
  _ts_metadata("design:returntype", void 0)
6037
6074
  ], AttributeApplicationValidator.prototype, "_checkSchema", null);
6038
6075
  function assignableToAttributeParam(arg, param, attr) {
6076
+ const genericError = {
6077
+ result: false,
6078
+ error: "invalid argument type"
6079
+ };
6080
+ const success = {
6081
+ result: true
6082
+ };
6039
6083
  const argResolvedType = arg.$resolvedType;
6040
6084
  if (!argResolvedType) {
6041
- return false;
6085
+ return {
6086
+ result: false,
6087
+ error: "unable to resolve argument type"
6088
+ };
6042
6089
  }
6043
6090
  let dstType = param.type.type;
6044
6091
  let dstIsArray = param.type.array;
6045
6092
  if (dstType === "ContextType") {
6046
6093
  if (isDataField(attr.$container)) {
6047
- const dstIsTypedJson = hasAttribute(attr.$container, "@json");
6048
- if (dstIsTypedJson && attr.decl.ref?.name === "@default") {
6049
- return argResolvedType.decl === "String";
6094
+ const dstIsJson = attr.$container.type.type === "Json" || hasAttribute(attr.$container, "@json");
6095
+ if (dstIsJson && attr.decl.ref?.name === "@default") {
6096
+ if (attr.$container.type.array && attr.$container.type.type === "Json") {
6097
+ if (isArrayExpr(arg.value) && arg.value.items.every((item) => isLiteralJsonString(item))) {
6098
+ return success;
6099
+ } else {
6100
+ return {
6101
+ result: false,
6102
+ error: "expected an array of JSON string literals"
6103
+ };
6104
+ }
6105
+ } else {
6106
+ if (isLiteralJsonString(arg.value)) {
6107
+ return success;
6108
+ } else {
6109
+ return {
6110
+ result: false,
6111
+ error: "expected a JSON string literal"
6112
+ };
6113
+ }
6114
+ }
6050
6115
  }
6051
6116
  dstIsArray = attr.$container.type.array;
6052
6117
  }
6053
6118
  }
6054
6119
  const dstRef = param.type.reference;
6055
6120
  if (dstType === "Any" && !dstIsArray) {
6056
- return true;
6121
+ return success;
6057
6122
  }
6058
6123
  if (argResolvedType.decl === "Any") {
6059
6124
  if (!argResolvedType.array) {
6060
- return true;
6125
+ return success;
6061
6126
  } else {
6062
- return argResolvedType.array === dstIsArray;
6127
+ if (argResolvedType.array === dstIsArray) {
6128
+ return success;
6129
+ } else {
6130
+ return {
6131
+ result: false,
6132
+ error: `expected ${dstIsArray ? "array" : "non-array"}`
6133
+ };
6134
+ }
6063
6135
  }
6064
6136
  }
6065
6137
  if (dstType === "FieldReference" || dstType === "TransitiveFieldReference") {
6066
6138
  if (dstIsArray) {
6067
- return isArrayExpr(arg.value) && !arg.value.items.find((item) => !isReferenceExpr(item) || !isDataField(item.target.ref));
6139
+ if (isArrayExpr(arg.value) && !arg.value.items.some((item) => !isReferenceExpr(item) || !isDataField(item.target.ref))) {
6140
+ return success;
6141
+ } else {
6142
+ return {
6143
+ result: false,
6144
+ error: "expected an array of field references"
6145
+ };
6146
+ }
6068
6147
  } else {
6069
- return isReferenceExpr(arg.value) && isDataField(arg.value.target.ref);
6148
+ if (isReferenceExpr(arg.value) && isDataField(arg.value.target.ref)) {
6149
+ return success;
6150
+ } else {
6151
+ return {
6152
+ result: false,
6153
+ error: "expected a field reference"
6154
+ };
6155
+ }
6070
6156
  }
6071
6157
  }
6072
6158
  if (isEnum(argResolvedType.decl)) {
@@ -6075,15 +6161,24 @@ function assignableToAttributeParam(arg, param, attr) {
6075
6161
  attrArgDeclType = resolved(attr.$container.type.reference);
6076
6162
  dstIsArray = attr.$container.type.array;
6077
6163
  }
6078
- return attrArgDeclType === argResolvedType.decl && dstIsArray === argResolvedType.array;
6164
+ if (attrArgDeclType !== argResolvedType.decl) {
6165
+ return genericError;
6166
+ }
6167
+ if (dstIsArray !== argResolvedType.array) {
6168
+ return {
6169
+ result: false,
6170
+ error: `expected ${dstIsArray ? "array" : "non-array"}`
6171
+ };
6172
+ }
6173
+ return success;
6079
6174
  } else if (dstType) {
6080
6175
  if (typeof argResolvedType?.decl !== "string") {
6081
- return false;
6176
+ return genericError;
6082
6177
  }
6083
6178
  if (dstType === "ContextType") {
6084
6179
  if (isDataField(attr.$container)) {
6085
6180
  if (!attr.$container?.type?.type) {
6086
- return false;
6181
+ return genericError;
6087
6182
  }
6088
6183
  dstType = mapBuiltinTypeToExpressionType(attr.$container.type.type);
6089
6184
  dstIsArray = attr.$container.type.array;
@@ -6091,9 +6186,17 @@ function assignableToAttributeParam(arg, param, attr) {
6091
6186
  dstType = "Any";
6092
6187
  }
6093
6188
  }
6094
- return typeAssignable(dstType, argResolvedType.decl, arg.value) && dstIsArray === argResolvedType.array;
6189
+ if (typeAssignable(dstType, argResolvedType.decl, arg.value) && dstIsArray === argResolvedType.array) {
6190
+ return success;
6191
+ } else {
6192
+ return genericError;
6193
+ }
6095
6194
  } else {
6096
- return (dstRef?.ref === argResolvedType.decl || dstType === "Any") && dstIsArray === argResolvedType.array;
6195
+ if ((dstRef?.ref === argResolvedType.decl || dstType === "Any") && dstIsArray === argResolvedType.array) {
6196
+ return success;
6197
+ } else {
6198
+ return genericError;
6199
+ }
6097
6200
  }
6098
6201
  }
6099
6202
  __name(assignableToAttributeParam, "assignableToAttributeParam");
@@ -6156,6 +6259,18 @@ function validateAttributeApplication(attr, accept, contextDataModel) {
6156
6259
  new AttributeApplicationValidator().validate(attr, accept, contextDataModel);
6157
6260
  }
6158
6261
  __name(validateAttributeApplication, "validateAttributeApplication");
6262
+ function isLiteralJsonString(value) {
6263
+ if (!isStringLiteral(value)) {
6264
+ return false;
6265
+ }
6266
+ try {
6267
+ JSON.parse(value.value);
6268
+ return true;
6269
+ } catch {
6270
+ return false;
6271
+ }
6272
+ }
6273
+ __name(isLiteralJsonString, "isLiteralJsonString");
6159
6274
 
6160
6275
  // src/validators/attribute-validator.ts
6161
6276
  var AttributeValidator = class {
@@ -6177,7 +6292,7 @@ function validateDuplicatedDeclarations(container, decls, accept) {
6177
6292
  group[decl.name] = group[decl.name] ?? [];
6178
6293
  group[decl.name].push(decl);
6179
6294
  return group;
6180
- }, {});
6295
+ }, /* @__PURE__ */ Object.create(null));
6181
6296
  for (const [name, decls2] of Object.entries(groupByName)) {
6182
6297
  if (decls2.length > 1) {
6183
6298
  let errorField = decls2[1];
@@ -7060,7 +7175,9 @@ var FunctionInvocationValidator = class {
7060
7175
  return true;
7061
7176
  }
7062
7177
  if (typeof argResolvedType.decl === "string") {
7063
- if (!typeAssignable(dstType, argResolvedType.decl, arg.value) || dstIsArray !== argResolvedType.array) {
7178
+ const dstScalarType = mapBuiltinTypeToExpressionType(dstType);
7179
+ const srcScalarType = mapBuiltinTypeToExpressionType(argResolvedType.decl);
7180
+ if (!typeAssignable(dstScalarType, srcScalarType, arg.value) || dstIsArray !== argResolvedType.array) {
7064
7181
  accept("error", `argument is not assignable to parameter`, {
7065
7182
  node: arg
7066
7183
  });
@@ -7289,6 +7406,30 @@ _ts_decorate2([
7289
7406
  _ts_metadata2("design:returntype", void 0)
7290
7407
  ], FunctionInvocationValidator.prototype, "_checkCheck", null);
7291
7408
 
7409
+ // src/validators/procedure-validator.ts
7410
+ var RESERVED_PROCEDURE_NAMES = /* @__PURE__ */ new Set([
7411
+ "__proto__",
7412
+ "prototype",
7413
+ "constructor"
7414
+ ]);
7415
+ var ProcedureValidator = class {
7416
+ static {
7417
+ __name(this, "ProcedureValidator");
7418
+ }
7419
+ validate(proc, accept) {
7420
+ this.validateName(proc, accept);
7421
+ proc.attributes.forEach((attr) => validateAttributeApplication(attr, accept));
7422
+ }
7423
+ validateName(proc, accept) {
7424
+ if (RESERVED_PROCEDURE_NAMES.has(proc.name)) {
7425
+ accept("error", `Procedure name "${proc.name}" is reserved`, {
7426
+ node: proc,
7427
+ property: "name"
7428
+ });
7429
+ }
7430
+ }
7431
+ };
7432
+
7292
7433
  // src/validators/schema-validator.ts
7293
7434
  var SchemaValidator = class {
7294
7435
  static {
@@ -7376,7 +7517,8 @@ function registerValidationChecks(services) {
7376
7517
  Attribute: validator.checkAttribute,
7377
7518
  Expression: validator.checkExpression,
7378
7519
  InvocationExpr: validator.checkFunctionInvocation,
7379
- FunctionDecl: validator.checkFunctionDecl
7520
+ FunctionDecl: validator.checkFunctionDecl,
7521
+ Procedure: validator.checkProcedure
7380
7522
  };
7381
7523
  registry.register(checks, validator);
7382
7524
  }
@@ -7421,6 +7563,9 @@ var ZModelValidator = class {
7421
7563
  checkFunctionDecl(node, accept) {
7422
7564
  new FunctionDeclValidator().validate(node, accept);
7423
7565
  }
7566
+ checkProcedure(node, accept) {
7567
+ new ProcedureValidator().validate(node, accept);
7568
+ }
7424
7569
  };
7425
7570
 
7426
7571
  // src/zmodel-comment-provider.ts