@likec4/language-server 1.40.0 → 1.41.0
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/ast.d.ts +3 -2
- package/dist/bundled.mjs +3383 -3377
- package/dist/formatting/LikeC4Formatter.mjs +1 -0
- package/dist/generated/ast.d.ts +5 -3
- package/dist/generated/ast.mjs +2 -0
- package/dist/generated/grammar.mjs +1 -1
- package/dist/logger.d.ts +1 -1
- package/dist/logger.mjs +3 -0
- package/dist/lsp/HoverProvider.mjs +14 -2
- package/dist/model/builder/MergedSpecification.d.ts +1 -1
- package/dist/model/builder/MergedSpecification.mjs +39 -35
- package/dist/model/model-parser.d.ts +72 -45
- package/dist/model/parser/Base.d.ts +13 -7
- package/dist/model/parser/Base.mjs +27 -16
- package/dist/model/parser/DeploymentModelParser.d.ts +8 -5
- package/dist/model/parser/DeploymentModelParser.mjs +47 -45
- package/dist/model/parser/DeploymentViewParser.d.ts +8 -5
- package/dist/model/parser/DeploymentViewParser.mjs +1 -2
- package/dist/model/parser/FqnRefParser.d.ts +10 -6
- package/dist/model/parser/FqnRefParser.mjs +12 -4
- package/dist/model/parser/GlobalsParser.d.ts +8 -5
- package/dist/model/parser/GlobalsParser.mjs +5 -3
- package/dist/model/parser/ImportsParser.d.ts +8 -5
- package/dist/model/parser/ImportsParser.mjs +4 -2
- package/dist/model/parser/ModelParser.d.ts +8 -5
- package/dist/model/parser/ModelParser.mjs +31 -36
- package/dist/model/parser/PredicatesParser.d.ts +8 -5
- package/dist/model/parser/SpecificationParser.d.ts +8 -5
- package/dist/model/parser/SpecificationParser.mjs +15 -21
- package/dist/model/parser/ValueConverter.mjs +1 -1
- package/dist/model/parser/ViewsParser.d.ts +8 -5
- package/dist/model/parser/ViewsParser.mjs +2 -4
- package/dist/test/testServices.mjs +22 -24
- package/package.json +7 -7
|
@@ -1,11 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
FqnRef,
|
|
3
|
+
invariant,
|
|
4
|
+
isNonEmptyArray,
|
|
5
|
+
LinkedList,
|
|
6
|
+
nameFromFqn,
|
|
7
|
+
nonexhaustive,
|
|
8
|
+
nonNullable,
|
|
9
|
+
omitUndefined
|
|
10
|
+
} from "@likec4/core";
|
|
11
|
+
import { loggable } from "@likec4/log";
|
|
12
|
+
import { filter, first, isDefined, isEmpty, isTruthy, mapToObj, pipe } from "remeda";
|
|
3
13
|
import {
|
|
4
14
|
ast,
|
|
5
15
|
toRelationshipStyleExcludeDefaults
|
|
6
16
|
} from "../../ast.mjs";
|
|
7
|
-
import {
|
|
17
|
+
import { serverLogger } from "../../logger.mjs";
|
|
8
18
|
import { stringHash } from "../../utils/stringHash.mjs";
|
|
19
|
+
const logger = serverLogger.getChild("DeploymentModelParser");
|
|
9
20
|
function* streamDeploymentModel(doc) {
|
|
10
21
|
const traverseStack = LinkedList.from(
|
|
11
22
|
doc.parseResult.value.deployments.flatMap((m) => m.elements)
|
|
@@ -58,7 +69,7 @@ export function DeploymentModelParser(B) {
|
|
|
58
69
|
nonexhaustive(el);
|
|
59
70
|
}
|
|
60
71
|
} catch (e) {
|
|
61
|
-
|
|
72
|
+
logger.warn(loggable(e));
|
|
62
73
|
}
|
|
63
74
|
}
|
|
64
75
|
}
|
|
@@ -75,23 +86,21 @@ export function DeploymentModelParser(B) {
|
|
|
75
86
|
filter(ast.isElementStringProperty),
|
|
76
87
|
mapToObj((p) => [p.key, p.value])
|
|
77
88
|
);
|
|
78
|
-
const { title, ...descAndTech } = this.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
bodyProps
|
|
83
|
-
);
|
|
89
|
+
const { title, ...descAndTech } = this.parseBaseProps(bodyProps, {
|
|
90
|
+
title: astNode.title,
|
|
91
|
+
summary: astNode.summary
|
|
92
|
+
});
|
|
84
93
|
const links = this.convertLinks(astNode.body);
|
|
85
|
-
return {
|
|
94
|
+
return omitUndefined({
|
|
86
95
|
id,
|
|
87
96
|
kind,
|
|
88
97
|
title: title ?? nameFromFqn(id),
|
|
89
|
-
...metadata && { metadata },
|
|
90
|
-
...tags && { tags },
|
|
91
|
-
...links && isNonEmptyArray(links) && { links },
|
|
92
98
|
...descAndTech,
|
|
93
|
-
|
|
94
|
-
|
|
99
|
+
tags: tags ?? void 0,
|
|
100
|
+
...links && isNonEmptyArray(links) && { links },
|
|
101
|
+
style,
|
|
102
|
+
metadata
|
|
103
|
+
});
|
|
95
104
|
}
|
|
96
105
|
parseDeployedInstance(astNode) {
|
|
97
106
|
const isValid = this.isValid;
|
|
@@ -107,22 +116,20 @@ export function DeploymentModelParser(B) {
|
|
|
107
116
|
filter(ast.isElementStringProperty),
|
|
108
117
|
mapToObj((p) => [p.key, p.value])
|
|
109
118
|
);
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
bodyProps
|
|
115
|
-
);
|
|
119
|
+
const baseProps = this.parseBaseProps(bodyProps, {
|
|
120
|
+
title: astNode.title,
|
|
121
|
+
summary: astNode.summary
|
|
122
|
+
});
|
|
116
123
|
const links = this.convertLinks(astNode.body);
|
|
117
|
-
return {
|
|
124
|
+
return omitUndefined({
|
|
118
125
|
id,
|
|
119
126
|
element: target,
|
|
120
|
-
|
|
121
|
-
...tags && { tags },
|
|
127
|
+
tags: tags ?? void 0,
|
|
122
128
|
...links && isNonEmptyArray(links) && { links },
|
|
123
|
-
...
|
|
124
|
-
style
|
|
125
|
-
|
|
129
|
+
...baseProps,
|
|
130
|
+
style,
|
|
131
|
+
metadata
|
|
132
|
+
});
|
|
126
133
|
}
|
|
127
134
|
parseExtendDeployment(astNode) {
|
|
128
135
|
if (!this.isValid(astNode)) {
|
|
@@ -140,8 +147,8 @@ export function DeploymentModelParser(B) {
|
|
|
140
147
|
id,
|
|
141
148
|
astPath,
|
|
142
149
|
...metadata && { metadata },
|
|
143
|
-
|
|
144
|
-
|
|
150
|
+
tags,
|
|
151
|
+
links: isNonEmptyArray(links) ? links : null
|
|
145
152
|
};
|
|
146
153
|
}
|
|
147
154
|
_resolveDeploymentRelationSource(node) {
|
|
@@ -175,16 +182,11 @@ export function DeploymentModelParser(B) {
|
|
|
175
182
|
const navigateTo = pipe(
|
|
176
183
|
astNode.body?.props ?? [],
|
|
177
184
|
filter(ast.isRelationNavigateToProperty),
|
|
178
|
-
map((p) => p.value.view.ref?.name),
|
|
179
|
-
filter(isTruthy),
|
|
180
185
|
first()
|
|
181
|
-
);
|
|
182
|
-
const titleDescAndTech = this.
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
},
|
|
186
|
-
bodyProps
|
|
187
|
-
);
|
|
186
|
+
)?.value.view.ref?.name;
|
|
187
|
+
const titleDescAndTech = this.parseBaseProps(bodyProps, {
|
|
188
|
+
title: astNode.title
|
|
189
|
+
});
|
|
188
190
|
const styleProp = astNode.body?.props.find(ast.isRelationStyleProperty);
|
|
189
191
|
const id = stringHash(
|
|
190
192
|
"deployment",
|
|
@@ -192,19 +194,19 @@ export function DeploymentModelParser(B) {
|
|
|
192
194
|
source.deployment,
|
|
193
195
|
target.deployment
|
|
194
196
|
);
|
|
195
|
-
return {
|
|
197
|
+
return omitUndefined({
|
|
196
198
|
id,
|
|
197
199
|
source,
|
|
198
200
|
target,
|
|
199
201
|
...titleDescAndTech,
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
202
|
+
metadata,
|
|
203
|
+
kind,
|
|
204
|
+
tags: tags ?? void 0,
|
|
203
205
|
...isNonEmptyArray(links) && { links },
|
|
204
206
|
...toRelationshipStyleExcludeDefaults(styleProp?.props, isValid),
|
|
205
|
-
|
|
207
|
+
navigateTo,
|
|
206
208
|
astPath
|
|
207
|
-
};
|
|
209
|
+
});
|
|
208
210
|
}
|
|
209
211
|
};
|
|
210
212
|
}
|
|
@@ -48,16 +48,19 @@ export declare function DeploymentViewParser<TBase extends WithExpressionV2 & Wi
|
|
|
48
48
|
parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
|
|
49
49
|
parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
|
|
50
50
|
parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
|
|
51
|
-
|
|
52
|
-
title?: string | undefined;
|
|
53
|
-
description?: string | undefined;
|
|
54
|
-
technology?: string | undefined;
|
|
55
|
-
}, bodyProps: {
|
|
51
|
+
parseBaseProps(props: {
|
|
56
52
|
title?: ast.MarkdownOrString | undefined;
|
|
53
|
+
summary?: ast.MarkdownOrString | undefined;
|
|
57
54
|
description?: ast.MarkdownOrString | undefined;
|
|
58
55
|
technology?: ast.MarkdownOrString | undefined;
|
|
56
|
+
}, override?: {
|
|
57
|
+
title?: string | undefined;
|
|
58
|
+
summary?: string | undefined;
|
|
59
|
+
description?: string | undefined;
|
|
60
|
+
technology?: string | undefined;
|
|
59
61
|
}): {
|
|
60
62
|
title?: string;
|
|
63
|
+
summary?: c4.MarkdownOrString;
|
|
61
64
|
description?: c4.MarkdownOrString;
|
|
62
65
|
technology?: string;
|
|
63
66
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type * as c4 from '@likec4/core';
|
|
2
|
+
import { type AstNode } from 'langium';
|
|
2
3
|
import { ast } from '../../ast';
|
|
3
4
|
import { type Base } from './Base';
|
|
4
5
|
export type WithExpressionV2 = ReturnType<typeof ExpressionV2Parser>;
|
|
@@ -25,7 +26,7 @@ export declare function ExpressionV2Parser<TBase extends Base>(B: TBase): {
|
|
|
25
26
|
readonly doc: import("../../ast").ParsedLikeC4LangiumDocument;
|
|
26
27
|
get project(): import("../../workspace").Project;
|
|
27
28
|
resolveFqn(node: ast.FqnReferenceable): c4.Fqn;
|
|
28
|
-
getAstNodePath(node:
|
|
29
|
+
getAstNodePath(node: AstNode): any;
|
|
29
30
|
getMetadata(metadataAstNode: ast.MetadataProperty | undefined): {
|
|
30
31
|
[key: string]: string;
|
|
31
32
|
} | undefined;
|
|
@@ -43,16 +44,19 @@ export declare function ExpressionV2Parser<TBase extends Base>(B: TBase): {
|
|
|
43
44
|
parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
|
|
44
45
|
parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
|
|
45
46
|
parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
|
|
46
|
-
|
|
47
|
-
title?: string | undefined;
|
|
48
|
-
description?: string | undefined;
|
|
49
|
-
technology?: string | undefined;
|
|
50
|
-
}, bodyProps: {
|
|
47
|
+
parseBaseProps(props: {
|
|
51
48
|
title?: ast.MarkdownOrString | undefined;
|
|
49
|
+
summary?: ast.MarkdownOrString | undefined;
|
|
52
50
|
description?: ast.MarkdownOrString | undefined;
|
|
53
51
|
technology?: ast.MarkdownOrString | undefined;
|
|
52
|
+
}, override?: {
|
|
53
|
+
title?: string | undefined;
|
|
54
|
+
summary?: string | undefined;
|
|
55
|
+
description?: string | undefined;
|
|
56
|
+
technology?: string | undefined;
|
|
54
57
|
}): {
|
|
55
58
|
title?: string;
|
|
59
|
+
summary?: c4.MarkdownOrString;
|
|
56
60
|
description?: c4.MarkdownOrString;
|
|
57
61
|
technology?: string;
|
|
58
62
|
};
|
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import { invariant, nonexhaustive, nonNullable } from "@likec4/core";
|
|
2
|
+
import { loggable } from "@likec4/log";
|
|
3
|
+
import { AstUtils } from "langium";
|
|
2
4
|
import { isBoolean, isDefined, isNonNullish, isTruthy } from "remeda";
|
|
3
5
|
import { ast, parseAstOpacityProperty, parseAstSizeValue, parseMarkdownAsString, toColor } from "../../ast.mjs";
|
|
4
|
-
import {
|
|
6
|
+
import { serverLogger } from "../../logger.mjs";
|
|
5
7
|
import { projectIdFrom } from "../../utils/index.mjs";
|
|
6
8
|
import { importsRef, instanceRef } from "../../utils/fqnRef.mjs";
|
|
7
9
|
import { createBinaryOperator, parseWhereClause } from "../model-parser-where.mjs";
|
|
8
10
|
import { removeIndent } from "./Base.mjs";
|
|
11
|
+
const logger = serverLogger.getChild("ExpressionV2Parser");
|
|
12
|
+
const location = (astNode) => {
|
|
13
|
+
const cst = astNode.$cstNode;
|
|
14
|
+
const position = cst ? `:${cst.range.start.line + 1}:${cst.range.start.character + 1}` : "";
|
|
15
|
+
return `${AstUtils.getDocument(astNode).uri.fsPath}${position}`;
|
|
16
|
+
};
|
|
9
17
|
export function ExpressionV2Parser(B) {
|
|
10
18
|
return class ExpressionV2Parser extends B {
|
|
11
19
|
parseFqnRef(astNode) {
|
|
12
20
|
const refValue = nonNullable(
|
|
13
21
|
astNode.value?.ref,
|
|
14
|
-
`FqnRef
|
|
22
|
+
() => `FqnRef "${astNode.$cstNode?.text}" is empty at ${location(astNode)}`
|
|
15
23
|
);
|
|
16
24
|
if (ast.isImported(refValue)) {
|
|
17
25
|
const fqnRef = {
|
|
@@ -87,7 +95,7 @@ export function ExpressionV2Parser(B) {
|
|
|
87
95
|
return acc;
|
|
88
96
|
}
|
|
89
97
|
if (ast.isElementStringProperty(prop)) {
|
|
90
|
-
if (isDefined(prop.value)) {
|
|
98
|
+
if (isDefined(prop.value) && prop.key !== "summary") {
|
|
91
99
|
if (prop.key === "description") {
|
|
92
100
|
const parsed = this.parseMarkdownOrString(prop.value);
|
|
93
101
|
if (parsed) {
|
|
@@ -248,7 +256,7 @@ export function ExpressionV2Parser(B) {
|
|
|
248
256
|
exprs.push(this.parseFqnExpr(iter.value));
|
|
249
257
|
}
|
|
250
258
|
} catch (e) {
|
|
251
|
-
|
|
259
|
+
logger.warn(loggable(e));
|
|
252
260
|
}
|
|
253
261
|
iter = iter.prev;
|
|
254
262
|
}
|
|
@@ -72,16 +72,19 @@ export declare function GlobalsParser<TBase extends WithViewsParser>(B: TBase):
|
|
|
72
72
|
parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
|
|
73
73
|
parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
|
|
74
74
|
parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
|
|
75
|
-
|
|
76
|
-
title?: string | undefined;
|
|
77
|
-
description?: string | undefined;
|
|
78
|
-
technology?: string | undefined;
|
|
79
|
-
}, bodyProps: {
|
|
75
|
+
parseBaseProps(props: {
|
|
80
76
|
title?: ast.MarkdownOrString | undefined;
|
|
77
|
+
summary?: ast.MarkdownOrString | undefined;
|
|
81
78
|
description?: ast.MarkdownOrString | undefined;
|
|
82
79
|
technology?: ast.MarkdownOrString | undefined;
|
|
80
|
+
}, override?: {
|
|
81
|
+
title?: string | undefined;
|
|
82
|
+
summary?: string | undefined;
|
|
83
|
+
description?: string | undefined;
|
|
84
|
+
technology?: string | undefined;
|
|
83
85
|
}): {
|
|
84
86
|
title?: string;
|
|
87
|
+
summary?: c4.MarkdownOrString;
|
|
85
88
|
description?: c4.MarkdownOrString;
|
|
86
89
|
technology?: string;
|
|
87
90
|
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { nonexhaustive } from "@likec4/core";
|
|
2
|
+
import { loggable } from "@likec4/log";
|
|
2
3
|
import { hasAtLeast, isTruthy } from "remeda";
|
|
3
4
|
import { ast } from "../../ast.mjs";
|
|
4
|
-
import {
|
|
5
|
+
import { serverLogger } from "../../logger.mjs";
|
|
6
|
+
const logger = serverLogger.getChild("GlobalsParser");
|
|
5
7
|
export function GlobalsParser(B) {
|
|
6
8
|
return class GlobalsParser extends B {
|
|
7
9
|
parseGlobals() {
|
|
@@ -21,7 +23,7 @@ export function GlobalsParser(B) {
|
|
|
21
23
|
}
|
|
22
24
|
this.parseAndStoreGlobalPredicateGroupOrDynamic(predicate, globalPredicateId, c4Globals);
|
|
23
25
|
} catch (e) {
|
|
24
|
-
|
|
26
|
+
logger.warn(loggable(e));
|
|
25
27
|
}
|
|
26
28
|
}
|
|
27
29
|
const styles = globals.flatMap((r) => r.styles.filter(isValid));
|
|
@@ -40,7 +42,7 @@ export function GlobalsParser(B) {
|
|
|
40
42
|
c4Globals.styles[globalStyleId] = styles2;
|
|
41
43
|
}
|
|
42
44
|
} catch (e) {
|
|
43
|
-
|
|
45
|
+
logger.warn(loggable(e));
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
48
|
}
|
|
@@ -27,16 +27,19 @@ export declare function ImportsParser<TBase extends Base>(B: TBase): {
|
|
|
27
27
|
parseColorLiteral(astNode: ast.ColorLiteral): ProjectId | undefined;
|
|
28
28
|
parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
|
|
29
29
|
parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
|
|
30
|
-
|
|
31
|
-
title?: string | undefined;
|
|
32
|
-
description?: string | undefined;
|
|
33
|
-
technology?: string | undefined;
|
|
34
|
-
}, bodyProps: {
|
|
30
|
+
parseBaseProps(props: {
|
|
35
31
|
title?: ast.MarkdownOrString | undefined;
|
|
32
|
+
summary?: ast.MarkdownOrString | undefined;
|
|
36
33
|
description?: ast.MarkdownOrString | undefined;
|
|
37
34
|
technology?: ast.MarkdownOrString | undefined;
|
|
35
|
+
}, override?: {
|
|
36
|
+
title?: string | undefined;
|
|
37
|
+
summary?: string | undefined;
|
|
38
|
+
description?: string | undefined;
|
|
39
|
+
technology?: string | undefined;
|
|
38
40
|
}): {
|
|
39
41
|
title?: string;
|
|
42
|
+
summary?: ProjectId;
|
|
40
43
|
description?: ProjectId;
|
|
41
44
|
technology?: string;
|
|
42
45
|
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { nonNullable } from "@likec4/core";
|
|
2
|
-
import {
|
|
2
|
+
import { loggable } from "@likec4/log";
|
|
3
|
+
import { serverLogger } from "../../logger.mjs";
|
|
4
|
+
const logger = serverLogger.getChild("ImportsParser");
|
|
3
5
|
export function ImportsParser(B) {
|
|
4
6
|
return class ImportsParser extends B {
|
|
5
7
|
parseImports() {
|
|
@@ -16,7 +18,7 @@ export function ImportsParser(B) {
|
|
|
16
18
|
)
|
|
17
19
|
);
|
|
18
20
|
} catch (e) {
|
|
19
|
-
|
|
21
|
+
logger.warn(loggable(e));
|
|
20
22
|
}
|
|
21
23
|
imported = imported.prev;
|
|
22
24
|
}
|
|
@@ -49,16 +49,19 @@ export declare function ModelParser<TBase extends WithExpressionV2>(B: TBase): {
|
|
|
49
49
|
parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
|
|
50
50
|
parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
|
|
51
51
|
parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
|
|
52
|
-
|
|
53
|
-
title?: string | undefined;
|
|
54
|
-
description?: string | undefined;
|
|
55
|
-
technology?: string | undefined;
|
|
56
|
-
}, bodyProps: {
|
|
52
|
+
parseBaseProps(props: {
|
|
57
53
|
title?: ast.MarkdownOrString | undefined;
|
|
54
|
+
summary?: ast.MarkdownOrString | undefined;
|
|
58
55
|
description?: ast.MarkdownOrString | undefined;
|
|
59
56
|
technology?: ast.MarkdownOrString | undefined;
|
|
57
|
+
}, override?: {
|
|
58
|
+
title?: string | undefined;
|
|
59
|
+
summary?: string | undefined;
|
|
60
|
+
description?: string | undefined;
|
|
61
|
+
technology?: string | undefined;
|
|
60
62
|
}): {
|
|
61
63
|
title?: string;
|
|
64
|
+
summary?: c4.MarkdownOrString;
|
|
62
65
|
description?: c4.MarkdownOrString;
|
|
63
66
|
technology?: string;
|
|
64
67
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { invariant, isNonEmptyArray, LinkedList, nonexhaustive, nonNullable } from "@likec4/core";
|
|
2
|
-
import { FqnRef } from "@likec4/core/types";
|
|
2
|
+
import { FqnRef, omitUndefined } from "@likec4/core/types";
|
|
3
3
|
import { loggable } from "@likec4/log";
|
|
4
4
|
import { filter, first, isDefined, isEmpty, isTruthy, map, mapToObj, pipe } from "remeda";
|
|
5
5
|
import {
|
|
@@ -75,33 +75,30 @@ ${error}`, {
|
|
|
75
75
|
const style = this.parseElementStyle(astNode.body?.props);
|
|
76
76
|
const metadata = this.getMetadata(astNode.body?.props.find(ast.isMetadataProperty));
|
|
77
77
|
const astPath = this.getAstNodePath(astNode);
|
|
78
|
-
let [_title,
|
|
78
|
+
let [_title, _summary, _technology] = astNode.props ?? [];
|
|
79
79
|
const bodyProps = pipe(
|
|
80
80
|
astNode.body?.props ?? [],
|
|
81
81
|
filter(isValid),
|
|
82
82
|
filter(ast.isElementStringProperty),
|
|
83
83
|
mapToObj((p) => [p.key, p.value])
|
|
84
84
|
);
|
|
85
|
-
const { title, ...descAndTech } = this.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
},
|
|
91
|
-
bodyProps
|
|
92
|
-
);
|
|
85
|
+
const { title, ...descAndTech } = this.parseBaseProps(bodyProps, {
|
|
86
|
+
title: _title,
|
|
87
|
+
summary: _summary,
|
|
88
|
+
technology: _technology
|
|
89
|
+
});
|
|
93
90
|
const links = this.parseLinks(astNode.body);
|
|
94
|
-
return {
|
|
91
|
+
return omitUndefined({
|
|
95
92
|
id,
|
|
96
93
|
kind,
|
|
97
94
|
astPath,
|
|
98
95
|
title: title ?? astNode.name,
|
|
99
|
-
|
|
100
|
-
|
|
96
|
+
metadata,
|
|
97
|
+
tags: tags ?? void 0,
|
|
101
98
|
...links && isNonEmptyArray(links) && { links },
|
|
102
99
|
...descAndTech,
|
|
103
100
|
style
|
|
104
|
-
};
|
|
101
|
+
});
|
|
105
102
|
}
|
|
106
103
|
parseExtendElement(astNode) {
|
|
107
104
|
const id = this.resolveFqn(astNode);
|
|
@@ -112,13 +109,13 @@ ${error}`, {
|
|
|
112
109
|
if (!tags && isEmpty(metadata ?? {}) && isEmpty(links)) {
|
|
113
110
|
return null;
|
|
114
111
|
}
|
|
115
|
-
return {
|
|
112
|
+
return omitUndefined({
|
|
116
113
|
id,
|
|
117
114
|
astPath,
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
};
|
|
115
|
+
metadata,
|
|
116
|
+
tags,
|
|
117
|
+
links: isNonEmptyArray(links) ? links : null
|
|
118
|
+
});
|
|
122
119
|
}
|
|
123
120
|
_resolveRelationSource(node) {
|
|
124
121
|
if (isDefined(node.source)) {
|
|
@@ -156,35 +153,33 @@ ${error}`, {
|
|
|
156
153
|
filter(isTruthy),
|
|
157
154
|
first()
|
|
158
155
|
);
|
|
159
|
-
const { title = "",
|
|
156
|
+
const { title = "", description, technology } = this.parseBaseProps(bodyProps, {
|
|
160
157
|
// inline props
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
},
|
|
166
|
-
bodyProps
|
|
167
|
-
);
|
|
158
|
+
title: astNode.title,
|
|
159
|
+
description: astNode.description,
|
|
160
|
+
technology: astNode.technology
|
|
161
|
+
});
|
|
168
162
|
const styleProp = astNode.body?.props.find(ast.isRelationStyleProperty);
|
|
169
163
|
const id = stringHash(
|
|
170
164
|
astPath,
|
|
171
165
|
source.model,
|
|
172
166
|
target.model
|
|
173
167
|
);
|
|
174
|
-
return {
|
|
168
|
+
return omitUndefined({
|
|
175
169
|
id,
|
|
176
170
|
astPath,
|
|
177
171
|
source,
|
|
178
172
|
target,
|
|
179
173
|
title,
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
174
|
+
metadata,
|
|
175
|
+
kind,
|
|
176
|
+
tags: tags ?? void 0,
|
|
177
|
+
links: isNonEmptyArray(links) ? links : void 0,
|
|
178
|
+
navigateTo: navigateTo ? navigateTo : void 0,
|
|
179
|
+
description,
|
|
180
|
+
technology,
|
|
181
|
+
...toRelationshipStyleExcludeDefaults(styleProp?.props, isValid)
|
|
182
|
+
});
|
|
188
183
|
}
|
|
189
184
|
};
|
|
190
185
|
}
|
|
@@ -54,16 +54,19 @@ export declare function PredicatesParser<TBase extends WithExpressionV2>(B: TBas
|
|
|
54
54
|
parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
|
|
55
55
|
parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
|
|
56
56
|
parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
|
|
57
|
-
|
|
58
|
-
title?: string | undefined;
|
|
59
|
-
description?: string | undefined;
|
|
60
|
-
technology?: string | undefined;
|
|
61
|
-
}, bodyProps: {
|
|
57
|
+
parseBaseProps(props: {
|
|
62
58
|
title?: ast.MarkdownOrString | undefined;
|
|
59
|
+
summary?: ast.MarkdownOrString | undefined;
|
|
63
60
|
description?: ast.MarkdownOrString | undefined;
|
|
64
61
|
technology?: ast.MarkdownOrString | undefined;
|
|
62
|
+
}, override?: {
|
|
63
|
+
title?: string | undefined;
|
|
64
|
+
summary?: string | undefined;
|
|
65
|
+
description?: string | undefined;
|
|
66
|
+
technology?: string | undefined;
|
|
65
67
|
}): {
|
|
66
68
|
title?: string;
|
|
69
|
+
summary?: c4.MarkdownOrString;
|
|
67
70
|
description?: c4.MarkdownOrString;
|
|
68
71
|
technology?: string;
|
|
69
72
|
};
|
|
@@ -33,16 +33,19 @@ export declare function SpecificationParser<TBase extends Base>(B: TBase): {
|
|
|
33
33
|
parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
|
|
34
34
|
parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
|
|
35
35
|
parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
|
|
36
|
-
|
|
37
|
-
title?: string | undefined;
|
|
38
|
-
description?: string | undefined;
|
|
39
|
-
technology?: string | undefined;
|
|
40
|
-
}, bodyProps: {
|
|
36
|
+
parseBaseProps(props: {
|
|
41
37
|
title?: ast.MarkdownOrString | undefined;
|
|
38
|
+
summary?: ast.MarkdownOrString | undefined;
|
|
42
39
|
description?: ast.MarkdownOrString | undefined;
|
|
43
40
|
technology?: ast.MarkdownOrString | undefined;
|
|
41
|
+
}, override?: {
|
|
42
|
+
title?: string | undefined;
|
|
43
|
+
summary?: string | undefined;
|
|
44
|
+
description?: string | undefined;
|
|
45
|
+
technology?: string | undefined;
|
|
44
46
|
}): {
|
|
45
47
|
title?: string;
|
|
48
|
+
summary?: c4.MarkdownOrString;
|
|
46
49
|
description?: c4.MarkdownOrString;
|
|
47
50
|
technology?: string;
|
|
48
51
|
};
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import * as c4 from "@likec4/core";
|
|
2
|
+
import { omitUndefined } from "@likec4/core";
|
|
2
3
|
import { nonNullable } from "@likec4/core/utils";
|
|
4
|
+
import { loggable } from "@likec4/log";
|
|
3
5
|
import { filter, isNonNullish, isNullish, isTruthy, mapToObj, omitBy, pipe } from "remeda";
|
|
4
6
|
import { ast, parseMarkdownAsString, toRelationshipStyleExcludeDefaults } from "../../ast.mjs";
|
|
5
|
-
import {
|
|
7
|
+
import { serverLogger } from "../../logger.mjs";
|
|
6
8
|
import { removeIndent } from "./Base.mjs";
|
|
9
|
+
const logger = serverLogger.getChild("SpecificationParser");
|
|
7
10
|
export function SpecificationParser(B) {
|
|
8
11
|
return class SpecificationParser extends B {
|
|
9
12
|
parseSpecification() {
|
|
@@ -20,14 +23,14 @@ export function SpecificationParser(B) {
|
|
|
20
23
|
try {
|
|
21
24
|
Object.assign(c4Specification.elements, this.parseElementSpecificationNode(elementSpec));
|
|
22
25
|
} catch (e) {
|
|
23
|
-
|
|
26
|
+
logger.warn(loggable(e));
|
|
24
27
|
}
|
|
25
28
|
}
|
|
26
29
|
for (const deploymentNodeSpec of specifications.flatMap((s) => s.deploymentNodes.filter(isValid))) {
|
|
27
30
|
try {
|
|
28
31
|
Object.assign(c4Specification.deployments, this.parseElementSpecificationNode(deploymentNodeSpec));
|
|
29
32
|
} catch (e) {
|
|
30
|
-
|
|
33
|
+
logger.warn(loggable(e));
|
|
31
34
|
}
|
|
32
35
|
}
|
|
33
36
|
const relations_specs = specifications.flatMap((s) => s.relationships.filter(this.isValid));
|
|
@@ -52,7 +55,7 @@ export function SpecificationParser(B) {
|
|
|
52
55
|
...toRelationshipStyleExcludeDefaults(props, this.isValid)
|
|
53
56
|
};
|
|
54
57
|
} catch (e) {
|
|
55
|
-
|
|
58
|
+
logger.warn(loggable(e));
|
|
56
59
|
}
|
|
57
60
|
}
|
|
58
61
|
const tags_specs = specifications.flatMap((s) => s.tags.filter(this.isValid));
|
|
@@ -68,7 +71,7 @@ export function SpecificationParser(B) {
|
|
|
68
71
|
};
|
|
69
72
|
}
|
|
70
73
|
} catch (e) {
|
|
71
|
-
|
|
74
|
+
logger.warn(loggable(e));
|
|
72
75
|
}
|
|
73
76
|
}
|
|
74
77
|
const colors_specs = specifications.flatMap((s) => s.colors.filter(isValid));
|
|
@@ -83,7 +86,7 @@ export function SpecificationParser(B) {
|
|
|
83
86
|
color: nonNullable(this.parseColorLiteral(color), `Color "${colorName}" is not valid: ${color}`)
|
|
84
87
|
};
|
|
85
88
|
} catch (e) {
|
|
86
|
-
|
|
89
|
+
logger.warn(loggable(e));
|
|
87
90
|
}
|
|
88
91
|
}
|
|
89
92
|
}
|
|
@@ -101,25 +104,16 @@ export function SpecificationParser(B) {
|
|
|
101
104
|
filter((p) => this.isValid(p)),
|
|
102
105
|
mapToObj((p) => [p.key, p.value])
|
|
103
106
|
);
|
|
104
|
-
const
|
|
105
|
-
{
|
|
106
|
-
title: void 0,
|
|
107
|
-
description: void 0,
|
|
108
|
-
technology: void 0
|
|
109
|
-
},
|
|
110
|
-
bodyProps
|
|
111
|
-
);
|
|
107
|
+
const baseProps = this.parseBaseProps(bodyProps);
|
|
112
108
|
const notation = removeIndent(parseMarkdownAsString(bodyProps.notation));
|
|
113
109
|
return {
|
|
114
|
-
[kindName]: {
|
|
115
|
-
...
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
...notation && { notation },
|
|
119
|
-
...tags && { tags },
|
|
110
|
+
[kindName]: omitUndefined({
|
|
111
|
+
...baseProps,
|
|
112
|
+
notation,
|
|
113
|
+
tags: tags ?? void 0,
|
|
120
114
|
...links && c4.isNonEmptyArray(links) && { links },
|
|
121
115
|
style
|
|
122
|
-
}
|
|
116
|
+
})
|
|
123
117
|
};
|
|
124
118
|
}
|
|
125
119
|
};
|