@likec4/language-server 1.18.0 → 1.19.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.
Files changed (220) hide show
  1. package/dist/LikeC4FileSystem.d.ts +13 -0
  2. package/dist/LikeC4FileSystem.js +27 -0
  3. package/dist/Rpc.d.ts +9 -0
  4. package/dist/Rpc.js +126 -0
  5. package/dist/ast.d.ts +200 -0
  6. package/dist/ast.js +276 -0
  7. package/dist/browser.d.ts +6 -20
  8. package/dist/browser.js +13 -0
  9. package/dist/formatting/LikeC4Formatter.d.ts +27 -0
  10. package/dist/formatting/LikeC4Formatter.js +261 -0
  11. package/dist/formatting/utils.d.ts +6 -0
  12. package/dist/formatting/utils.js +15 -0
  13. package/dist/generated/ast.d.ts +1242 -0
  14. package/dist/generated/ast.js +1945 -0
  15. package/dist/generated/grammar.d.ts +6 -0
  16. package/dist/generated/grammar.js +3 -0
  17. package/dist/generated/module.d.ts +9 -0
  18. package/dist/generated/module.js +23 -0
  19. package/dist/generated-lib/icons.d.ts +1 -0
  20. package/dist/{likec4lib.mjs → generated-lib/icons.js} +1 -6
  21. package/dist/index.d.ts +8 -31
  22. package/dist/index.js +13 -0
  23. package/dist/like-c4.langium +845 -0
  24. package/dist/likec4lib.d.ts +4 -6
  25. package/dist/likec4lib.js +4 -0
  26. package/dist/logger.d.ts +7 -0
  27. package/dist/logger.js +73 -0
  28. package/dist/lsp/CodeLensProvider.d.ts +9 -0
  29. package/dist/lsp/CodeLensProvider.js +40 -0
  30. package/dist/lsp/CompletionProvider.d.ts +6 -0
  31. package/dist/lsp/CompletionProvider.js +135 -0
  32. package/dist/lsp/DocumentHighlightProvider.d.ts +9 -0
  33. package/dist/lsp/DocumentHighlightProvider.js +10 -0
  34. package/dist/lsp/DocumentLinkProvider.d.ts +11 -0
  35. package/dist/lsp/DocumentLinkProvider.js +49 -0
  36. package/dist/lsp/DocumentSymbolProvider.d.ts +23 -0
  37. package/dist/lsp/DocumentSymbolProvider.js +202 -0
  38. package/dist/lsp/HoverProvider.d.ts +10 -0
  39. package/dist/lsp/HoverProvider.js +69 -0
  40. package/dist/lsp/RenameProvider.d.ts +5 -0
  41. package/dist/lsp/RenameProvider.js +6 -0
  42. package/dist/lsp/SemanticTokenProvider.d.ts +7 -0
  43. package/dist/lsp/SemanticTokenProvider.js +297 -0
  44. package/dist/lsp/index.d.ts +7 -0
  45. package/dist/lsp/index.js +7 -0
  46. package/dist/model/deployments-index.d.ts +60 -0
  47. package/dist/model/deployments-index.js +181 -0
  48. package/dist/model/fqn-computation.d.ts +3 -0
  49. package/dist/model/fqn-computation.js +72 -0
  50. package/dist/model/fqn-index.d.ts +25 -0
  51. package/dist/model/fqn-index.js +96 -0
  52. package/dist/model/index.d.ts +6 -0
  53. package/dist/model/index.js +6 -0
  54. package/dist/model/model-builder.d.ts +32 -0
  55. package/dist/model/model-builder.js +598 -0
  56. package/dist/model/model-locator.d.ts +23 -0
  57. package/dist/model/model-locator.js +126 -0
  58. package/dist/model/model-parser-where.d.ts +3 -0
  59. package/dist/model/model-parser-where.js +70 -0
  60. package/dist/model/model-parser.d.ts +292 -0
  61. package/dist/model/model-parser.js +72 -0
  62. package/dist/model/parser/Base.d.ts +28 -0
  63. package/dist/model/parser/Base.js +87 -0
  64. package/dist/model/parser/DeploymentModelParser.d.ts +33 -0
  65. package/dist/model/parser/DeploymentModelParser.js +162 -0
  66. package/dist/model/parser/DeploymentViewParser.d.ts +38 -0
  67. package/dist/model/parser/DeploymentViewParser.js +98 -0
  68. package/dist/model/parser/FqnRefParser.d.ts +29 -0
  69. package/dist/model/parser/FqnRefParser.js +108 -0
  70. package/dist/model/parser/GlobalsParser.d.ts +66 -0
  71. package/dist/model/parser/GlobalsParser.js +80 -0
  72. package/dist/model/parser/ModelParser.d.ts +27 -0
  73. package/dist/model/parser/ModelParser.js +122 -0
  74. package/dist/model/parser/PredicatesParser.d.ts +34 -0
  75. package/dist/model/parser/PredicatesParser.js +272 -0
  76. package/dist/model/parser/SpecificationParser.d.ts +27 -0
  77. package/dist/model/parser/SpecificationParser.js +120 -0
  78. package/dist/model/parser/ViewsParser.d.ts +64 -0
  79. package/dist/model/parser/ViewsParser.js +377 -0
  80. package/dist/model-change/ModelChanges.d.ts +15 -0
  81. package/dist/model-change/ModelChanges.js +89 -0
  82. package/dist/model-change/changeElementStyle.d.ts +16 -0
  83. package/dist/model-change/changeElementStyle.js +136 -0
  84. package/dist/model-change/changeViewLayout.d.ts +12 -0
  85. package/dist/model-change/changeViewLayout.js +32 -0
  86. package/dist/model-change/saveManualLayout.d.ts +11 -0
  87. package/dist/model-change/saveManualLayout.js +27 -0
  88. package/dist/module.d.ts +62 -0
  89. package/dist/module.js +123 -0
  90. package/dist/protocol.d.ts +20 -23
  91. package/dist/protocol.js +14 -0
  92. package/dist/references/index.d.ts +3 -0
  93. package/dist/references/index.js +3 -0
  94. package/dist/references/name-provider.d.ts +9 -0
  95. package/dist/references/name-provider.js +33 -0
  96. package/dist/references/scope-computation.d.ts +20 -0
  97. package/dist/references/scope-computation.js +281 -0
  98. package/dist/references/scope-provider.d.ts +16 -0
  99. package/dist/references/scope-provider.js +165 -0
  100. package/dist/shared/NodeKindProvider.d.ts +15 -0
  101. package/dist/shared/NodeKindProvider.js +108 -0
  102. package/dist/shared/WorkspaceManager.d.ts +18 -0
  103. package/dist/shared/WorkspaceManager.js +36 -0
  104. package/dist/shared/WorkspaceSymbolProvider.d.ts +3 -0
  105. package/dist/shared/WorkspaceSymbolProvider.js +3 -0
  106. package/dist/shared/index.d.ts +3 -0
  107. package/dist/shared/index.js +3 -0
  108. package/dist/test/index.d.ts +1 -0
  109. package/dist/test/index.js +1 -0
  110. package/dist/test/setup.d.ts +1 -0
  111. package/dist/test/setup.js +7 -0
  112. package/dist/test/testServices.d.ts +22 -0
  113. package/dist/test/testServices.js +119 -0
  114. package/dist/utils/elementRef.d.ts +11 -0
  115. package/dist/utils/elementRef.js +15 -0
  116. package/dist/utils/fqnRef.d.ts +8 -0
  117. package/dist/utils/fqnRef.js +46 -0
  118. package/dist/utils/index.d.ts +1 -0
  119. package/dist/utils/index.js +1 -0
  120. package/dist/utils/printDocs.d.ts +2 -0
  121. package/dist/utils/printDocs.js +1 -0
  122. package/dist/utils/stringHash.d.ts +1 -0
  123. package/dist/utils/stringHash.js +5 -0
  124. package/dist/validation/_shared.d.ts +3 -0
  125. package/dist/validation/_shared.js +22 -0
  126. package/dist/validation/deployment-checks.d.ts +6 -0
  127. package/dist/validation/deployment-checks.js +114 -0
  128. package/dist/validation/dynamic-view-rule.d.ts +4 -0
  129. package/dist/validation/dynamic-view-rule.js +16 -0
  130. package/dist/validation/dynamic-view-step.d.ts +4 -0
  131. package/dist/validation/dynamic-view-step.js +33 -0
  132. package/dist/validation/element.d.ts +4 -0
  133. package/dist/validation/element.js +49 -0
  134. package/dist/validation/index.d.ts +15 -0
  135. package/dist/validation/index.js +152 -0
  136. package/dist/validation/property-checks.d.ts +6 -0
  137. package/dist/validation/property-checks.js +38 -0
  138. package/dist/validation/relation.d.ts +5 -0
  139. package/dist/validation/relation.js +56 -0
  140. package/dist/validation/specification.d.ts +11 -0
  141. package/dist/validation/specification.js +136 -0
  142. package/dist/validation/view-predicates/element-with.d.ts +4 -0
  143. package/dist/validation/view-predicates/element-with.js +30 -0
  144. package/dist/validation/view-predicates/expanded-element.d.ts +4 -0
  145. package/dist/validation/view-predicates/expanded-element.js +11 -0
  146. package/dist/validation/view-predicates/expression-v2.d.ts +5 -0
  147. package/dist/validation/view-predicates/expression-v2.js +83 -0
  148. package/dist/validation/view-predicates/incoming.d.ts +4 -0
  149. package/dist/validation/view-predicates/incoming.js +15 -0
  150. package/dist/validation/view-predicates/index.d.ts +6 -0
  151. package/dist/validation/view-predicates/index.js +6 -0
  152. package/dist/validation/view-predicates/outgoing.d.ts +4 -0
  153. package/dist/validation/view-predicates/outgoing.js +15 -0
  154. package/dist/validation/view-predicates/relation-with.d.ts +4 -0
  155. package/dist/validation/view-predicates/relation-with.js +12 -0
  156. package/dist/validation/view.d.ts +4 -0
  157. package/dist/validation/view.js +23 -0
  158. package/dist/view-utils/assignNavigateTo.d.ts +2 -0
  159. package/dist/view-utils/assignNavigateTo.js +25 -0
  160. package/dist/view-utils/index.d.ts +2 -0
  161. package/dist/view-utils/index.js +2 -0
  162. package/dist/view-utils/manual-layout.d.ts +7 -0
  163. package/dist/view-utils/manual-layout.js +99 -0
  164. package/dist/view-utils/resolve-relative-paths.d.ts +2 -0
  165. package/dist/view-utils/resolve-relative-paths.js +78 -0
  166. package/package.json +36 -53
  167. package/src/LikeC4FileSystem.ts +22 -21
  168. package/src/ast.ts +44 -133
  169. package/src/browser.ts +10 -11
  170. package/src/generated/ast.ts +177 -177
  171. package/src/generated/grammar.ts +1 -1
  172. package/src/index.ts +10 -8
  173. package/src/like-c4.langium +37 -34
  174. package/src/logger.ts +34 -55
  175. package/src/lsp/CompletionProvider.ts +4 -4
  176. package/src/lsp/HoverProvider.ts +5 -3
  177. package/src/lsp/SemanticTokenProvider.ts +2 -2
  178. package/src/model/deployments-index.ts +18 -14
  179. package/src/model/model-builder.ts +10 -8
  180. package/src/model/model-parser.ts +62 -1574
  181. package/src/model/parser/Base.ts +107 -0
  182. package/src/model/parser/DeploymentModelParser.ts +192 -0
  183. package/src/model/parser/DeploymentViewParser.ts +116 -0
  184. package/src/model/parser/FqnRefParser.ts +118 -0
  185. package/src/model/parser/GlobalsParser.ts +96 -0
  186. package/src/model/parser/ModelParser.ts +141 -0
  187. package/src/model/parser/PredicatesParser.ts +291 -0
  188. package/src/model/parser/SpecificationParser.ts +133 -0
  189. package/src/model/parser/ViewsParser.ts +428 -0
  190. package/src/module.ts +17 -18
  191. package/src/references/scope-provider.ts +13 -7
  192. package/src/utils/{deploymentRef.ts → fqnRef.ts} +27 -2
  193. package/src/validation/_shared.ts +0 -1
  194. package/src/validation/deployment-checks.ts +49 -62
  195. package/src/validation/index.ts +100 -9
  196. package/src/validation/view-predicates/expression-v2.ts +101 -0
  197. package/src/validation/view-predicates/index.ts +1 -1
  198. package/src/view-utils/assignNavigateTo.ts +1 -1
  199. package/src/view-utils/manual-layout.ts +25 -0
  200. package/dist/browser.cjs +0 -25
  201. package/dist/browser.d.cts +0 -23
  202. package/dist/browser.d.mts +0 -23
  203. package/dist/browser.mjs +0 -20
  204. package/dist/index.cjs +0 -53
  205. package/dist/index.d.cts +0 -34
  206. package/dist/index.d.mts +0 -34
  207. package/dist/index.mjs +0 -46
  208. package/dist/likec4lib.cjs +0 -1546
  209. package/dist/likec4lib.d.cts +0 -6
  210. package/dist/likec4lib.d.mts +0 -6
  211. package/dist/protocol.cjs +0 -25
  212. package/dist/protocol.d.cts +0 -48
  213. package/dist/protocol.d.mts +0 -48
  214. package/dist/protocol.mjs +0 -17
  215. package/dist/shared/language-server.CO_nmHiL.cjs +0 -7689
  216. package/dist/shared/language-server.Da6ey08o.d.cts +0 -1619
  217. package/dist/shared/language-server.De7S3e5Z.d.ts +0 -1619
  218. package/dist/shared/language-server.Dj4iDjtB.d.mts +0 -1619
  219. package/dist/shared/language-server.oO_9JoAG.mjs +0 -7666
  220. package/src/validation/view-predicates/deployments.ts +0 -56
