@zenstackhq/language 3.0.0-beta.8 → 3.0.0-beta.9

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
@@ -5240,8 +5240,14 @@ function getRecursiveBases(decl, includeDelegate = true, seen = /* @__PURE__ */
5240
5240
  return result;
5241
5241
  }
5242
5242
  seen.add(decl);
5243
- decl.mixins.forEach((mixin) => {
5244
- const baseDecl = decl.$container.declarations.find((d) => isTypeDef(d) && d.name === mixin.$refText);
5243
+ const bases = [
5244
+ ...decl.mixins,
5245
+ ...isDataModel(decl) && decl.baseModel ? [
5246
+ decl.baseModel
5247
+ ] : []
5248
+ ];
5249
+ bases.forEach((base) => {
5250
+ const baseDecl = decl.$container.declarations.find((d) => isTypeDef(d) || isDataModel(d) && d.name === base.$refText);
5245
5251
  if (baseDecl) {
5246
5252
  if (!includeDelegate && isDelegateModel(baseDecl)) {
5247
5253
  return;
@@ -5884,6 +5890,10 @@ function assignableToAttributeParam(arg, param, attr) {
5884
5890
  let dstIsArray = param.type.array;
5885
5891
  if (dstType === "ContextType") {
5886
5892
  if (isDataField(attr.$container)) {
5893
+ const dstIsTypedJson = hasAttribute(attr.$container, "@json");
5894
+ if (dstIsTypedJson && attr.decl.ref?.name === "@default") {
5895
+ return argResolvedType.decl === "String";
5896
+ }
5887
5897
  dstIsArray = attr.$container.type.array;
5888
5898
  }
5889
5899
  }
@@ -5975,6 +5985,9 @@ function isValidAttributeTarget(attrDecl, targetDecl) {
5975
5985
  case "TypeDefField":
5976
5986
  allowed = allowed || isTypeDef(targetDecl.type.reference?.ref);
5977
5987
  break;
5988
+ case "ListField":
5989
+ allowed = allowed || !isDataModel(targetDecl.type.reference?.ref) && targetDecl.type.array;
5990
+ break;
5978
5991
  default:
5979
5992
  break;
5980
5993
  }
@@ -6753,7 +6766,7 @@ var FunctionInvocationValidator = class {
6753
6766
  }
6754
6767
  curr = curr.$container;
6755
6768
  }
6756
- const exprContext = (0, import_ts_pattern.match)(containerAttribute?.decl.$refText).with("@default", () => ExpressionContext.DefaultValue).with(import_ts_pattern.P.union("@@allow", "@@deny", "@allow", "@deny"), () => ExpressionContext.AccessPolicy).with("@@validate", () => ExpressionContext.ValidationRule).with("@@index", () => ExpressionContext.Index).otherwise(() => void 0);
6769
+ const exprContext = this.getExpressionContext(containerAttribute);
6757
6770
  const funcAllowedContext = getFunctionExpressionContext(funcDecl);
6758
6771
  if (exprContext && !funcAllowedContext.includes(exprContext)) {
6759
6772
  accept("error", `function "${funcDecl.name}" is not allowed in the current context: ${exprContext}`, {
@@ -6785,6 +6798,18 @@ var FunctionInvocationValidator = class {
6785
6798
  checker.value.call(this, expr, accept);
6786
6799
  }
6787
6800
  }
6801
+ getExpressionContext(containerAttribute) {
6802
+ if (!containerAttribute) {
6803
+ return void 0;
6804
+ }
6805
+ if (this.isValidationAttribute(containerAttribute)) {
6806
+ return ExpressionContext.ValidationRule;
6807
+ }
6808
+ return (0, import_ts_pattern.match)(containerAttribute?.decl.$refText).with("@default", () => ExpressionContext.DefaultValue).with(import_ts_pattern.P.union("@@allow", "@@deny", "@allow", "@deny"), () => ExpressionContext.AccessPolicy).with("@@index", () => ExpressionContext.Index).otherwise(() => void 0);
6809
+ }
6810
+ isValidationAttribute(attr) {
6811
+ return !!attr.decl.ref?.attributes.some((attr2) => attr2.decl.$refText === "@@@validation");
6812
+ }
6788
6813
  validateArgs(funcDecl, args, accept) {
6789
6814
  let success = true;
6790
6815
  for (let i = 0; i < funcDecl.params.length; i++) {
@@ -6845,6 +6870,43 @@ var FunctionInvocationValidator = class {
6845
6870
  }
6846
6871
  return true;
6847
6872
  }
6873
+ _checkLength(expr, accept) {
6874
+ const msg = "argument must be a string or list field";
6875
+ const fieldArg = expr.args[0].value;
6876
+ if (!isDataFieldReference(fieldArg)) {
6877
+ accept("error", msg, {
6878
+ node: expr.args[0]
6879
+ });
6880
+ return;
6881
+ }
6882
+ if (isDataModel(fieldArg.$resolvedType?.decl)) {
6883
+ accept("error", msg, {
6884
+ node: expr.args[0]
6885
+ });
6886
+ return;
6887
+ }
6888
+ if (!fieldArg.$resolvedType?.array && fieldArg.$resolvedType?.decl !== "String") {
6889
+ accept("error", msg, {
6890
+ node: expr.args[0]
6891
+ });
6892
+ }
6893
+ }
6894
+ _checkRegex(expr, accept) {
6895
+ const regex = expr.args[1]?.value;
6896
+ if (!isStringLiteral(regex)) {
6897
+ accept("error", "second argument must be a string literal", {
6898
+ node: expr.args[1]
6899
+ });
6900
+ return;
6901
+ }
6902
+ try {
6903
+ new RegExp(regex.value);
6904
+ } catch (e) {
6905
+ accept("error", "invalid regular expression: " + e.message, {
6906
+ node: expr.args[1]
6907
+ });
6908
+ }
6909
+ }
6848
6910
  // TODO: move this to policy plugin
6849
6911
  _checkCheck(expr, accept) {
6850
6912
  let valid = true;
@@ -6917,6 +6979,24 @@ var FunctionInvocationValidator = class {
6917
6979
  }
6918
6980
  }
6919
6981
  };
6982
+ _ts_decorate2([
6983
+ func("length"),
6984
+ _ts_metadata2("design:type", Function),
6985
+ _ts_metadata2("design:paramtypes", [
6986
+ typeof InvocationExpr === "undefined" ? Object : InvocationExpr,
6987
+ typeof ValidationAcceptor === "undefined" ? Object : ValidationAcceptor
6988
+ ]),
6989
+ _ts_metadata2("design:returntype", void 0)
6990
+ ], FunctionInvocationValidator.prototype, "_checkLength", null);
6991
+ _ts_decorate2([
6992
+ func("regex"),
6993
+ _ts_metadata2("design:type", Function),
6994
+ _ts_metadata2("design:paramtypes", [
6995
+ typeof InvocationExpr === "undefined" ? Object : InvocationExpr,
6996
+ typeof ValidationAcceptor === "undefined" ? Object : ValidationAcceptor
6997
+ ]),
6998
+ _ts_metadata2("design:returntype", void 0)
6999
+ ], FunctionInvocationValidator.prototype, "_checkRegex", null);
6920
7000
  _ts_decorate2([
6921
7001
  func("check"),
6922
7002
  _ts_metadata2("design:type", Function),
@@ -7467,7 +7547,7 @@ var ZModelScopeComputation = class extends import_langium9.DefaultScopeComputati
7467
7547
  }
7468
7548
  processNode(node, document, scopes) {
7469
7549
  super.processNode(node, document, scopes);
7470
- if (isDataModel(node)) {
7550
+ if (isDataModel(node) || isTypeDef(node)) {
7471
7551
  const bases = getRecursiveBases(node);
7472
7552
  for (const base of bases) {
7473
7553
  for (const field of base.fields) {
@@ -7770,7 +7850,7 @@ var DocumentLoadError = class extends Error {
7770
7850
  super(message);
7771
7851
  }
7772
7852
  };
7773
- async function loadDocument(fileName, pluginModelFiles = []) {
7853
+ async function loadDocument(fileName, additionalModelFiles = []) {
7774
7854
  const { ZModelLanguage: services } = createZModelServices();
7775
7855
  const extensions = services.LanguageMetaData.fileExtensions;
7776
7856
  if (!extensions.includes(import_node_path2.default.extname(fileName))) {
@@ -7793,7 +7873,7 @@ async function loadDocument(fileName, pluginModelFiles = []) {
7793
7873
  }
7794
7874
  const _dirname = typeof __dirname !== "undefined" ? __dirname : import_node_path2.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
7795
7875
  const stdLib = await services.shared.workspace.LangiumDocuments.getOrCreateDocument(import_langium12.URI.file(import_node_path2.default.resolve(import_node_path2.default.join(_dirname, "../res", STD_LIB_MODULE_NAME))));
7796
- const pluginDocs = await Promise.all(pluginModelFiles.map((file) => services.shared.workspace.LangiumDocuments.getOrCreateDocument(import_langium12.URI.file(import_node_path2.default.resolve(file)))));
7876
+ const pluginDocs = await Promise.all(additionalModelFiles.map((file) => services.shared.workspace.LangiumDocuments.getOrCreateDocument(import_langium12.URI.file(import_node_path2.default.resolve(file)))));
7797
7877
  const langiumDocuments = services.shared.workspace.LangiumDocuments;
7798
7878
  const document = await langiumDocuments.getOrCreateDocument(import_langium12.URI.file(import_node_path2.default.resolve(fileName)));
7799
7879
  const importedURIs = await loadImports(document, langiumDocuments);