@zenstackhq/language 3.0.0-beta.6 → 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.cjs +152 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +105 -67
- package/dist/index.js.map +1 -1
- package/dist/utils.cjs +18 -21
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +2 -3
- package/dist/utils.d.ts +2 -3
- package/dist/utils.js +17 -19
- package/dist/utils.js.map +1 -1
- package/package.json +5 -5
- package/res/stdlib.zmodel +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -21,7 +21,6 @@ declare const ZModelLanguageMetaData: {
|
|
|
21
21
|
declare class ZModelValidator {
|
|
22
22
|
protected readonly services: ZModelServices;
|
|
23
23
|
constructor(services: ZModelServices);
|
|
24
|
-
private shouldCheck;
|
|
25
24
|
checkModel(node: Model, accept: ValidationAcceptor): void;
|
|
26
25
|
checkDataSource(node: DataSource, accept: ValidationAcceptor): void;
|
|
27
26
|
checkDataModel(node: DataModel, accept: ValidationAcceptor): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -21,7 +21,6 @@ declare const ZModelLanguageMetaData: {
|
|
|
21
21
|
declare class ZModelValidator {
|
|
22
22
|
protected readonly services: ZModelServices;
|
|
23
23
|
constructor(services: ZModelServices);
|
|
24
|
-
private shouldCheck;
|
|
25
24
|
checkModel(node: Model, accept: ValidationAcceptor): void;
|
|
26
25
|
checkDataSource(node: DataSource, accept: ValidationAcceptor): void;
|
|
27
26
|
checkDataModel(node: DataModel, accept: ValidationAcceptor): void;
|
package/dist/index.js
CHANGED
|
@@ -5109,7 +5109,6 @@ import { AstUtils as AstUtils2 } from "langium";
|
|
|
5109
5109
|
import pluralize from "pluralize";
|
|
5110
5110
|
|
|
5111
5111
|
// src/utils.ts
|
|
5112
|
-
import { invariant } from "@zenstackhq/common-helpers";
|
|
5113
5112
|
import { AstUtils, URI } from "langium";
|
|
5114
5113
|
import fs from "fs";
|
|
5115
5114
|
import path from "path";
|
|
@@ -5192,10 +5191,6 @@ function isRelationshipField(field) {
|
|
|
5192
5191
|
return isDataModel(field.type.reference?.ref);
|
|
5193
5192
|
}
|
|
5194
5193
|
__name(isRelationshipField, "isRelationshipField");
|
|
5195
|
-
function isFutureExpr(node) {
|
|
5196
|
-
return isInvocationExpr(node) && node.function.ref?.name === "future" && isFromStdlib(node.function.ref);
|
|
5197
|
-
}
|
|
5198
|
-
__name(isFutureExpr, "isFutureExpr");
|
|
5199
5194
|
function isDelegateModel(node) {
|
|
5200
5195
|
return isDataModel(node) && hasAttribute(node, "@@delegate");
|
|
5201
5196
|
}
|
|
@@ -5214,7 +5209,7 @@ function getRecursiveBases(decl, includeDelegate = true, seen = /* @__PURE__ */
|
|
|
5214
5209
|
}
|
|
5215
5210
|
seen.add(decl);
|
|
5216
5211
|
decl.mixins.forEach((mixin) => {
|
|
5217
|
-
const baseDecl = mixin
|
|
5212
|
+
const baseDecl = decl.$container.declarations.find((d) => isTypeDef(d) && d.name === mixin.$refText);
|
|
5218
5213
|
if (baseDecl) {
|
|
5219
5214
|
if (!includeDelegate && isDelegateModel(baseDecl)) {
|
|
5220
5215
|
return;
|
|
@@ -5431,10 +5426,10 @@ function getAuthDecl(decls) {
|
|
|
5431
5426
|
return authModel;
|
|
5432
5427
|
}
|
|
5433
5428
|
__name(getAuthDecl, "getAuthDecl");
|
|
5434
|
-
function
|
|
5435
|
-
return isInvocationExpr(node) && node.function.ref?.name === "
|
|
5429
|
+
function isBeforeInvocation(node) {
|
|
5430
|
+
return isInvocationExpr(node) && node.function.ref?.name === "before" && isFromStdlib(node.function.ref);
|
|
5436
5431
|
}
|
|
5437
|
-
__name(
|
|
5432
|
+
__name(isBeforeInvocation, "isBeforeInvocation");
|
|
5438
5433
|
function isCollectionPredicate(node) {
|
|
5439
5434
|
return isBinaryExpr(node) && [
|
|
5440
5435
|
"?",
|
|
@@ -5489,12 +5484,14 @@ function getAllFields(decl, includeIgnored = false, seen = /* @__PURE__ */ new S
|
|
|
5489
5484
|
seen.add(decl);
|
|
5490
5485
|
const fields = [];
|
|
5491
5486
|
for (const mixin of decl.mixins) {
|
|
5492
|
-
|
|
5493
|
-
|
|
5487
|
+
if (mixin.ref) {
|
|
5488
|
+
fields.push(...getAllFields(mixin.ref, includeIgnored, seen));
|
|
5489
|
+
}
|
|
5494
5490
|
}
|
|
5495
5491
|
if (isDataModel(decl) && decl.baseModel) {
|
|
5496
|
-
|
|
5497
|
-
|
|
5492
|
+
if (decl.baseModel.ref) {
|
|
5493
|
+
fields.push(...getAllFields(decl.baseModel.ref, includeIgnored, seen));
|
|
5494
|
+
}
|
|
5498
5495
|
}
|
|
5499
5496
|
fields.push(...decl.fields.filter((f) => includeIgnored || !hasAttribute(f, "@ignore")));
|
|
5500
5497
|
return fields;
|
|
@@ -5507,12 +5504,14 @@ function getAllAttributes(decl, seen = /* @__PURE__ */ new Set()) {
|
|
|
5507
5504
|
seen.add(decl);
|
|
5508
5505
|
const attributes = [];
|
|
5509
5506
|
for (const mixin of decl.mixins) {
|
|
5510
|
-
|
|
5511
|
-
|
|
5507
|
+
if (mixin.ref) {
|
|
5508
|
+
attributes.push(...getAllAttributes(mixin.ref, seen));
|
|
5509
|
+
}
|
|
5512
5510
|
}
|
|
5513
5511
|
if (isDataModel(decl) && decl.baseModel) {
|
|
5514
|
-
|
|
5515
|
-
|
|
5512
|
+
if (decl.baseModel.ref) {
|
|
5513
|
+
attributes.push(...getAllAttributes(decl.baseModel.ref, seen));
|
|
5514
|
+
}
|
|
5516
5515
|
}
|
|
5517
5516
|
attributes.push(...decl.attributes);
|
|
5518
5517
|
return attributes;
|
|
@@ -5662,12 +5661,21 @@ var AttributeApplicationValidator = class {
|
|
|
5662
5661
|
"create",
|
|
5663
5662
|
"read",
|
|
5664
5663
|
"update",
|
|
5664
|
+
"post-update",
|
|
5665
5665
|
"delete",
|
|
5666
5666
|
"all"
|
|
5667
5667
|
], attr, accept);
|
|
5668
5668
|
if ((kind === "create" || kind === "all") && attr.args[1]?.value) {
|
|
5669
5669
|
this.rejectNonOwnedRelationInExpression(attr.args[1].value, accept);
|
|
5670
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
|
+
}
|
|
5671
5679
|
}
|
|
5672
5680
|
rejectNonOwnedRelationInExpression(expr, accept) {
|
|
5673
5681
|
const contextModel = AstUtils2.getContainerOfType(expr, isDataModel);
|
|
@@ -5722,8 +5730,8 @@ var AttributeApplicationValidator = class {
|
|
|
5722
5730
|
"all"
|
|
5723
5731
|
], attr, accept);
|
|
5724
5732
|
const expr = attr.args[1]?.value;
|
|
5725
|
-
if (expr && AstUtils2.streamAst(expr).some((node) =>
|
|
5726
|
-
accept("error", `"
|
|
5733
|
+
if (expr && AstUtils2.streamAst(expr).some((node) => isBeforeInvocation(node))) {
|
|
5734
|
+
accept("error", `"before()" is not allowed in field-level policy rules`, {
|
|
5727
5735
|
node: expr
|
|
5728
5736
|
});
|
|
5729
5737
|
}
|
|
@@ -5961,7 +5969,7 @@ var AttributeValidator = class {
|
|
|
5961
5969
|
};
|
|
5962
5970
|
|
|
5963
5971
|
// src/validators/datamodel-validator.ts
|
|
5964
|
-
import { invariant
|
|
5972
|
+
import { invariant } from "@zenstackhq/common-helpers";
|
|
5965
5973
|
import { AstUtils as AstUtils3 } from "langium";
|
|
5966
5974
|
|
|
5967
5975
|
// src/validators/common.ts
|
|
@@ -6332,7 +6340,7 @@ var DataModelValidator = class {
|
|
|
6332
6340
|
if (!model.baseModel) {
|
|
6333
6341
|
return;
|
|
6334
6342
|
}
|
|
6335
|
-
|
|
6343
|
+
invariant(model.baseModel.ref, "baseModel must be resolved");
|
|
6336
6344
|
if (!isDelegateModel(model.baseModel.ref)) {
|
|
6337
6345
|
accept("error", `Model ${model.baseModel.$refText} cannot be extended because it's not a delegate model`, {
|
|
6338
6346
|
node: model,
|
|
@@ -6354,7 +6362,7 @@ var DataModelValidator = class {
|
|
|
6354
6362
|
}
|
|
6355
6363
|
seen.push(current);
|
|
6356
6364
|
if (current.baseModel) {
|
|
6357
|
-
|
|
6365
|
+
invariant(current.baseModel.ref, "baseModel must be resolved");
|
|
6358
6366
|
todo.push(current.baseModel.ref);
|
|
6359
6367
|
}
|
|
6360
6368
|
}
|
|
@@ -6484,11 +6492,21 @@ var ExpressionValidator = class {
|
|
|
6484
6492
|
}
|
|
6485
6493
|
}
|
|
6486
6494
|
switch (expr.$type) {
|
|
6495
|
+
case "MemberAccessExpr":
|
|
6496
|
+
this.validateMemberAccessExpr(expr, accept);
|
|
6497
|
+
break;
|
|
6487
6498
|
case "BinaryExpr":
|
|
6488
6499
|
this.validateBinaryExpr(expr, accept);
|
|
6489
6500
|
break;
|
|
6490
6501
|
}
|
|
6491
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
|
+
}
|
|
6492
6510
|
validateBinaryExpr(expr, accept) {
|
|
6493
6511
|
switch (expr.operator) {
|
|
6494
6512
|
case "in": {
|
|
@@ -6976,49 +6994,66 @@ var ZModelValidator = class {
|
|
|
6976
6994
|
constructor(services) {
|
|
6977
6995
|
this.services = services;
|
|
6978
6996
|
}
|
|
6979
|
-
shouldCheck(node) {
|
|
6980
|
-
let doc;
|
|
6981
|
-
let currNode = node;
|
|
6982
|
-
while (currNode) {
|
|
6983
|
-
if (currNode.$document) {
|
|
6984
|
-
doc = currNode.$document;
|
|
6985
|
-
break;
|
|
6986
|
-
}
|
|
6987
|
-
currNode = currNode.$container;
|
|
6988
|
-
}
|
|
6989
|
-
return doc?.parseResult.lexerErrors.length === 0 && doc?.parseResult.parserErrors.length === 0;
|
|
6990
|
-
}
|
|
6991
6997
|
checkModel(node, accept) {
|
|
6992
|
-
|
|
6998
|
+
new SchemaValidator(this.services.shared.workspace.LangiumDocuments).validate(node, accept);
|
|
6993
6999
|
}
|
|
6994
7000
|
checkDataSource(node, accept) {
|
|
6995
|
-
|
|
7001
|
+
new DataSourceValidator().validate(node, accept);
|
|
6996
7002
|
}
|
|
6997
7003
|
checkDataModel(node, accept) {
|
|
6998
|
-
|
|
7004
|
+
new DataModelValidator().validate(node, accept);
|
|
6999
7005
|
}
|
|
7000
7006
|
checkTypeDef(node, accept) {
|
|
7001
|
-
|
|
7007
|
+
new TypeDefValidator().validate(node, accept);
|
|
7002
7008
|
}
|
|
7003
7009
|
checkEnum(node, accept) {
|
|
7004
|
-
|
|
7010
|
+
new EnumValidator().validate(node, accept);
|
|
7005
7011
|
}
|
|
7006
7012
|
checkAttribute(node, accept) {
|
|
7007
|
-
|
|
7013
|
+
new AttributeValidator().validate(node, accept);
|
|
7008
7014
|
}
|
|
7009
7015
|
checkExpression(node, accept) {
|
|
7010
|
-
|
|
7016
|
+
new ExpressionValidator().validate(node, accept);
|
|
7011
7017
|
}
|
|
7012
7018
|
checkFunctionInvocation(node, accept) {
|
|
7013
|
-
|
|
7019
|
+
new FunctionInvocationValidator().validate(node, accept);
|
|
7014
7020
|
}
|
|
7015
7021
|
checkFunctionDecl(node, accept) {
|
|
7016
|
-
|
|
7022
|
+
new FunctionDeclValidator().validate(node, accept);
|
|
7023
|
+
}
|
|
7024
|
+
};
|
|
7025
|
+
|
|
7026
|
+
// src/zmodel-document-builder.ts
|
|
7027
|
+
import { DefaultDocumentBuilder } from "langium";
|
|
7028
|
+
var ZModelDocumentBuilder = class extends DefaultDocumentBuilder {
|
|
7029
|
+
static {
|
|
7030
|
+
__name(this, "ZModelDocumentBuilder");
|
|
7031
|
+
}
|
|
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
|
+
};
|
|
7017
7052
|
}
|
|
7018
7053
|
};
|
|
7019
7054
|
|
|
7020
7055
|
// src/zmodel-linker.ts
|
|
7021
|
-
import { AstUtils as AstUtils6, Cancellation, DefaultLinker, DocumentState, interruptAndCheck
|
|
7056
|
+
import { AstUtils as AstUtils6, Cancellation, DefaultLinker, DocumentState, interruptAndCheck } from "langium";
|
|
7022
7057
|
import { match as match2 } from "ts-pattern";
|
|
7023
7058
|
var ZModelLinker = class extends DefaultLinker {
|
|
7024
7059
|
static {
|
|
@@ -7040,21 +7075,19 @@ var ZModelLinker = class extends DefaultLinker {
|
|
|
7040
7075
|
}
|
|
7041
7076
|
document.state = DocumentState.Linked;
|
|
7042
7077
|
}
|
|
7043
|
-
linkReference(
|
|
7044
|
-
|
|
7078
|
+
linkReference(refInfo, document, extraScopes) {
|
|
7079
|
+
const defaultRef = refInfo.reference;
|
|
7080
|
+
if (defaultRef._ref) {
|
|
7045
7081
|
return;
|
|
7046
7082
|
}
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
property
|
|
7052
|
-
}, document);
|
|
7083
|
+
if (this.resolveFromScopeProviders(refInfo.reference, document, extraScopes)) {
|
|
7084
|
+
return;
|
|
7085
|
+
}
|
|
7086
|
+
this.doLink(refInfo, document);
|
|
7053
7087
|
}
|
|
7054
7088
|
//#endregion
|
|
7055
7089
|
//#region Expression type resolving
|
|
7056
|
-
resolveFromScopeProviders(
|
|
7057
|
-
const reference = node[property];
|
|
7090
|
+
resolveFromScopeProviders(reference, document, providers) {
|
|
7058
7091
|
for (const provider of providers) {
|
|
7059
7092
|
const target = provider(reference.$refText);
|
|
7060
7093
|
if (target) {
|
|
@@ -7183,7 +7216,11 @@ var ZModelLinker = class extends DefaultLinker {
|
|
|
7183
7216
|
}
|
|
7184
7217
|
}
|
|
7185
7218
|
resolveInvocation(node, document, extraScopes) {
|
|
7186
|
-
this.linkReference(
|
|
7219
|
+
this.linkReference({
|
|
7220
|
+
reference: node.function,
|
|
7221
|
+
container: node,
|
|
7222
|
+
property: "function"
|
|
7223
|
+
}, document, extraScopes);
|
|
7187
7224
|
node.args.forEach((arg) => this.resolve(arg, document, extraScopes));
|
|
7188
7225
|
if (node.function.ref) {
|
|
7189
7226
|
const funcDecl = node.function.ref;
|
|
@@ -7196,7 +7233,7 @@ var ZModelLinker = class extends DefaultLinker {
|
|
|
7196
7233
|
nullable: true
|
|
7197
7234
|
};
|
|
7198
7235
|
}
|
|
7199
|
-
} else if (
|
|
7236
|
+
} else if (isBeforeInvocation(node)) {
|
|
7200
7237
|
node.$resolvedType = {
|
|
7201
7238
|
decl: getContainingDataModel(node)
|
|
7202
7239
|
};
|
|
@@ -7260,7 +7297,7 @@ var ZModelLinker = class extends DefaultLinker {
|
|
|
7260
7297
|
if (isArrayExpr(node.value)) {
|
|
7261
7298
|
node.value.items.forEach((item) => {
|
|
7262
7299
|
if (isReferenceExpr(item)) {
|
|
7263
|
-
const resolved2 = this.resolveFromScopeProviders(item
|
|
7300
|
+
const resolved2 = this.resolveFromScopeProviders(item.target, document, [
|
|
7264
7301
|
scopeProvider
|
|
7265
7302
|
]);
|
|
7266
7303
|
if (resolved2) {
|
|
@@ -7274,7 +7311,7 @@ var ZModelLinker = class extends DefaultLinker {
|
|
|
7274
7311
|
this.resolveToBuiltinTypeOrDecl(node.value, node.value.items[0].$resolvedType.decl, true);
|
|
7275
7312
|
}
|
|
7276
7313
|
} else if (isReferenceExpr(node.value)) {
|
|
7277
|
-
const resolved2 = this.resolveFromScopeProviders(node.value
|
|
7314
|
+
const resolved2 = this.resolveFromScopeProviders(node.value.target, document, [
|
|
7278
7315
|
scopeProvider
|
|
7279
7316
|
]);
|
|
7280
7317
|
if (resolved2) {
|
|
@@ -7326,13 +7363,9 @@ var ZModelLinker = class extends DefaultLinker {
|
|
|
7326
7363
|
this.resolveDefault(node, document, scopes);
|
|
7327
7364
|
}
|
|
7328
7365
|
resolveDefault(node, document, extraScopes) {
|
|
7329
|
-
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
this.linkReference(node, property, document, extraScopes);
|
|
7333
|
-
}
|
|
7334
|
-
}
|
|
7335
|
-
}
|
|
7366
|
+
AstUtils6.streamReferences(node).forEach((ref) => {
|
|
7367
|
+
this.linkReference(ref, document, extraScopes);
|
|
7368
|
+
});
|
|
7336
7369
|
for (const child of AstUtils6.streamContents(node)) {
|
|
7337
7370
|
this.resolve(child, document, extraScopes);
|
|
7338
7371
|
}
|
|
@@ -7473,7 +7506,7 @@ var ZModelScopeProvider = class extends DefaultScopeProvider {
|
|
|
7473
7506
|
if (isAuthInvocation(operand)) {
|
|
7474
7507
|
return this.createScopeForAuth(node, globalScope);
|
|
7475
7508
|
}
|
|
7476
|
-
if (
|
|
7509
|
+
if (isBeforeInvocation(operand)) {
|
|
7477
7510
|
return this.createScopeForContainingModel(node, globalScope);
|
|
7478
7511
|
}
|
|
7479
7512
|
return EMPTY_SCOPE;
|
|
@@ -7669,6 +7702,7 @@ var ZModelLanguageModule = {
|
|
|
7669
7702
|
};
|
|
7670
7703
|
var ZModelSharedModule = {
|
|
7671
7704
|
workspace: {
|
|
7705
|
+
DocumentBuilder: /* @__PURE__ */ __name((services) => new ZModelDocumentBuilder(services), "DocumentBuilder"),
|
|
7672
7706
|
WorkspaceManager: /* @__PURE__ */ __name((services) => new ZModelWorkspaceManager(services), "WorkspaceManager")
|
|
7673
7707
|
}
|
|
7674
7708
|
};
|
|
@@ -7739,7 +7773,11 @@ async function loadDocument(fileName, pluginModelFiles = []) {
|
|
|
7739
7773
|
document,
|
|
7740
7774
|
...importedDocuments
|
|
7741
7775
|
], {
|
|
7742
|
-
validation:
|
|
7776
|
+
validation: {
|
|
7777
|
+
stopAfterLexingErrors: true,
|
|
7778
|
+
stopAfterParsingErrors: true,
|
|
7779
|
+
stopAfterLinkingErrors: true
|
|
7780
|
+
}
|
|
7743
7781
|
});
|
|
7744
7782
|
const diagnostics = langiumDocuments.all.flatMap((doc) => (doc.diagnostics ?? []).map((diag) => ({
|
|
7745
7783
|
doc,
|