@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,13 @@
1
+ import { type FileSystemNode, URI } from 'langium';
2
+ import { NodeFileSystemProvider } from 'langium/node';
3
+ export declare const LikeC4FileSystem: {
4
+ fileSystemProvider: () => SymLinkTraversingFileSystemProvider;
5
+ };
6
+ /**
7
+ * A file system provider that follows symbolic links.
8
+ * @see https://github.com/likec4/likec4/pull/1213
9
+ */
10
+ declare class SymLinkTraversingFileSystemProvider extends NodeFileSystemProvider {
11
+ readDirectory(folderPath: URI): Promise<FileSystemNode[]>;
12
+ }
13
+ export {};
@@ -0,0 +1,27 @@
1
+ import { fdir } from "fdir";
2
+ import { URI } from "langium";
3
+ import { NodeFileSystemProvider } from "langium/node";
4
+ import { stat } from "node:fs/promises";
5
+ import { logger } from "./logger.js";
6
+ export const LikeC4FileSystem = {
7
+ fileSystemProvider: () => new SymLinkTraversingFileSystemProvider()
8
+ };
9
+ class SymLinkTraversingFileSystemProvider extends NodeFileSystemProvider {
10
+ async readDirectory(folderPath) {
11
+ const crawled = await new fdir().withSymlinks().withFullPaths().crawl(folderPath.fsPath).withPromise();
12
+ const entries = [];
13
+ for (const path of crawled) {
14
+ try {
15
+ const stats = await stat(path);
16
+ entries.push({
17
+ isFile: stats.isFile(),
18
+ isDirectory: stats.isDirectory(),
19
+ uri: URI.file(path)
20
+ });
21
+ } catch (error) {
22
+ logger.error(error);
23
+ }
24
+ }
25
+ return entries;
26
+ }
27
+ }
package/dist/Rpc.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import type { LikeC4Services } from './module';
2
+ import { Disposable } from 'langium';
3
+ export declare class Rpc implements Disposable {
4
+ private services;
5
+ private disposables;
6
+ constructor(services: LikeC4Services);
7
+ init(): void;
8
+ dispose(): void;
9
+ }
package/dist/Rpc.js ADDED
@@ -0,0 +1,126 @@
1
+ import { debounce } from "remeda";
2
+ import { logError, logger } from "./logger.js";
3
+ import { nonexhaustive } from "@likec4/core";
4
+ import { Disposable, interruptAndCheck, URI, UriUtils } from "langium";
5
+ import { isLikeC4LangiumDocument } from "./ast.js";
6
+ import { Scheme } from "./likec4lib.js";
7
+ import {
8
+ buildDocuments,
9
+ changeView,
10
+ computeView,
11
+ fetchComputedModel,
12
+ fetchModel,
13
+ locate,
14
+ onDidChangeModel
15
+ } from "./protocol.js";
16
+ export class Rpc {
17
+ constructor(services) {
18
+ this.services = services;
19
+ }
20
+ disposables = [];
21
+ init() {
22
+ const modelBuilder = this.services.likec4.ModelBuilder;
23
+ const modelLocator = this.services.likec4.ModelLocator;
24
+ const modelEditor = this.services.likec4.ModelChanges;
25
+ const connection = this.services.shared.lsp.Connection;
26
+ if (!connection) {
27
+ logger.info(`[ServerRpc] no connection, not initializing`);
28
+ return;
29
+ }
30
+ logger.info(`[ServerRpc] init`);
31
+ const LangiumDocuments = this.services.shared.workspace.LangiumDocuments;
32
+ const DocumentBuilder = this.services.shared.workspace.DocumentBuilder;
33
+ const notifyModelParsed = debounce(
34
+ () => {
35
+ connection.sendNotification(onDidChangeModel, "").catch((e) => {
36
+ logger.error(`[ServerRpc] error sending onDidChangeModel: ${e}`);
37
+ return Promise.resolve();
38
+ });
39
+ },
40
+ {
41
+ timing: "trailing",
42
+ waitMs: 300,
43
+ maxWaitMs: 1e3
44
+ }
45
+ );
46
+ let isFirstBuild = true;
47
+ this.disposables.push(
48
+ Disposable.create(() => {
49
+ notifyModelParsed.cancel();
50
+ }),
51
+ modelBuilder.onModelParsed(() => notifyModelParsed.call()),
52
+ connection.onRequest(fetchComputedModel, async ({ cleanCaches }, cancelToken) => {
53
+ if (cleanCaches) {
54
+ this.services.WorkspaceCache.clear();
55
+ }
56
+ const model = await modelBuilder.buildComputedModel(cancelToken);
57
+ return { model };
58
+ }),
59
+ connection.onRequest(fetchModel, async (cancelToken) => {
60
+ const model = await modelBuilder.buildModel(cancelToken);
61
+ return { model };
62
+ }),
63
+ connection.onRequest(computeView, async ({ viewId }, cancelToken) => {
64
+ const view = await modelBuilder.computeView(viewId, cancelToken);
65
+ return { view };
66
+ }),
67
+ connection.onRequest(buildDocuments, async ({ docs }, cancelToken) => {
68
+ const changed = docs.map((d) => URI.parse(d));
69
+ const notChanged = (uri) => changed.every((c) => !UriUtils.equals(c, uri));
70
+ const deleted = LangiumDocuments.all.filter((d) => isLikeC4LangiumDocument(d) && notChanged(d.uri) && d.uri.scheme !== Scheme).map((d) => d.uri).toArray();
71
+ logger.debug(
72
+ `[ServerRpc] received request to build:
73
+ changed (total ${changed.length}):${docs.map((d) => "\n - " + d).join("")}
74
+ deleted (total ${deleted.length}):${deleted.map((d) => "\n - " + d.toString()).join("\n")}`
75
+ );
76
+ if (!isFirstBuild && changed.length + deleted.length > 0) {
77
+ await Promise.allSettled(
78
+ [...changed, ...deleted].map(async (d) => {
79
+ const uri = d.toString();
80
+ logger.debug(`clear diagnostics for ${uri}`);
81
+ try {
82
+ await connection.sendDiagnostics({
83
+ uri,
84
+ diagnostics: []
85
+ });
86
+ } catch (e) {
87
+ logger.warn(`error clearing diagnostics for ${uri}: ${e}`);
88
+ }
89
+ })
90
+ );
91
+ await interruptAndCheck(cancelToken);
92
+ }
93
+ isFirstBuild = false;
94
+ await DocumentBuilder.update(changed, deleted, cancelToken);
95
+ }),
96
+ connection.onRequest(locate, (params) => {
97
+ if ("element" in params) {
98
+ return modelLocator.locateElement(params.element, params.property ?? "name");
99
+ }
100
+ if ("relation" in params) {
101
+ return modelLocator.locateRelation(params.relation);
102
+ }
103
+ if ("view" in params) {
104
+ return modelLocator.locateView(params.view);
105
+ }
106
+ if ("deployment" in params) {
107
+ return modelLocator.locateDeploymentElement(params.deployment, params.property ?? "name");
108
+ }
109
+ nonexhaustive(params);
110
+ }),
111
+ connection.onRequest(changeView, async (request, _cancelToken) => {
112
+ return await modelEditor.applyChange(request);
113
+ })
114
+ );
115
+ }
116
+ dispose() {
117
+ let item;
118
+ while (item = this.disposables.pop()) {
119
+ try {
120
+ item.dispose();
121
+ } catch (e) {
122
+ logError(e);
123
+ }
124
+ }
125
+ }
126
+ }
package/dist/ast.d.ts ADDED
@@ -0,0 +1,200 @@
1
+ import type * as c4 from '@likec4/core';
2
+ import type { AstNode, AstNodeDescription, DiagnosticInfo, LangiumDocument, MultiMap } from 'langium';
3
+ import type { ConditionalPick, SetRequired, ValueOf, Writable } from 'type-fest';
4
+ import type { Diagnostic } from 'vscode-languageserver-types';
5
+ import type { LikeC4Grammar } from './generated/ast';
6
+ import * as ast from './generated/ast';
7
+ import type { IsValidFn } from './validation';
8
+ export { ast };
9
+ declare const idattr: unique symbol;
10
+ declare module './generated/ast' {
11
+ interface Element {
12
+ [idattr]?: c4.Fqn | undefined;
13
+ }
14
+ interface ElementView {
15
+ [idattr]?: c4.ViewId | undefined;
16
+ }
17
+ interface DynamicView {
18
+ [idattr]?: c4.ViewId | undefined;
19
+ }
20
+ interface DeploymentView {
21
+ [idattr]?: c4.ViewId | undefined;
22
+ }
23
+ interface DeploymentNode {
24
+ [idattr]?: c4.Fqn | undefined;
25
+ }
26
+ interface DeployedInstance {
27
+ [idattr]?: c4.Fqn | undefined;
28
+ }
29
+ }
30
+ type ParsedElementStyle = {
31
+ shape?: c4.ElementShape;
32
+ icon?: c4.IconUrl;
33
+ color?: c4.Color;
34
+ border?: c4.BorderStyle;
35
+ opacity?: number;
36
+ };
37
+ export interface ParsedAstSpecification {
38
+ tags: Set<c4.Tag>;
39
+ elements: Record<c4.ElementKind, {
40
+ technology?: string;
41
+ notation?: string;
42
+ style: ParsedElementStyle;
43
+ }>;
44
+ relationships: Record<c4.RelationshipKind, {
45
+ technology?: string;
46
+ notation?: string;
47
+ color?: c4.Color;
48
+ line?: c4.RelationshipLineType;
49
+ head?: c4.RelationshipArrowType;
50
+ tail?: c4.RelationshipArrowType;
51
+ }>;
52
+ colors: Record<c4.CustomColor, {
53
+ color: c4.HexColorLiteral;
54
+ }>;
55
+ deployments: Record<c4.DeploymentNodeKind, c4.DeploymentNodeKindSpecification>;
56
+ }
57
+ export interface ParsedAstElement {
58
+ id: c4.Fqn;
59
+ astPath: string;
60
+ kind: c4.ElementKind;
61
+ title: string;
62
+ description?: string;
63
+ technology?: string;
64
+ tags?: c4.NonEmptyArray<c4.Tag>;
65
+ links?: c4.NonEmptyArray<ParsedLink>;
66
+ style: ParsedElementStyle;
67
+ metadata?: {
68
+ [key: string]: string;
69
+ };
70
+ }
71
+ export interface ParsedAstRelation {
72
+ id: c4.RelationId;
73
+ astPath: string;
74
+ source: c4.Fqn;
75
+ target: c4.Fqn;
76
+ kind?: c4.RelationshipKind;
77
+ tags?: c4.NonEmptyArray<c4.Tag>;
78
+ title: string;
79
+ description?: string;
80
+ technology?: string;
81
+ color?: c4.Color;
82
+ line?: c4.RelationshipLineType;
83
+ head?: c4.RelationshipArrowType;
84
+ tail?: c4.RelationshipArrowType;
85
+ links?: c4.NonEmptyArray<ParsedLink>;
86
+ navigateTo?: c4.ViewId;
87
+ metadata?: {
88
+ [key: string]: string;
89
+ };
90
+ }
91
+ export type ParsedAstDeployment = c4.DeploymentElement;
92
+ export declare namespace ParsedAstDeployment {
93
+ type Node = c4.DeploymentNode;
94
+ type Instance = c4.DeployedInstance;
95
+ }
96
+ export type ParsedAstDeploymentRelation = c4.DeploymentRelation & {
97
+ astPath: string;
98
+ };
99
+ export type ParsedAstGlobals = Writable<c4.ModelGlobals>;
100
+ export interface ParsedAstElementView {
101
+ __: 'element';
102
+ id: c4.ViewId;
103
+ viewOf?: c4.Fqn;
104
+ extends?: c4.ViewId;
105
+ astPath: string;
106
+ title: string | null;
107
+ description: string | null;
108
+ tags: c4.NonEmptyArray<c4.Tag> | null;
109
+ links: c4.NonEmptyArray<ParsedLink> | null;
110
+ rules: c4.ViewRule[];
111
+ manualLayout?: c4.ViewManualLayout;
112
+ }
113
+ export interface ParsedAstDynamicView {
114
+ __: 'dynamic';
115
+ id: c4.ViewId;
116
+ astPath: string;
117
+ title: string | null;
118
+ description: string | null;
119
+ tags: c4.NonEmptyArray<c4.Tag> | null;
120
+ links: c4.NonEmptyArray<ParsedLink> | null;
121
+ steps: c4.DynamicViewStepOrParallel[];
122
+ rules: Array<c4.DynamicViewRule>;
123
+ manualLayout?: c4.ViewManualLayout;
124
+ }
125
+ export interface ParsedAstDeploymentView {
126
+ __: 'deployment';
127
+ id: c4.ViewId;
128
+ astPath: string;
129
+ title: string | null;
130
+ description: string | null;
131
+ tags: c4.NonEmptyArray<c4.Tag> | null;
132
+ links: c4.NonEmptyArray<ParsedLink> | null;
133
+ rules: Array<c4.DeploymentViewRule>;
134
+ }
135
+ export type ParsedAstView = ParsedAstElementView | ParsedAstDynamicView | ParsedAstDeploymentView;
136
+ export declare const ViewOps: {
137
+ writeId<T extends ast.LikeC4View>(node: T, id: c4.ViewId): T;
138
+ readId(node: ast.LikeC4View): c4.ViewId | undefined;
139
+ };
140
+ export interface ParsedLink {
141
+ title?: string;
142
+ url: string;
143
+ }
144
+ export declare const ElementOps: {
145
+ writeId(node: ast.Element | ast.DeploymentElement, id: c4.Fqn | null): ast.DeploymentElement | ast.Element;
146
+ readId(node: ast.Element | ast.DeploymentElement): any;
147
+ };
148
+ export interface DocFqnIndexAstNodeDescription extends AstNodeDescription {
149
+ fqn: c4.Fqn;
150
+ }
151
+ export interface DeploymentAstNodeDescription extends AstNodeDescription {
152
+ fqn: string;
153
+ }
154
+ export type LikeC4AstNode = ValueOf<ConditionalPick<ast.LikeC4AstType, AstNode>>;
155
+ type LikeC4DocumentDiagnostic = Diagnostic & DiagnosticInfo<LikeC4AstNode>;
156
+ export interface LikeC4DocumentProps {
157
+ diagnostics?: Array<LikeC4DocumentDiagnostic>;
158
+ c4Specification?: ParsedAstSpecification;
159
+ c4Elements?: ParsedAstElement[];
160
+ c4Relations?: ParsedAstRelation[];
161
+ c4Globals?: ParsedAstGlobals;
162
+ c4Views?: ParsedAstView[];
163
+ c4Deployments?: ParsedAstDeployment[];
164
+ c4DeploymentRelations?: ParsedAstDeploymentRelation[];
165
+ c4fqnIndex?: MultiMap<c4.Fqn, DocFqnIndexAstNodeDescription>;
166
+ }
167
+ type LikeC4GrammarDocument = Omit<LangiumDocument<LikeC4Grammar>, 'diagnostics'>;
168
+ export interface LikeC4LangiumDocument extends LikeC4GrammarDocument, LikeC4DocumentProps {
169
+ }
170
+ export interface FqnIndexedDocument extends SetRequired<LikeC4LangiumDocument, 'c4fqnIndex'> {
171
+ }
172
+ export interface ParsedLikeC4LangiumDocument extends LikeC4GrammarDocument, Required<LikeC4DocumentProps> {
173
+ }
174
+ export declare function isLikeC4LangiumDocument(doc: LangiumDocument): doc is LikeC4LangiumDocument;
175
+ export declare function isFqnIndexedDocument(doc: LangiumDocument): doc is FqnIndexedDocument;
176
+ export declare function isParsedLikeC4LangiumDocument(doc: LangiumDocument): doc is ParsedLikeC4LangiumDocument;
177
+ export declare function streamModel(doc: LikeC4LangiumDocument): Generator<any, void, unknown>;
178
+ export declare function streamDeploymentModel(doc: LikeC4LangiumDocument): Generator<any, void, unknown>;
179
+ export declare function resolveRelationPoints(node: ast.Relation): {
180
+ source: ast.Element;
181
+ target: ast.Element;
182
+ };
183
+ export declare function parseAstOpacityProperty({ value }: ast.OpacityProperty): number;
184
+ export declare function toElementStyle(props: Array<ast.StyleProperty> | undefined, isValid: IsValidFn): ParsedElementStyle;
185
+ export declare function toRelationshipStyle(props: ast.RelationshipStyleProperty[] | undefined, isValid: IsValidFn): {
186
+ color?: c4.Color;
187
+ line?: c4.RelationshipLineType;
188
+ head?: c4.RelationshipArrowType;
189
+ tail?: c4.RelationshipArrowType;
190
+ };
191
+ export declare function toRelationshipStyleExcludeDefaults(props: ast.SpecificationRelationshipKind['props'] | undefined, isValid: IsValidFn): {
192
+ tail?: any;
193
+ head?: any;
194
+ line?: any;
195
+ color?: any;
196
+ };
197
+ export declare function toColor(astNode: ast.ColorProperty): c4.Color | undefined;
198
+ export declare function toAutoLayout(rule: ast.ViewRuleAutoLayout): c4.ViewRuleAutoLayout;
199
+ export declare function toAstViewLayoutDirection(c4: c4.ViewRuleAutoLayout['direction']): ast.ViewLayoutDirection;
200
+ export declare function elementExpressionFromPredicate(predicate: ast.ElementPredicate): ast.ElementExpression;
package/dist/ast.js ADDED
@@ -0,0 +1,276 @@
1
+ import { DefaultArrowType, DefaultLineStyle, DefaultRelationshipColor, LinkedList, nonexhaustive } from "@likec4/core";
2
+ import { DocumentState } from "langium";
3
+ import { clamp, isDefined, isNullish, isTruthy } from "remeda";
4
+ import * as ast from "./generated/ast.js";
5
+ import { LikeC4LanguageMetaData } from "./generated/module.js";
6
+ import { elementRef } from "./utils/elementRef.js";
7
+ export { ast };
8
+ const idattr = Symbol.for("idattr");
9
+ export const ViewOps = {
10
+ writeId(node, id) {
11
+ node[idattr] = id;
12
+ return node;
13
+ },
14
+ readId(node) {
15
+ return node[idattr];
16
+ }
17
+ };
18
+ export const ElementOps = {
19
+ writeId(node, id) {
20
+ if (isNullish(id)) {
21
+ node[idattr] = void 0;
22
+ } else {
23
+ node[idattr] = id;
24
+ }
25
+ return node;
26
+ },
27
+ readId(node) {
28
+ return node[idattr];
29
+ }
30
+ };
31
+ export function isLikeC4LangiumDocument(doc) {
32
+ return doc.textDocument.languageId === LikeC4LanguageMetaData.languageId;
33
+ }
34
+ export function isFqnIndexedDocument(doc) {
35
+ return isLikeC4LangiumDocument(doc) && doc.state >= DocumentState.IndexedContent && !!doc.c4fqnIndex;
36
+ }
37
+ export function isParsedLikeC4LangiumDocument(doc) {
38
+ return isLikeC4LangiumDocument(doc) && doc.state == DocumentState.Validated && !!doc.c4Specification && !!doc.c4Elements && !!doc.c4Relations && !!doc.c4Views && !!doc.c4fqnIndex && !!doc.c4Deployments && !!doc.c4DeploymentRelations;
39
+ }
40
+ export function* streamModel(doc) {
41
+ const traverseStack = LinkedList.from(doc.parseResult.value.models.flatMap((m) => m.elements));
42
+ const relations = [];
43
+ let el;
44
+ while (el = traverseStack.shift()) {
45
+ if (ast.isRelation(el)) {
46
+ relations.push(el);
47
+ continue;
48
+ }
49
+ if (ast.isExtendElement(el)) {
50
+ if (el.body && el.body.elements.length > 0) {
51
+ for (const child of el.body.elements) {
52
+ traverseStack.push(child);
53
+ }
54
+ }
55
+ continue;
56
+ }
57
+ if (el.body && el.body.elements.length > 0) {
58
+ for (const child of el.body.elements) {
59
+ traverseStack.push(child);
60
+ }
61
+ }
62
+ yield el;
63
+ }
64
+ yield* relations;
65
+ return;
66
+ }
67
+ export function* streamDeploymentModel(doc) {
68
+ const traverseStack = LinkedList.from(
69
+ doc.parseResult.value.deployments.flatMap((m) => m.elements)
70
+ );
71
+ const relations = [];
72
+ let el;
73
+ while (el = traverseStack.shift()) {
74
+ if (ast.isDeploymentRelation(el)) {
75
+ relations.push(el);
76
+ continue;
77
+ }
78
+ if (ast.isDeploymentNode(el) && el.body && el.body.elements.length > 0) {
79
+ for (const child of el.body.elements) {
80
+ traverseStack.push(child);
81
+ }
82
+ }
83
+ yield el;
84
+ }
85
+ yield* relations;
86
+ return;
87
+ }
88
+ export function resolveRelationPoints(node) {
89
+ const target = elementRef(node.target);
90
+ if (!target) {
91
+ throw new Error("RelationRefError: Invalid reference to target");
92
+ }
93
+ if (isDefined(node.source)) {
94
+ const source = elementRef(node.source);
95
+ if (!source) {
96
+ throw new Error("RelationRefError: Invalid reference to source");
97
+ }
98
+ return {
99
+ source,
100
+ target
101
+ };
102
+ }
103
+ if (!ast.isElementBody(node.$container)) {
104
+ throw new Error("RelationRefError: Invalid container for sourceless relation");
105
+ }
106
+ return {
107
+ source: node.$container.$container,
108
+ target
109
+ };
110
+ }
111
+ export function parseAstOpacityProperty({ value }) {
112
+ const opacity = parseFloat(value);
113
+ return isNaN(opacity) ? 100 : clamp(opacity, { min: 0, max: 100 });
114
+ }
115
+ export function toElementStyle(props, isValid) {
116
+ const result = {};
117
+ if (!props || props.length === 0) {
118
+ return result;
119
+ }
120
+ for (const prop of props) {
121
+ if (!isValid(prop)) {
122
+ continue;
123
+ }
124
+ switch (true) {
125
+ case ast.isBorderProperty(prop): {
126
+ if (isTruthy(prop.value)) {
127
+ result.border = prop.value;
128
+ }
129
+ break;
130
+ }
131
+ case ast.isColorProperty(prop): {
132
+ const color = toColor(prop);
133
+ if (isTruthy(color)) {
134
+ result.color = color;
135
+ }
136
+ break;
137
+ }
138
+ case ast.isShapeProperty(prop): {
139
+ if (isTruthy(prop.value)) {
140
+ result.shape = prop.value;
141
+ }
142
+ break;
143
+ }
144
+ case ast.isIconProperty(prop): {
145
+ const icon = prop.libicon?.ref?.name ?? prop.value;
146
+ if (isTruthy(icon)) {
147
+ result.icon = icon;
148
+ }
149
+ break;
150
+ }
151
+ case ast.isOpacityProperty(prop): {
152
+ result.opacity = parseAstOpacityProperty(prop);
153
+ break;
154
+ }
155
+ default:
156
+ nonexhaustive(prop);
157
+ }
158
+ }
159
+ return result;
160
+ }
161
+ export function toRelationshipStyle(props, isValid) {
162
+ const result = {};
163
+ if (!props || props.length === 0) {
164
+ return result;
165
+ }
166
+ for (const prop of props) {
167
+ if (!isValid(prop)) {
168
+ continue;
169
+ }
170
+ switch (true) {
171
+ case ast.isColorProperty(prop): {
172
+ const color = toColor(prop);
173
+ if (isTruthy(color)) {
174
+ result.color = color;
175
+ }
176
+ break;
177
+ }
178
+ case ast.isLineProperty(prop): {
179
+ result.line = prop.value;
180
+ break;
181
+ }
182
+ case ast.isArrowProperty(prop): {
183
+ switch (prop.key) {
184
+ case "head": {
185
+ result.head = prop.value;
186
+ break;
187
+ }
188
+ case "tail": {
189
+ result.tail = prop.value;
190
+ break;
191
+ }
192
+ default: {
193
+ nonexhaustive(prop);
194
+ }
195
+ }
196
+ break;
197
+ }
198
+ default: {
199
+ nonexhaustive(prop);
200
+ }
201
+ }
202
+ }
203
+ return result;
204
+ }
205
+ export function toRelationshipStyleExcludeDefaults(props, isValid) {
206
+ const { color, line, head, tail } = toRelationshipStyle(props?.filter(ast.isRelationshipStyleProperty), isValid);
207
+ return {
208
+ ...color && color !== DefaultRelationshipColor ? { color } : {},
209
+ ...line && line !== DefaultLineStyle ? { line } : {},
210
+ ...head && head !== DefaultArrowType ? { head } : {},
211
+ ...tail ? { tail } : {}
212
+ };
213
+ }
214
+ export function toColor(astNode) {
215
+ return astNode?.themeColor ?? astNode?.customColor?.$refText;
216
+ }
217
+ export function toAutoLayout(rule) {
218
+ const rankSep = rule.rankSep;
219
+ const nodeSep = rule.nodeSep;
220
+ let direction;
221
+ switch (rule.direction) {
222
+ case "TopBottom": {
223
+ direction = "TB";
224
+ break;
225
+ }
226
+ case "BottomTop": {
227
+ direction = "BT";
228
+ break;
229
+ }
230
+ case "LeftRight": {
231
+ direction = "LR";
232
+ break;
233
+ }
234
+ case "RightLeft": {
235
+ direction = "RL";
236
+ break;
237
+ }
238
+ default:
239
+ nonexhaustive(rule.direction);
240
+ }
241
+ return {
242
+ direction,
243
+ ...nodeSep && { nodeSep },
244
+ ...rankSep && { rankSep }
245
+ };
246
+ }
247
+ export function toAstViewLayoutDirection(c4) {
248
+ switch (c4) {
249
+ case "TB": {
250
+ return "TopBottom";
251
+ }
252
+ case "BT": {
253
+ return "BottomTop";
254
+ }
255
+ case "LR": {
256
+ return "LeftRight";
257
+ }
258
+ case "RL": {
259
+ return "RightLeft";
260
+ }
261
+ default:
262
+ nonexhaustive(c4);
263
+ }
264
+ }
265
+ export function elementExpressionFromPredicate(predicate) {
266
+ if (ast.isElementExpression(predicate)) {
267
+ return predicate;
268
+ }
269
+ if (ast.isElementPredicateWhere(predicate)) {
270
+ return predicate.subject;
271
+ }
272
+ if (ast.isElementPredicateWith(predicate)) {
273
+ return elementExpressionFromPredicate(predicate.subject);
274
+ }
275
+ nonexhaustive(predicate);
276
+ }
package/dist/browser.d.ts CHANGED
@@ -1,23 +1,9 @@
1
- import { L as LikeC4SharedServices, a as LikeC4Services } from './shared/language-server.De7S3e5Z.js';
2
- export { D as DeploymentsIndex, e as DocumentDeploymentsIndex, g as FqnIndex, F as FqnIndexEntry, I as IsValidFn, l as LanguageServicesContext, k as LikeC4AddedServices, h as LikeC4ModelBuilder, i as LikeC4ModelLocator, j as LikeC4ModelParser, d as LikeC4Module, M as ModelParsedListener, f as computeDocumentFqn, c as createCustomLanguageServices, b as createLanguageServices, m as createSharedServices, s as setLogLevel } from './shared/language-server.De7S3e5Z.js';
3
- import * as vscode_languageserver from 'vscode-languageserver';
4
- import { BrowserMessageReader, BrowserMessageWriter } from 'vscode-languageserver/browser';
5
- import 'langium';
6
- import 'langium/lsp';
7
- import 'vscode-languageserver-types';
8
- import '@likec4/core';
9
- import 'type-fest';
10
- import './protocol.js';
11
- import 'vscode-jsonrpc';
12
- import 'vscode-uri';
13
- import '@likec4/log';
14
-
15
- declare function startLanguageServer(): {
16
- connection: vscode_languageserver.Connection;
17
- messageReader: BrowserMessageReader;
18
- messageWriter: BrowserMessageWriter;
1
+ import { type LikeC4Services, type LikeC4SharedServices } from './module';
2
+ export { logger as lspLogger, setLogLevel } from './logger';
3
+ export type { DocumentParser, LikeC4ModelBuilder, LikeC4ModelLocator, LikeC4ModelParser } from './model';
4
+ export { createCustomLanguageServices, createLanguageServices, LikeC4Module } from './module';
5
+ export type { LikeC4Services, LikeC4SharedServices } from './module';
6
+ export declare function startLanguageServer(): {
19
7
  shared: LikeC4SharedServices;
20
8
  likec4: LikeC4Services;
21
9
  };
22
-
23
- export { LikeC4Services, LikeC4SharedServices, startLanguageServer };
@@ -0,0 +1,13 @@
1
+ import { startLanguageServer as startLanguim } from "langium/lsp";
2
+ import { BrowserMessageReader, BrowserMessageWriter, createConnection } from "vscode-languageserver/browser";
3
+ import { createLanguageServices } from "./module.js";
4
+ export { logger as lspLogger, setLogLevel } from "./logger.js";
5
+ export { createCustomLanguageServices, createLanguageServices, LikeC4Module } from "./module.js";
6
+ export function startLanguageServer() {
7
+ const messageReader = new BrowserMessageReader(self);
8
+ const messageWriter = new BrowserMessageWriter(self);
9
+ const connection = createConnection(messageReader, messageWriter);
10
+ const services = createLanguageServices({ connection });
11
+ startLanguim(services.shared);
12
+ return services;
13
+ }