@@ -0,0 +1,87 @@
1
+ import { invariant, isNonEmptyArray } from "@likec4/core";
2
+ import { filter, flatMap, isNonNullish, isTruthy, mapToObj, pipe } from "remeda";
3
+ import stripIndent from "strip-indent";
4
+ import { ast } from "../../ast.js";
5
+ import { getFqnElementRef } from "../../utils/elementRef.js";
6
+ import { checksFromDiagnostics } from "../../validation/index.js";
7
+ export function toSingleLine(str) {
8
+ return isNonNullish(str) ? removeIndent(str).split("\n").join(" ") : void 0;
9
+ }
10
+ export function removeIndent(str) {
11
+ return isNonNullish(str) ? stripIndent(str).trim() : void 0;
12
+ }
13
+ export class BaseParser {
14
+ constructor(services, doc) {
15
+ this.services = services;
16
+ this.doc = doc;
17
+ this.isValid = checksFromDiagnostics(doc).isValid;
18
+ }
19
+ isValid;
20
+ resolveFqn(node) {
21
+ if (ast.isDeploymentElement(node)) {
22
+ return this.services.likec4.DeploymentsIndex.getFqn(node);
23
+ }
24
+ if (ast.isExtendElement(node)) {
25
+ return getFqnElementRef(node.element);
26
+ }
27
+ const fqn = this.services.likec4.FqnIndex.getFqn(node);
28
+ invariant(fqn, `Not indexed element: ${this.getAstNodePath(node)}`);
29
+ return fqn;
30
+ }
31
+ getAstNodePath(node) {
32
+ return this.services.workspace.AstNodeLocator.getAstNodePath(node);
33
+ }
34
+ getMetadata(metadataAstNode) {
35
+ if (!metadataAstNode || !this.isValid(metadataAstNode)) {
36
+ return void 0;
37
+ }
38
+ return mapToObj(metadataAstNode.props, (p) => [p.key, removeIndent(p.value)]);
39
+ }
40
+ convertTags(withTags) {
41
+ return this.parseTags(withTags);
42
+ }
43
+ parseTags(withTags) {
44
+ let iter = withTags?.tags;
45
+ if (!iter) {
46
+ return null;
47
+ }
48
+ const tags = [];
49
+ while (iter) {
50
+ try {
51
+ if (this.isValid(iter)) {
52
+ const values = iter.values.map((t) => t.ref?.name).filter(isTruthy);
53
+ if (values.length > 0) {
54
+ tags.push(...values);
55
+ }
56
+ }
57
+ } catch (e) {
58
+ }
59
+ iter = iter.prev;
60
+ }
61
+ tags.reverse();
62
+ return isNonEmptyArray(tags) ? tags : null;
63
+ }
64
+ convertLinks(source) {
65
+ return this.parseLinks(source);
66
+ }
67
+ parseLinks(source) {
68
+ if (!source?.props || source.props.length === 0) {
69
+ return void 0;
70
+ }
71
+ return pipe(
72
+ source.props,
73
+ filter(ast.isLinkProperty),
74
+ flatMap((p) => {
75
+ if (!this.isValid(p)) {
76
+ return [];
77
+ }
78
+ const url = p.value;
79
+ if (isTruthy(url)) {
80
+ const title = isTruthy(p.title) ? toSingleLine(p.title) : void 0;
81
+ return title ? { url, title } : { url };
82
+ }
83
+ return [];
84
+ })
85
+ );
86
+ }
87
+ }
@@ -0,0 +1,33 @@
1
+ import type * as c4 from '@likec4/core';
2
+ import { type ParsedAstDeployment, type ParsedAstDeploymentRelation, ast } from '../../ast';
3
+ import type { WithExpressionV2 } from './FqnRefParser';
4
+ export type WithDeploymentModel = ReturnType<typeof DeploymentModelParser>;
5
+ export declare function DeploymentModelParser<TBase extends WithExpressionV2>(B: TBase): {
6
+ new (...args: any[]): {
7
+ parseDeployment(): void;
8
+ parseDeploymentNode(astNode: ast.DeploymentNode): ParsedAstDeployment.Node;
9
+ parseDeployedInstance(astNode: ast.DeployedInstance): ParsedAstDeployment.Instance;
10
+ parseDeploymentRelation(astNode: ast.DeploymentRelation): ParsedAstDeploymentRelation;
11
+ parseFqnRef(astNode: ast.FqnRef): c4.FqnRef;
12
+ parseFqnExpr(astNode: ast.FqnExpr): c4.FqnExpr;
13
+ parseFqnRefExpr(astNode: ast.FqnRefExpr): c4.FqnExpr.NonWildcard;
14
+ parseFqnExpressions(astNode: ast.FqnExpressions): c4.FqnExpr[];
15
+ parseRelationExpr(astNode: ast.RelationExpr): c4.RelationExpr;
16
+ isValid: import("../../validation").IsValidFn;
17
+ readonly services: import("../..").LikeC4Services;
18
+ readonly doc: import("../../ast").ParsedLikeC4LangiumDocument;
19
+ resolveFqn(node: ast.FqnReferenceable): c4.Fqn;
20
+ getAstNodePath(node: c4): any;
21
+ getMetadata(metadataAstNode: ast.MetadataProperty | undefined): {
22
+ [key: string]: string;
23
+ } | undefined;
24
+ convertTags<E extends {
25
+ tags?: ast.Tags;
26
+ }>(withTags?: E | undefined): any;
27
+ parseTags<E extends {
28
+ tags?: ast.Tags;
29
+ }>(withTags?: E): c4.NonEmptyArray<c4.Tag> | null;
30
+ convertLinks(source?: ast.LinkProperty["$container"]): import("../../ast").ParsedLink[] | undefined;
31
+ parseLinks(source?: ast.LinkProperty["$container"]): import("../../ast").ParsedLink[] | undefined;
32
+ };
33
+ } & TBase;
@@ -0,0 +1,162 @@
1
+ import { FqnRef, isNonEmptyArray, nameFromFqn, nonexhaustive, nonNullable } from "@likec4/core";
2
+ import { filter, first, isTruthy, map, mapToObj, pipe } from "remeda";
3
+ import {
4
+ ast,
5
+ streamDeploymentModel,
6
+ toElementStyle,
7
+ toRelationshipStyleExcludeDefaults
8
+ } from "../../ast.js";
9
+ import { logWarnError } from "../../logger.js";
10
+ import { elementRef } from "../../utils/elementRef.js";
11
+ import { stringHash } from "../../utils/stringHash.js";
12
+ import { removeIndent, toSingleLine } from "./Base.js";
13
+ export function DeploymentModelParser(B) {
14
+ return class DeploymentModelParser extends B {
15
+ parseDeployment() {
16
+ const doc = this.doc;
17
+ for (const el of streamDeploymentModel(doc)) {
18
+ try {
19
+ switch (true) {
20
+ case ast.isDeploymentRelation(el): {
21
+ if (this.isValid(el)) {
22
+ doc.c4DeploymentRelations.push(this.parseDeploymentRelation(el));
23
+ }
24
+ break;
25
+ }
26
+ case ast.isDeployedInstance(el):
27
+ doc.c4Deployments.push(this.parseDeployedInstance(el));
28
+ break;
29
+ case ast.isDeploymentNode(el): {
30
+ doc.c4Deployments.push(this.parseDeploymentNode(el));
31
+ break;
32
+ }
33
+ default:
34
+ nonexhaustive(el);
35
+ }
36
+ } catch (e) {
37
+ logWarnError(e);
38
+ }
39
+ }
40
+ }
41
+ parseDeploymentNode(astNode) {
42
+ const isValid = this.isValid;
43
+ const id = this.resolveFqn(astNode);
44
+ const kind = nonNullable(astNode.kind.ref, "DeploymentKind not resolved").name;
45
+ const tags = this.convertTags(astNode.body);
46
+ const stylePropsAst = astNode.body?.props.find(ast.isElementStyleProperty)?.props;
47
+ const style = toElementStyle(stylePropsAst, isValid);
48
+ const metadata = this.getMetadata(astNode.body?.props.find(ast.isMetadataProperty));
49
+ const bodyProps = pipe(
50
+ astNode.body?.props ?? [],
51
+ filter(isValid),
52
+ filter(ast.isElementStringProperty),
53
+ mapToObj((p) => [p.key, p.value || void 0])
54
+ );
55
+ const title = removeIndent(astNode.title ?? bodyProps.title);
56
+ const description = removeIndent(bodyProps.description);
57
+ const technology = toSingleLine(bodyProps.technology);
58
+ const links = this.convertLinks(astNode.body);
59
+ const iconProp = astNode.body?.props.find(ast.isIconProperty);
60
+ if (iconProp && isValid(iconProp)) {
61
+ const value = iconProp.libicon?.ref?.name ?? iconProp.value;
62
+ if (isTruthy(value)) {
63
+ style.icon = value;
64
+ }
65
+ }
66
+ return {
67
+ id,
68
+ kind,
69
+ title: title ?? nameFromFqn(id),
70
+ ...metadata && { metadata },
71
+ ...tags && { tags },
72
+ ...links && isNonEmptyArray(links) && { links },
73
+ ...isTruthy(technology) && { technology },
74
+ ...isTruthy(description) && { description },
75
+ style
76
+ };
77
+ }
78
+ parseDeployedInstance(astNode) {
79
+ const isValid = this.isValid;
80
+ const id = this.resolveFqn(astNode);
81
+ const element = this.resolveFqn(nonNullable(elementRef(astNode.element), "DeployedInstance element not found"));
82
+ const tags = this.convertTags(astNode.body);
83
+ const stylePropsAst = astNode.body?.props.find(ast.isElementStyleProperty)?.props;
84
+ const style = toElementStyle(stylePropsAst, isValid);
85
+ const metadata = this.getMetadata(astNode.body?.props.find(ast.isMetadataProperty));
86
+ const bodyProps = pipe(
87
+ astNode.body?.props ?? [],
88
+ filter(isValid),
89
+ filter(ast.isElementStringProperty),
90
+ mapToObj((p) => [p.key, p.value || void 0])
91
+ );
92
+ const title = removeIndent(astNode.title ?? bodyProps.title);
93
+ const description = removeIndent(bodyProps.description);
94
+ const technology = toSingleLine(bodyProps.technology);
95
+ const links = this.convertLinks(astNode.body);
96
+ const iconProp = astNode.body?.props.find(ast.isIconProperty);
97
+ if (iconProp && isValid(iconProp)) {
98
+ const value = iconProp.libicon?.ref?.name ?? iconProp.value;
99
+ if (isTruthy(value)) {
100
+ style.icon = value;
101
+ }
102
+ }
103
+ return {
104
+ id,
105
+ element,
106
+ ...metadata && { metadata },
107
+ ...title && { title },
108
+ ...tags && { tags },
109
+ ...links && isNonEmptyArray(links) && { links },
110
+ ...isTruthy(technology) && { technology },
111
+ ...isTruthy(description) && { description },
112
+ style
113
+ };
114
+ }
115
+ parseDeploymentRelation(astNode) {
116
+ const isValid = this.isValid;
117
+ const astPath = this.getAstNodePath(astNode);
118
+ const source = FqnRef.toDeploymentRef(this.parseFqnRef(astNode.source));
119
+ const target = FqnRef.toDeploymentRef(this.parseFqnRef(astNode.target));
120
+ const tags = this.convertTags(astNode) ?? this.convertTags(astNode.body);
121
+ const links = this.convertLinks(astNode.body);
122
+ const kind = astNode.kind?.ref?.name;
123
+ const metadata = this.getMetadata(astNode.body?.props.find(ast.isMetadataProperty));
124
+ const bodyProps = mapToObj(
125
+ astNode.body?.props.filter(ast.isRelationStringProperty) ?? [],
126
+ (p) => [p.key, p.value]
127
+ );
128
+ const navigateTo = pipe(
129
+ astNode.body?.props ?? [],
130
+ filter(ast.isRelationNavigateToProperty),
131
+ map((p) => p.value.view.ref?.name),
132
+ filter(isTruthy),
133
+ first()
134
+ );
135
+ const title = removeIndent(astNode.title ?? bodyProps.title);
136
+ const description = removeIndent(bodyProps.description);
137
+ const technology = toSingleLine(astNode.technology) ?? removeIndent(bodyProps.technology);
138
+ const styleProp = astNode.body?.props.find(ast.isRelationStyleProperty);
139
+ const id = stringHash(
140
+ "deployment",
141
+ astPath,
142
+ source.id,
143
+ target.id
144
+ );
145
+ return {
146
+ id,
147
+ source,
148
+ target,
149
+ ...title && { title },
150
+ ...metadata && { metadata },
151
+ ...isTruthy(technology) && { technology },
152
+ ...isTruthy(description) && { description },
153
+ ...kind && { kind },
154
+ ...tags && { tags },
155
+ ...isNonEmptyArray(links) && { links },
156
+ ...toRelationshipStyleExcludeDefaults(styleProp?.props, isValid),
157
+ ...navigateTo && { navigateTo },
158
+ astPath
159
+ };
160
+ }
161
+ };
162
+ }
@@ -0,0 +1,38 @@
1
+ import type * as c4 from '@likec4/core';
2
+ import { ast, type ParsedAstDeploymentView } from '../../ast';
3
+ import type { WithDeploymentModel } from './DeploymentModelParser';
4
+ import type { WithExpressionV2 } from './FqnRefParser';
5
+ export type WithDeploymentView = ReturnType<typeof DeploymentViewParser>;
6
+ export declare function DeploymentViewParser<TBase extends WithExpressionV2 & WithDeploymentModel>(B: TBase): {
7
+ new (...args: any[]): {
8
+ parseDeploymentView(astNode: ast.DeploymentView): ParsedAstDeploymentView;
9
+ parseDeploymentViewRule(astRule: ast.DeploymentViewRule): c4.DeploymentViewRule;
10
+ parseDeploymentViewRulePredicate(astRule: ast.DeploymentViewRulePredicate): c4.DeploymentViewRulePredicate;
11
+ parseDeploymentViewRuleStyle(astRule: ast.DeploymentViewRuleStyle): c4.DeploymentViewRuleStyle;
12
+ parseFqnRef(astNode: ast.FqnRef): c4.FqnRef;
13
+ parseFqnExpr(astNode: ast.FqnExpr): c4.FqnExpr;
14
+ parseFqnRefExpr(astNode: ast.FqnRefExpr): c4.FqnExpr.NonWildcard;
15
+ parseFqnExpressions(astNode: ast.FqnExpressions): c4.FqnExpr[];
16
+ parseRelationExpr(astNode: ast.RelationExpr): c4.RelationExpr;
17
+ isValid: import("../../validation").IsValidFn;
18
+ readonly services: import("../..").LikeC4Services;
19
+ readonly doc: import("../../ast").ParsedLikeC4LangiumDocument;
20
+ resolveFqn(node: ast.FqnReferenceable): c4.Fqn;
21
+ getAstNodePath(node: c4): any;
22
+ getMetadata(metadataAstNode: ast.MetadataProperty | undefined): {
23
+ [key: string]: string;
24
+ } | undefined;
25
+ convertTags<E extends {
26
+ tags?: ast.Tags;
27
+ }>(withTags?: E | undefined): any;
28
+ parseTags<E extends {
29
+ tags?: ast.Tags;
30
+ }>(withTags?: E): c4.NonEmptyArray<c4.Tag> | null;
31
+ convertLinks(source?: ast.LinkProperty["$container"]): import("../../ast").ParsedLink[] | undefined;
32
+ parseLinks(source?: ast.LinkProperty["$container"]): import("../../ast").ParsedLink[] | undefined;
33
+ parseDeployment(): void;
34
+ parseDeploymentNode(astNode: ast.DeploymentNode): import("../../ast").ParsedAstDeployment.Node;
35
+ parseDeployedInstance(astNode: ast.DeployedInstance): import("../../ast").ParsedAstDeployment.Instance;
36
+ parseDeploymentRelation(astNode: ast.DeploymentRelation): import("../../ast").ParsedAstDeploymentRelation;
37
+ };
38
+ } & TBase;
@@ -0,0 +1,98 @@
1
+ import { invariant, isNonEmptyArray, nonexhaustive } from "@likec4/core";
2
+ import { isNonNullish } from "remeda";
3
+ import { ast, toAutoLayout, toElementStyle, ViewOps } from "../../ast.js";
4
+ import { logWarnError } from "../../logger.js";
5
+ import { stringHash } from "../../utils/index.js";
6
+ import { parseViewManualLayout } from "../../view-utils/manual-layout.js";
7
+ import { removeIndent, toSingleLine } from "./Base.js";
8
+ export function DeploymentViewParser(B) {
9
+ return class DeploymentViewParser extends B {
10
+ parseDeploymentView(astNode) {
11
+ const body = astNode.body;
12
+ invariant(body, "DynamicElementView body is not defined");
13
+ const props = body.props.filter(this.isValid);
14
+ const astPath = this.getAstNodePath(astNode);
15
+ let id = astNode.name;
16
+ if (!id) {
17
+ id = "deployment_" + stringHash(
18
+ this.doc.uri.toString(),
19
+ astPath
20
+ );
21
+ }
22
+ const title = toSingleLine(props.find((p) => p.key === "title")?.value) ?? null;
23
+ const description = removeIndent(props.find((p) => p.key === "description")?.value) ?? null;
24
+ const tags = this.convertTags(body);
25
+ const links = this.convertLinks(body);
26
+ ViewOps.writeId(astNode, id);
27
+ const manualLayout = parseViewManualLayout(astNode);
28
+ return {
29
+ __: "deployment",
30
+ id,
31
+ astPath,
32
+ title,
33
+ description,
34
+ tags,
35
+ links: isNonEmptyArray(links) ? links : null,
36
+ rules: body.rules.flatMap((n) => {
37
+ try {
38
+ return this.isValid(n) ? this.parseDeploymentViewRule(n) : [];
39
+ } catch (e) {
40
+ logWarnError(e);
41
+ return [];
42
+ }
43
+ }),
44
+ ...manualLayout && { manualLayout }
45
+ };
46
+ }
47
+ parseDeploymentViewRule(astRule) {
48
+ if (ast.isDeploymentViewRulePredicate(astRule)) {
49
+ return this.parseDeploymentViewRulePredicate(astRule);
50
+ }
51
+ if (ast.isViewRuleAutoLayout(astRule)) {
52
+ return toAutoLayout(astRule);
53
+ }
54
+ if (ast.isDeploymentViewRuleStyle(astRule)) {
55
+ return this.parseDeploymentViewRuleStyle(astRule);
56
+ }
57
+ nonexhaustive(astRule);
58
+ }
59
+ parseDeploymentViewRulePredicate(astRule) {
60
+ const exprs = [];
61
+ let iterator = astRule.expr;
62
+ while (iterator) {
63
+ try {
64
+ const expr = iterator.value;
65
+ if (isNonNullish(expr) && this.isValid(expr)) {
66
+ switch (true) {
67
+ case ast.isFqnExpr(expr):
68
+ exprs.unshift(this.parseFqnExpr(expr));
69
+ break;
70
+ case ast.isRelationExpr(expr):
71
+ exprs.unshift(this.parseRelationExpr(expr));
72
+ break;
73
+ default:
74
+ nonexhaustive(expr);
75
+ }
76
+ }
77
+ } catch (e) {
78
+ logWarnError(e);
79
+ }
80
+ iterator = iterator.prev;
81
+ }
82
+ return astRule.isInclude ? { include: exprs } : { exclude: exprs };
83
+ }
84
+ parseDeploymentViewRuleStyle(astRule) {
85
+ const styleProps = astRule.props.filter(ast.isStyleProperty);
86
+ const notationProperty = astRule.props.find(ast.isNotationProperty);
87
+ const notation = removeIndent(notationProperty?.value);
88
+ const targets = this.parseFqnExpressions(astRule.targets);
89
+ return {
90
+ targets,
91
+ ...notation && { notation },
92
+ style: {
93
+ ...toElementStyle(styleProps, this.isValid)
94
+ }
95
+ };
96
+ }
97
+ };
98
+ }
@@ -0,0 +1,29 @@
1
+ import type * as c4 from '@likec4/core';
2
+ import { ast } from '../../ast';
3
+ import type { Base } from './Base';
4
+ export type WithExpressionV2 = ReturnType<typeof ExpressionV2Parser>;
5
+ export declare function ExpressionV2Parser<TBase extends Base>(B: TBase): {
6
+ new (...args: any[]): {
7
+ parseFqnRef(astNode: ast.FqnRef): c4.FqnRef;
8
+ parseFqnExpr(astNode: ast.FqnExpr): c4.FqnExpr;
9
+ parseFqnRefExpr(astNode: ast.FqnRefExpr): c4.FqnExpr.NonWildcard;
10
+ parseFqnExpressions(astNode: ast.FqnExpressions): c4.FqnExpr[];
11
+ parseRelationExpr(astNode: ast.RelationExpr): c4.RelationExpr;
12
+ isValid: import("../../validation").IsValidFn;
13
+ readonly services: import("../..").LikeC4Services;
14
+ readonly doc: import("../../ast").ParsedLikeC4LangiumDocument;
15
+ resolveFqn(node: ast.FqnReferenceable): c4.Fqn;
16
+ getAstNodePath(node: c4): any;
17
+ getMetadata(metadataAstNode: ast.MetadataProperty | undefined): {
18
+ [key: string]: string;
19
+ } | undefined;
20
+ convertTags<E extends {
21
+ tags?: ast.Tags;
22
+ }>(withTags?: E | undefined): any;
23
+ parseTags<E extends {
24
+ tags?: ast.Tags;
25
+ }>(withTags?: E): c4.NonEmptyArray<c4.Tag> | null;
26
+ convertLinks(source?: ast.LinkProperty["$container"]): import("../../ast").ParsedLink[] | undefined;
27
+ parseLinks(source?: ast.LinkProperty["$container"]): import("../../ast").ParsedLink[] | undefined;
28
+ };
29
+ } & TBase;
@@ -0,0 +1,108 @@
1
+ import { nonexhaustive, nonNullable } from "@likec4/core";
2
+ import { isNonNullish } from "remeda";
3
+ import { ast } from "../../ast.js";
4
+ import { logWarnError } from "../../logger.js";
5
+ import { instanceRef } from "../../utils/fqnRef.js";
6
+ export function ExpressionV2Parser(B) {
7
+ return class ExpressionV2Parser extends B {
8
+ parseFqnRef(astNode) {
9
+ const refValue = nonNullable(
10
+ astNode.value.ref,
11
+ `FqnRef is empty ${astNode.$cstNode?.range.start.line}:${astNode.$cstNode?.range.start.character}`
12
+ );
13
+ if (ast.isElement(refValue)) {
14
+ const deployedInstanceAst = instanceRef(astNode);
15
+ if (!deployedInstanceAst) {
16
+ return {
17
+ model: this.resolveFqn(refValue)
18
+ };
19
+ }
20
+ const deployment = this.resolveFqn(deployedInstanceAst);
21
+ const element = this.resolveFqn(refValue);
22
+ return {
23
+ deployment,
24
+ element
25
+ };
26
+ }
27
+ if (ast.isDeploymentElement(refValue)) {
28
+ return {
29
+ deployment: this.resolveFqn(refValue)
30
+ };
31
+ }
32
+ nonexhaustive(refValue);
33
+ }
34
+ parseFqnExpr(astNode) {
35
+ if (ast.isWildcardExpression(astNode)) {
36
+ return {
37
+ wildcard: true
38
+ };
39
+ }
40
+ if (ast.isFqnRefExpr(astNode)) {
41
+ return this.parseFqnRefExpr(astNode);
42
+ }
43
+ nonexhaustive(astNode);
44
+ }
45
+ parseFqnRefExpr(astNode) {
46
+ const ref = this.parseFqnRef(astNode.ref);
47
+ switch (true) {
48
+ case astNode.selector === "._":
49
+ return {
50
+ ref,
51
+ selector: "expanded"
52
+ };
53
+ case astNode.selector === ".**":
54
+ return {
55
+ ref,
56
+ selector: "descendants"
57
+ };
58
+ case astNode.selector === ".*":
59
+ return {
60
+ ref,
61
+ selector: "children"
62
+ };
63
+ default:
64
+ return { ref };
65
+ }
66
+ }
67
+ parseFqnExpressions(astNode) {
68
+ const exprs = [];
69
+ let iter = astNode;
70
+ while (iter) {
71
+ try {
72
+ if (isNonNullish(iter.value) && this.isValid(iter.value)) {
73
+ exprs.push(this.parseFqnExpr(iter.value));
74
+ }
75
+ } catch (e) {
76
+ logWarnError(e);
77
+ }
78
+ iter = iter.prev;
79
+ }
80
+ return exprs.reverse();
81
+ }
82
+ parseRelationExpr(astNode) {
83
+ if (ast.isDirectedRelationExpr(astNode)) {
84
+ return {
85
+ source: this.parseFqnExpr(astNode.source.from),
86
+ target: this.parseFqnExpr(astNode.target),
87
+ isBidirectional: astNode.source.isBidirectional
88
+ };
89
+ }
90
+ if (ast.isInOutRelationExpr(astNode)) {
91
+ return {
92
+ inout: this.parseFqnExpr(astNode.inout.to)
93
+ };
94
+ }
95
+ if (ast.isOutgoingRelationExpr(astNode)) {
96
+ return {
97
+ outgoing: this.parseFqnExpr(astNode.from)
98
+ };
99
+ }
100
+ if (ast.isIncomingRelationExpr(astNode)) {
101
+ return {
102
+ incoming: this.parseFqnExpr(astNode.to)
103
+ };
104
+ }
105
+ nonexhaustive(astNode);
106
+ }
107
+ };
108
+ }
@@ -0,0 +1,66 @@
1
+ import type * as c4 from '@likec4/core';
2
+ import { ast, type ParsedAstGlobals } from '../../ast';
3
+ import type { WithViewsParser } from './ViewsParser';
4
+ export declare function GlobalsParser<TBase extends WithViewsParser>(B: TBase): {
5
+ new (...args: any[]): {
6
+ parseGlobals(): void;
7
+ parseAndStoreGlobalPredicateGroupOrDynamic(astRule: ast.GlobalPredicateGroup | ast.GlobalDynamicPredicateGroup, id: c4.GlobalPredicateId, c4Globals: ParsedAstGlobals): void;
8
+ parseGlobalPredicateGroup(astRule: ast.GlobalPredicateGroup): c4.ViewRulePredicate[];
9
+ parseGlobalDynamicPredicateGroup(astRule: ast.GlobalDynamicPredicateGroup): c4.DynamicViewIncludeRule[];
10
+ parseGlobalStyleOrGroup(astRule: ast.GlobalStyle | ast.GlobalStyleGroup): c4.ViewRuleStyle[];
11
+ parseViews(): void;
12
+ parseElementView(astNode: ast.ElementView, additionalStyles: c4.ViewRuleStyleOrGlobalRef[]): import("../../ast").ParsedAstElementView;
13
+ parseViewRule(astRule: ast.ViewRule): c4.ViewRule;
14
+ parseViewRulePredicate(astNode: ast.ViewRulePredicate): c4.ViewRulePredicate;
15
+ parseViewRuleGlobalPredicateRef(astRule: ast.ViewRuleGlobalPredicateRef | ast.DynamicViewGlobalPredicateRef): c4.ViewRuleGlobalPredicateRef;
16
+ parseViewRuleStyleOrGlobalRef(astRule: ast.ViewRuleStyleOrGlobalRef): c4.ViewRuleStyleOrGlobalRef;
17
+ parseViewRuleGroup(astNode: ast.ViewRuleGroup): c4.ViewRuleGroup;
18
+ parseViewRuleStyle(astRule: ast.ViewRuleStyle | ast.GlobalStyle): c4.ViewRuleStyle;
19
+ parseRuleStyle(styleProperties: ast.StyleProperty[], elementExpressionsIterator: ast.ElementExpressionsIterator, notationProperty?: ast.NotationProperty): c4.ViewRuleStyle;
20
+ parseViewRuleGlobalStyle(astRule: ast.ViewRuleGlobalStyle): c4.ViewRuleGlobalStyle;
21
+ parseDynamicElementView(astNode: ast.DynamicView, additionalStyles: c4.ViewRuleStyleOrGlobalRef[]): import("../../ast").ParsedAstDynamicView;
22
+ parseDynamicViewRule(astRule: ast.DynamicViewRule): c4.DynamicViewRule;
23
+ parseDynamicViewIncludePredicate(astRule: ast.DynamicViewIncludePredicate): c4.DynamicViewIncludeRule;
24
+ parseDynamicParallelSteps(node: ast.DynamicViewParallelSteps): c4.DynamicViewParallelSteps;
25
+ parseDynamicStep(node: ast.DynamicViewStep): c4.DynamicViewStep;
26
+ parsePredicate(astNode: ast.Predicate): c4.Expression;
27
+ parseElementPredicate(astNode: ast.ElementPredicate): c4.ElementPredicateExpression;
28
+ parseElementExpressionsIterator(astNode: ast.ElementExpressionsIterator): c4.ElementExpression[];
29
+ parseElementExpression(astNode: ast.ElementExpression): c4.ElementExpression;
30
+ parseElementPredicateWhere(astNode: ast.ElementPredicateWhere): c4.ElementWhereExpr;
31
+ parseElementPredicateWith(astNode: ast.ElementPredicateWith): c4.CustomElementExpr;
32
+ parseRelationPredicate(astNode: ast.RelationPredicate): c4.RelationPredicateExpression;
33
+ parseRelationPredicateWhere(astNode: ast.RelationPredicateWhere): c4.RelationWhereExpr;
34
+ parseRelationPredicateWith(astNode: ast.RelationPredicateWith, relation: c4.RelationExpression | c4.RelationWhereExpr): c4.CustomRelationExpr;
35
+ parseRelationExpression(astNode: ast.RelationExpression): c4.RelationExpression;
36
+ isValid: import("../../validation").IsValidFn;
37
+ readonly services: import("../..").LikeC4Services;
38
+ readonly doc: import("../../ast").ParsedLikeC4LangiumDocument;
39
+ resolveFqn(node: ast.FqnReferenceable): c4.Fqn;
40
+ getAstNodePath(node: c4): any;
41
+ getMetadata(metadataAstNode: ast.MetadataProperty | undefined): {
42
+ [key: string]: string;
43
+ } | undefined;
44
+ convertTags<E extends {
45
+ tags?: ast.Tags;
46
+ }>(withTags?: E | undefined): any;
47
+ parseTags<E extends {
48
+ tags?: ast.Tags;
49
+ }>(withTags?: E): c4.NonEmptyArray<c4.Tag> | null;
50
+ convertLinks(source?: ast.LinkProperty["$container"]): import("../../ast").ParsedLink[] | undefined;
51
+ parseLinks(source?: ast.LinkProperty["$container"]): import("../../ast").ParsedLink[] | undefined;
52
+ parseDeploymentView(astNode: ast.DeploymentView): import("../../ast").ParsedAstDeploymentView;
53
+ parseDeploymentViewRule(astRule: ast.DeploymentViewRule): c4.DeploymentViewRule;
54
+ parseDeploymentViewRulePredicate(astRule: ast.DeploymentViewRulePredicate): c4.DeploymentViewRulePredicate;
55
+ parseDeploymentViewRuleStyle(astRule: ast.DeploymentViewRuleStyle): c4.DeploymentViewRuleStyle;
56
+ parseFqnRef(astNode: ast.FqnRef): c4.FqnRef;
57
+ parseFqnExpr(astNode: ast.FqnExpr): c4.FqnExpr;
58
+ parseFqnRefExpr(astNode: ast.FqnRefExpr): c4.FqnExpr.NonWildcard;
59
+ parseFqnExpressions(astNode: ast.FqnExpressions): c4.FqnExpr[];
60
+ parseRelationExpr(astNode: ast.RelationExpr): c4.RelationExpr;
61
+ parseDeployment(): void;
62
+ parseDeploymentNode(astNode: ast.DeploymentNode): import("../../ast").ParsedAstDeployment.Node;
63
+ parseDeployedInstance(astNode: ast.DeployedInstance): import("../../ast").ParsedAstDeployment.Instance;
64
+ parseDeploymentRelation(astNode: ast.DeploymentRelation): import("../../ast").ParsedAstDeploymentRelation;
65
+ };
66
+ } & TBase;