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

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.js CHANGED
@@ -5191,10 +5191,6 @@ function isRelationshipField(field) {
5191
5191
  return isDataModel(field.type.reference?.ref);
5192
5192
  }
5193
5193
  __name(isRelationshipField, "isRelationshipField");
5194
- function isFutureExpr(node) {
5195
- return isInvocationExpr(node) && node.function.ref?.name === "future" && isFromStdlib(node.function.ref);
5196
- }
5197
- __name(isFutureExpr, "isFutureExpr");
5198
5194
  function isDelegateModel(node) {
5199
5195
  return isDataModel(node) && hasAttribute(node, "@@delegate");
5200
5196
  }
@@ -5430,10 +5426,10 @@ function getAuthDecl(decls) {
5430
5426
  return authModel;
5431
5427
  }
5432
5428
  __name(getAuthDecl, "getAuthDecl");
5433
- function isFutureInvocation(node) {
5434
- return isInvocationExpr(node) && node.function.ref?.name === "future" && isFromStdlib(node.function.ref);
5429
+ function isBeforeInvocation(node) {
5430
+ return isInvocationExpr(node) && node.function.ref?.name === "before" && isFromStdlib(node.function.ref);
5435
5431
  }
5436
- __name(isFutureInvocation, "isFutureInvocation");
5432
+ __name(isBeforeInvocation, "isBeforeInvocation");
5437
5433
  function isCollectionPredicate(node) {
5438
5434
  return isBinaryExpr(node) && [
5439
5435
  "?",
@@ -5665,12 +5661,21 @@ var AttributeApplicationValidator = class {
5665
5661
  "create",
5666
5662
  "read",
5667
5663
  "update",
5664
+ "post-update",
5668
5665
  "delete",
5669
5666
  "all"
5670
5667
  ], attr, accept);
5671
5668
  if ((kind === "create" || kind === "all") && attr.args[1]?.value) {
5672
5669
  this.rejectNonOwnedRelationInExpression(attr.args[1].value, accept);
5673
5670
  }
5671
+ if (kind !== "post-update" && attr.args[1]?.value) {
5672
+ const beforeCall = AstUtils2.streamAst(attr.args[1]?.value).find(isBeforeInvocation);
5673
+ if (beforeCall) {
5674
+ accept("error", `"before()" is only allowed in "post-update" policy rules`, {
5675
+ node: beforeCall
5676
+ });
5677
+ }
5678
+ }
5674
5679
  }
5675
5680
  rejectNonOwnedRelationInExpression(expr, accept) {
5676
5681
  const contextModel = AstUtils2.getContainerOfType(expr, isDataModel);
@@ -5725,8 +5730,8 @@ var AttributeApplicationValidator = class {
5725
5730
  "all"
5726
5731
  ], attr, accept);
5727
5732
  const expr = attr.args[1]?.value;
5728
- if (expr && AstUtils2.streamAst(expr).some((node) => isFutureExpr(node))) {
5729
- accept("error", `"future()" is not allowed in field-level policy rules`, {
5733
+ if (expr && AstUtils2.streamAst(expr).some((node) => isBeforeInvocation(node))) {
5734
+ accept("error", `"before()" is not allowed in field-level policy rules`, {
5730
5735
  node: expr
5731
5736
  });
5732
5737
  }
@@ -6487,11 +6492,21 @@ var ExpressionValidator = class {
6487
6492
  }
6488
6493
  }
6489
6494
  switch (expr.$type) {
6495
+ case "MemberAccessExpr":
6496
+ this.validateMemberAccessExpr(expr, accept);
6497
+ break;
6490
6498
  case "BinaryExpr":
6491
6499
  this.validateBinaryExpr(expr, accept);
6492
6500
  break;
6493
6501
  }
6494
6502
  }
6503
+ validateMemberAccessExpr(expr, accept) {
6504
+ if (isBeforeInvocation(expr.operand) && isDataModel(expr.$resolvedType?.decl)) {
6505
+ accept("error", "relation fields cannot be accessed from `before()`", {
6506
+ node: expr
6507
+ });
6508
+ }
6509
+ }
6495
6510
  validateBinaryExpr(expr, accept) {
6496
6511
  switch (expr.operator) {
6497
6512
  case "in": {
@@ -7014,23 +7029,31 @@ var ZModelDocumentBuilder = class extends DefaultDocumentBuilder {
7014
7029
  static {
7015
7030
  __name(this, "ZModelDocumentBuilder");
7016
7031
  }
7017
- buildDocuments(documents, options, cancelToken) {
7018
- return super.buildDocuments(documents, {
7019
- ...options,
7020
- validation: (
7021
- // force overriding validation options
7022
- options.validation === false || options.validation === void 0 ? options.validation : {
7023
- stopAfterLexingErrors: true,
7024
- stopAfterParsingErrors: true,
7025
- stopAfterLinkingErrors: true
7026
- }
7027
- )
7028
- }, cancelToken);
7032
+ constructor(services) {
7033
+ super(services);
7034
+ let validationOptions = this.updateBuildOptions.validation;
7035
+ const stopFlags = {
7036
+ stopAfterLinkingErrors: true,
7037
+ stopAfterLexingErrors: true,
7038
+ stopAfterParsingErrors: true
7039
+ };
7040
+ if (validationOptions === true) {
7041
+ validationOptions = stopFlags;
7042
+ } else if (typeof validationOptions === "object") {
7043
+ validationOptions = {
7044
+ ...validationOptions,
7045
+ ...stopFlags
7046
+ };
7047
+ }
7048
+ this.updateBuildOptions = {
7049
+ ...this.updateBuildOptions,
7050
+ validation: validationOptions
7051
+ };
7029
7052
  }
7030
7053
  };
7031
7054
 
7032
7055
  // src/zmodel-linker.ts
7033
- import { AstUtils as AstUtils6, Cancellation, DefaultLinker, DocumentState, interruptAndCheck, isReference } from "langium";
7056
+ import { AstUtils as AstUtils6, Cancellation, DefaultLinker, DocumentState, interruptAndCheck } from "langium";
7034
7057
  import { match as match2 } from "ts-pattern";
7035
7058
  var ZModelLinker = class extends DefaultLinker {
7036
7059
  static {
@@ -7052,21 +7075,19 @@ var ZModelLinker = class extends DefaultLinker {
7052
7075
  }
7053
7076
  document.state = DocumentState.Linked;
7054
7077
  }
7055
- linkReference(container, property, document, extraScopes) {
7056
- if (this.resolveFromScopeProviders(container, property, document, extraScopes)) {
7078
+ linkReference(refInfo, document, extraScopes) {
7079
+ const defaultRef = refInfo.reference;
7080
+ if (defaultRef._ref) {
7081
+ return;
7082
+ }
7083
+ if (this.resolveFromScopeProviders(refInfo.reference, document, extraScopes)) {
7057
7084
  return;
7058
7085
  }
7059
- const reference = container[property];
7060
- this.doLink({
7061
- reference,
7062
- container,
7063
- property
7064
- }, document);
7086
+ this.doLink(refInfo, document);
7065
7087
  }
7066
7088
  //#endregion
7067
7089
  //#region Expression type resolving
7068
- resolveFromScopeProviders(node, property, document, providers) {
7069
- const reference = node[property];
7090
+ resolveFromScopeProviders(reference, document, providers) {
7070
7091
  for (const provider of providers) {
7071
7092
  const target = provider(reference.$refText);
7072
7093
  if (target) {
@@ -7195,7 +7216,11 @@ var ZModelLinker = class extends DefaultLinker {
7195
7216
  }
7196
7217
  }
7197
7218
  resolveInvocation(node, document, extraScopes) {
7198
- this.linkReference(node, "function", document, extraScopes);
7219
+ this.linkReference({
7220
+ reference: node.function,
7221
+ container: node,
7222
+ property: "function"
7223
+ }, document, extraScopes);
7199
7224
  node.args.forEach((arg) => this.resolve(arg, document, extraScopes));
7200
7225
  if (node.function.ref) {
7201
7226
  const funcDecl = node.function.ref;
@@ -7208,7 +7233,7 @@ var ZModelLinker = class extends DefaultLinker {
7208
7233
  nullable: true
7209
7234
  };
7210
7235
  }
7211
- } else if (isFutureExpr(node)) {
7236
+ } else if (isBeforeInvocation(node)) {
7212
7237
  node.$resolvedType = {
7213
7238
  decl: getContainingDataModel(node)
7214
7239
  };
@@ -7272,7 +7297,7 @@ var ZModelLinker = class extends DefaultLinker {
7272
7297
  if (isArrayExpr(node.value)) {
7273
7298
  node.value.items.forEach((item) => {
7274
7299
  if (isReferenceExpr(item)) {
7275
- const resolved2 = this.resolveFromScopeProviders(item, "target", document, [
7300
+ const resolved2 = this.resolveFromScopeProviders(item.target, document, [
7276
7301
  scopeProvider
7277
7302
  ]);
7278
7303
  if (resolved2) {
@@ -7286,7 +7311,7 @@ var ZModelLinker = class extends DefaultLinker {
7286
7311
  this.resolveToBuiltinTypeOrDecl(node.value, node.value.items[0].$resolvedType.decl, true);
7287
7312
  }
7288
7313
  } else if (isReferenceExpr(node.value)) {
7289
- const resolved2 = this.resolveFromScopeProviders(node.value, "target", document, [
7314
+ const resolved2 = this.resolveFromScopeProviders(node.value.target, document, [
7290
7315
  scopeProvider
7291
7316
  ]);
7292
7317
  if (resolved2) {
@@ -7338,13 +7363,9 @@ var ZModelLinker = class extends DefaultLinker {
7338
7363
  this.resolveDefault(node, document, scopes);
7339
7364
  }
7340
7365
  resolveDefault(node, document, extraScopes) {
7341
- for (const [property, value] of Object.entries(node)) {
7342
- if (!property.startsWith("$")) {
7343
- if (isReference(value)) {
7344
- this.linkReference(node, property, document, extraScopes);
7345
- }
7346
- }
7347
- }
7366
+ AstUtils6.streamReferences(node).forEach((ref) => {
7367
+ this.linkReference(ref, document, extraScopes);
7368
+ });
7348
7369
  for (const child of AstUtils6.streamContents(node)) {
7349
7370
  this.resolve(child, document, extraScopes);
7350
7371
  }
@@ -7485,7 +7506,7 @@ var ZModelScopeProvider = class extends DefaultScopeProvider {
7485
7506
  if (isAuthInvocation(operand)) {
7486
7507
  return this.createScopeForAuth(node, globalScope);
7487
7508
  }
7488
- if (isFutureInvocation(operand)) {
7509
+ if (isBeforeInvocation(operand)) {
7489
7510
  return this.createScopeForContainingModel(node, globalScope);
7490
7511
  }
7491
7512
  return EMPTY_SCOPE;
@@ -7752,7 +7773,11 @@ async function loadDocument(fileName, pluginModelFiles = []) {
7752
7773
  document,
7753
7774
  ...importedDocuments
7754
7775
  ], {
7755
- validation: true
7776
+ validation: {
7777
+ stopAfterLexingErrors: true,
7778
+ stopAfterParsingErrors: true,
7779
+ stopAfterLinkingErrors: true
7780
+ }
7756
7781
  });
7757
7782
  const diagnostics = langiumDocuments.all.flatMap((doc) => (doc.diagnostics ?? []).map((diag) => ({
7758
7783
  doc,