@zenstackhq/language 3.0.0-beta.7 → 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 +155 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +156 -51
- package/dist/index.js.map +1 -1
- package/dist/utils.cjs +13 -13
- 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 +12 -11
- package/dist/utils.js.map +1 -1
- package/package.json +6 -5
- package/res/stdlib.zmodel +18 -17
package/dist/index.cjs
CHANGED
|
@@ -5223,10 +5223,6 @@ function isRelationshipField(field) {
|
|
|
5223
5223
|
return isDataModel(field.type.reference?.ref);
|
|
5224
5224
|
}
|
|
5225
5225
|
__name(isRelationshipField, "isRelationshipField");
|
|
5226
|
-
function isFutureExpr(node) {
|
|
5227
|
-
return isInvocationExpr(node) && node.function.ref?.name === "future" && isFromStdlib(node.function.ref);
|
|
5228
|
-
}
|
|
5229
|
-
__name(isFutureExpr, "isFutureExpr");
|
|
5230
5226
|
function isDelegateModel(node) {
|
|
5231
5227
|
return isDataModel(node) && hasAttribute(node, "@@delegate");
|
|
5232
5228
|
}
|
|
@@ -5244,8 +5240,14 @@ function getRecursiveBases(decl, includeDelegate = true, seen = /* @__PURE__ */
|
|
|
5244
5240
|
return result;
|
|
5245
5241
|
}
|
|
5246
5242
|
seen.add(decl);
|
|
5247
|
-
|
|
5248
|
-
|
|
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);
|
|
5249
5251
|
if (baseDecl) {
|
|
5250
5252
|
if (!includeDelegate && isDelegateModel(baseDecl)) {
|
|
5251
5253
|
return;
|
|
@@ -5462,10 +5464,10 @@ function getAuthDecl(decls) {
|
|
|
5462
5464
|
return authModel;
|
|
5463
5465
|
}
|
|
5464
5466
|
__name(getAuthDecl, "getAuthDecl");
|
|
5465
|
-
function
|
|
5466
|
-
return isInvocationExpr(node) && node.function.ref?.name === "
|
|
5467
|
+
function isBeforeInvocation(node) {
|
|
5468
|
+
return isInvocationExpr(node) && node.function.ref?.name === "before" && isFromStdlib(node.function.ref);
|
|
5467
5469
|
}
|
|
5468
|
-
__name(
|
|
5470
|
+
__name(isBeforeInvocation, "isBeforeInvocation");
|
|
5469
5471
|
function isCollectionPredicate(node) {
|
|
5470
5472
|
return isBinaryExpr(node) && [
|
|
5471
5473
|
"?",
|
|
@@ -5697,12 +5699,21 @@ var AttributeApplicationValidator = class {
|
|
|
5697
5699
|
"create",
|
|
5698
5700
|
"read",
|
|
5699
5701
|
"update",
|
|
5702
|
+
"post-update",
|
|
5700
5703
|
"delete",
|
|
5701
5704
|
"all"
|
|
5702
5705
|
], attr, accept);
|
|
5703
5706
|
if ((kind === "create" || kind === "all") && attr.args[1]?.value) {
|
|
5704
5707
|
this.rejectNonOwnedRelationInExpression(attr.args[1].value, accept);
|
|
5705
5708
|
}
|
|
5709
|
+
if (kind !== "post-update" && attr.args[1]?.value) {
|
|
5710
|
+
const beforeCall = import_langium3.AstUtils.streamAst(attr.args[1]?.value).find(isBeforeInvocation);
|
|
5711
|
+
if (beforeCall) {
|
|
5712
|
+
accept("error", `"before()" is only allowed in "post-update" policy rules`, {
|
|
5713
|
+
node: beforeCall
|
|
5714
|
+
});
|
|
5715
|
+
}
|
|
5716
|
+
}
|
|
5706
5717
|
}
|
|
5707
5718
|
rejectNonOwnedRelationInExpression(expr, accept) {
|
|
5708
5719
|
const contextModel = import_langium3.AstUtils.getContainerOfType(expr, isDataModel);
|
|
@@ -5757,8 +5768,8 @@ var AttributeApplicationValidator = class {
|
|
|
5757
5768
|
"all"
|
|
5758
5769
|
], attr, accept);
|
|
5759
5770
|
const expr = attr.args[1]?.value;
|
|
5760
|
-
if (expr && import_langium3.AstUtils.streamAst(expr).some((node) =>
|
|
5761
|
-
accept("error", `"
|
|
5771
|
+
if (expr && import_langium3.AstUtils.streamAst(expr).some((node) => isBeforeInvocation(node))) {
|
|
5772
|
+
accept("error", `"before()" is not allowed in field-level policy rules`, {
|
|
5762
5773
|
node: expr
|
|
5763
5774
|
});
|
|
5764
5775
|
}
|
|
@@ -5879,6 +5890,10 @@ function assignableToAttributeParam(arg, param, attr) {
|
|
|
5879
5890
|
let dstIsArray = param.type.array;
|
|
5880
5891
|
if (dstType === "ContextType") {
|
|
5881
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
|
+
}
|
|
5882
5897
|
dstIsArray = attr.$container.type.array;
|
|
5883
5898
|
}
|
|
5884
5899
|
}
|
|
@@ -5970,6 +5985,9 @@ function isValidAttributeTarget(attrDecl, targetDecl) {
|
|
|
5970
5985
|
case "TypeDefField":
|
|
5971
5986
|
allowed = allowed || isTypeDef(targetDecl.type.reference?.ref);
|
|
5972
5987
|
break;
|
|
5988
|
+
case "ListField":
|
|
5989
|
+
allowed = allowed || !isDataModel(targetDecl.type.reference?.ref) && targetDecl.type.array;
|
|
5990
|
+
break;
|
|
5973
5991
|
default:
|
|
5974
5992
|
break;
|
|
5975
5993
|
}
|
|
@@ -6519,11 +6537,21 @@ var ExpressionValidator = class {
|
|
|
6519
6537
|
}
|
|
6520
6538
|
}
|
|
6521
6539
|
switch (expr.$type) {
|
|
6540
|
+
case "MemberAccessExpr":
|
|
6541
|
+
this.validateMemberAccessExpr(expr, accept);
|
|
6542
|
+
break;
|
|
6522
6543
|
case "BinaryExpr":
|
|
6523
6544
|
this.validateBinaryExpr(expr, accept);
|
|
6524
6545
|
break;
|
|
6525
6546
|
}
|
|
6526
6547
|
}
|
|
6548
|
+
validateMemberAccessExpr(expr, accept) {
|
|
6549
|
+
if (isBeforeInvocation(expr.operand) && isDataModel(expr.$resolvedType?.decl)) {
|
|
6550
|
+
accept("error", "relation fields cannot be accessed from `before()`", {
|
|
6551
|
+
node: expr
|
|
6552
|
+
});
|
|
6553
|
+
}
|
|
6554
|
+
}
|
|
6527
6555
|
validateBinaryExpr(expr, accept) {
|
|
6528
6556
|
switch (expr.operator) {
|
|
6529
6557
|
case "in": {
|
|
@@ -6738,7 +6766,7 @@ var FunctionInvocationValidator = class {
|
|
|
6738
6766
|
}
|
|
6739
6767
|
curr = curr.$container;
|
|
6740
6768
|
}
|
|
6741
|
-
const exprContext =
|
|
6769
|
+
const exprContext = this.getExpressionContext(containerAttribute);
|
|
6742
6770
|
const funcAllowedContext = getFunctionExpressionContext(funcDecl);
|
|
6743
6771
|
if (exprContext && !funcAllowedContext.includes(exprContext)) {
|
|
6744
6772
|
accept("error", `function "${funcDecl.name}" is not allowed in the current context: ${exprContext}`, {
|
|
@@ -6770,6 +6798,18 @@ var FunctionInvocationValidator = class {
|
|
|
6770
6798
|
checker.value.call(this, expr, accept);
|
|
6771
6799
|
}
|
|
6772
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
|
+
}
|
|
6773
6813
|
validateArgs(funcDecl, args, accept) {
|
|
6774
6814
|
let success = true;
|
|
6775
6815
|
for (let i = 0; i < funcDecl.params.length; i++) {
|
|
@@ -6830,6 +6870,43 @@ var FunctionInvocationValidator = class {
|
|
|
6830
6870
|
}
|
|
6831
6871
|
return true;
|
|
6832
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
|
+
}
|
|
6833
6910
|
// TODO: move this to policy plugin
|
|
6834
6911
|
_checkCheck(expr, accept) {
|
|
6835
6912
|
let valid = true;
|
|
@@ -6902,6 +6979,24 @@ var FunctionInvocationValidator = class {
|
|
|
6902
6979
|
}
|
|
6903
6980
|
}
|
|
6904
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);
|
|
6905
7000
|
_ts_decorate2([
|
|
6906
7001
|
func("check"),
|
|
6907
7002
|
_ts_metadata2("design:type", Function),
|
|
@@ -7046,18 +7141,26 @@ var ZModelDocumentBuilder = class extends import_langium7.DefaultDocumentBuilder
|
|
|
7046
7141
|
static {
|
|
7047
7142
|
__name(this, "ZModelDocumentBuilder");
|
|
7048
7143
|
}
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
|
|
7053
|
-
|
|
7054
|
-
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
|
|
7144
|
+
constructor(services) {
|
|
7145
|
+
super(services);
|
|
7146
|
+
let validationOptions = this.updateBuildOptions.validation;
|
|
7147
|
+
const stopFlags = {
|
|
7148
|
+
stopAfterLinkingErrors: true,
|
|
7149
|
+
stopAfterLexingErrors: true,
|
|
7150
|
+
stopAfterParsingErrors: true
|
|
7151
|
+
};
|
|
7152
|
+
if (validationOptions === true) {
|
|
7153
|
+
validationOptions = stopFlags;
|
|
7154
|
+
} else if (typeof validationOptions === "object") {
|
|
7155
|
+
validationOptions = {
|
|
7156
|
+
...validationOptions,
|
|
7157
|
+
...stopFlags
|
|
7158
|
+
};
|
|
7159
|
+
}
|
|
7160
|
+
this.updateBuildOptions = {
|
|
7161
|
+
...this.updateBuildOptions,
|
|
7162
|
+
validation: validationOptions
|
|
7163
|
+
};
|
|
7061
7164
|
}
|
|
7062
7165
|
};
|
|
7063
7166
|
|
|
@@ -7084,21 +7187,19 @@ var ZModelLinker = class extends import_langium8.DefaultLinker {
|
|
|
7084
7187
|
}
|
|
7085
7188
|
document.state = import_langium8.DocumentState.Linked;
|
|
7086
7189
|
}
|
|
7087
|
-
linkReference(
|
|
7088
|
-
|
|
7190
|
+
linkReference(refInfo, document, extraScopes) {
|
|
7191
|
+
const defaultRef = refInfo.reference;
|
|
7192
|
+
if (defaultRef._ref) {
|
|
7089
7193
|
return;
|
|
7090
7194
|
}
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
7095
|
-
property
|
|
7096
|
-
}, document);
|
|
7195
|
+
if (this.resolveFromScopeProviders(refInfo.reference, document, extraScopes)) {
|
|
7196
|
+
return;
|
|
7197
|
+
}
|
|
7198
|
+
this.doLink(refInfo, document);
|
|
7097
7199
|
}
|
|
7098
7200
|
//#endregion
|
|
7099
7201
|
//#region Expression type resolving
|
|
7100
|
-
resolveFromScopeProviders(
|
|
7101
|
-
const reference = node[property];
|
|
7202
|
+
resolveFromScopeProviders(reference, document, providers) {
|
|
7102
7203
|
for (const provider of providers) {
|
|
7103
7204
|
const target = provider(reference.$refText);
|
|
7104
7205
|
if (target) {
|
|
@@ -7227,7 +7328,11 @@ var ZModelLinker = class extends import_langium8.DefaultLinker {
|
|
|
7227
7328
|
}
|
|
7228
7329
|
}
|
|
7229
7330
|
resolveInvocation(node, document, extraScopes) {
|
|
7230
|
-
this.linkReference(
|
|
7331
|
+
this.linkReference({
|
|
7332
|
+
reference: node.function,
|
|
7333
|
+
container: node,
|
|
7334
|
+
property: "function"
|
|
7335
|
+
}, document, extraScopes);
|
|
7231
7336
|
node.args.forEach((arg) => this.resolve(arg, document, extraScopes));
|
|
7232
7337
|
if (node.function.ref) {
|
|
7233
7338
|
const funcDecl = node.function.ref;
|
|
@@ -7240,7 +7345,7 @@ var ZModelLinker = class extends import_langium8.DefaultLinker {
|
|
|
7240
7345
|
nullable: true
|
|
7241
7346
|
};
|
|
7242
7347
|
}
|
|
7243
|
-
} else if (
|
|
7348
|
+
} else if (isBeforeInvocation(node)) {
|
|
7244
7349
|
node.$resolvedType = {
|
|
7245
7350
|
decl: getContainingDataModel(node)
|
|
7246
7351
|
};
|
|
@@ -7304,7 +7409,7 @@ var ZModelLinker = class extends import_langium8.DefaultLinker {
|
|
|
7304
7409
|
if (isArrayExpr(node.value)) {
|
|
7305
7410
|
node.value.items.forEach((item) => {
|
|
7306
7411
|
if (isReferenceExpr(item)) {
|
|
7307
|
-
const resolved2 = this.resolveFromScopeProviders(item
|
|
7412
|
+
const resolved2 = this.resolveFromScopeProviders(item.target, document, [
|
|
7308
7413
|
scopeProvider
|
|
7309
7414
|
]);
|
|
7310
7415
|
if (resolved2) {
|
|
@@ -7318,7 +7423,7 @@ var ZModelLinker = class extends import_langium8.DefaultLinker {
|
|
|
7318
7423
|
this.resolveToBuiltinTypeOrDecl(node.value, node.value.items[0].$resolvedType.decl, true);
|
|
7319
7424
|
}
|
|
7320
7425
|
} else if (isReferenceExpr(node.value)) {
|
|
7321
|
-
const resolved2 = this.resolveFromScopeProviders(node.value
|
|
7426
|
+
const resolved2 = this.resolveFromScopeProviders(node.value.target, document, [
|
|
7322
7427
|
scopeProvider
|
|
7323
7428
|
]);
|
|
7324
7429
|
if (resolved2) {
|
|
@@ -7370,13 +7475,9 @@ var ZModelLinker = class extends import_langium8.DefaultLinker {
|
|
|
7370
7475
|
this.resolveDefault(node, document, scopes);
|
|
7371
7476
|
}
|
|
7372
7477
|
resolveDefault(node, document, extraScopes) {
|
|
7373
|
-
|
|
7374
|
-
|
|
7375
|
-
|
|
7376
|
-
this.linkReference(node, property, document, extraScopes);
|
|
7377
|
-
}
|
|
7378
|
-
}
|
|
7379
|
-
}
|
|
7478
|
+
import_langium8.AstUtils.streamReferences(node).forEach((ref) => {
|
|
7479
|
+
this.linkReference(ref, document, extraScopes);
|
|
7480
|
+
});
|
|
7380
7481
|
for (const child of import_langium8.AstUtils.streamContents(node)) {
|
|
7381
7482
|
this.resolve(child, document, extraScopes);
|
|
7382
7483
|
}
|
|
@@ -7446,7 +7547,7 @@ var ZModelScopeComputation = class extends import_langium9.DefaultScopeComputati
|
|
|
7446
7547
|
}
|
|
7447
7548
|
processNode(node, document, scopes) {
|
|
7448
7549
|
super.processNode(node, document, scopes);
|
|
7449
|
-
if (isDataModel(node)) {
|
|
7550
|
+
if (isDataModel(node) || isTypeDef(node)) {
|
|
7450
7551
|
const bases = getRecursiveBases(node);
|
|
7451
7552
|
for (const base of bases) {
|
|
7452
7553
|
for (const field of base.fields) {
|
|
@@ -7517,7 +7618,7 @@ var ZModelScopeProvider = class extends import_langium9.DefaultScopeProvider {
|
|
|
7517
7618
|
if (isAuthInvocation(operand)) {
|
|
7518
7619
|
return this.createScopeForAuth(node, globalScope);
|
|
7519
7620
|
}
|
|
7520
|
-
if (
|
|
7621
|
+
if (isBeforeInvocation(operand)) {
|
|
7521
7622
|
return this.createScopeForContainingModel(node, globalScope);
|
|
7522
7623
|
}
|
|
7523
7624
|
return import_langium9.EMPTY_SCOPE;
|
|
@@ -7749,7 +7850,7 @@ var DocumentLoadError = class extends Error {
|
|
|
7749
7850
|
super(message);
|
|
7750
7851
|
}
|
|
7751
7852
|
};
|
|
7752
|
-
async function loadDocument(fileName,
|
|
7853
|
+
async function loadDocument(fileName, additionalModelFiles = []) {
|
|
7753
7854
|
const { ZModelLanguage: services } = createZModelServices();
|
|
7754
7855
|
const extensions = services.LanguageMetaData.fileExtensions;
|
|
7755
7856
|
if (!extensions.includes(import_node_path2.default.extname(fileName))) {
|
|
@@ -7772,7 +7873,7 @@ async function loadDocument(fileName, pluginModelFiles = []) {
|
|
|
7772
7873
|
}
|
|
7773
7874
|
const _dirname = typeof __dirname !== "undefined" ? __dirname : import_node_path2.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
7774
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))));
|
|
7775
|
-
const pluginDocs = await Promise.all(
|
|
7876
|
+
const pluginDocs = await Promise.all(additionalModelFiles.map((file) => services.shared.workspace.LangiumDocuments.getOrCreateDocument(import_langium12.URI.file(import_node_path2.default.resolve(file)))));
|
|
7776
7877
|
const langiumDocuments = services.shared.workspace.LangiumDocuments;
|
|
7777
7878
|
const document = await langiumDocuments.getOrCreateDocument(import_langium12.URI.file(import_node_path2.default.resolve(fileName)));
|
|
7778
7879
|
const importedURIs = await loadImports(document, langiumDocuments);
|
|
@@ -7786,7 +7887,11 @@ async function loadDocument(fileName, pluginModelFiles = []) {
|
|
|
7786
7887
|
document,
|
|
7787
7888
|
...importedDocuments
|
|
7788
7889
|
], {
|
|
7789
|
-
validation:
|
|
7890
|
+
validation: {
|
|
7891
|
+
stopAfterLexingErrors: true,
|
|
7892
|
+
stopAfterParsingErrors: true,
|
|
7893
|
+
stopAfterLinkingErrors: true
|
|
7894
|
+
}
|
|
7790
7895
|
});
|
|
7791
7896
|
const diagnostics = langiumDocuments.all.flatMap((doc) => (doc.diagnostics ?? []).map((diag) => ({
|
|
7792
7897
|
doc,
|