@likec4/language-server 1.47.0 → 1.48.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 (316) hide show
  1. package/LICENSE +1 -1
  2. package/browser/package.json +2 -2
  3. package/browser-worker/package.json +2 -2
  4. package/bundled/package.json +4 -0
  5. package/dist/LikeC4LanguageServices.d.mts +4 -0
  6. package/dist/LikeC4LanguageServices.mjs +3 -0
  7. package/dist/_chunks/ConfigurableLayouter.mjs +1956 -0
  8. package/dist/_chunks/LikeC4LanguageServices.d.mts +1978 -0
  9. package/dist/_chunks/LikeC4LanguageServices.mjs +725 -0
  10. package/dist/_chunks/ast.d.mts +1444 -0
  11. package/dist/_chunks/ast.mjs +2375 -0
  12. package/dist/_chunks/ast2.mjs +176 -0
  13. package/dist/_chunks/common-exports.mjs +0 -0
  14. package/dist/_chunks/filesystem.mjs +58 -0
  15. package/dist/_chunks/grammar.mjs +8 -0
  16. package/dist/_chunks/icons.mjs +5211 -0
  17. package/dist/_chunks/libs/@hono/node-server.mjs +436 -0
  18. package/dist/_chunks/libs/@msgpack/msgpack.mjs +805 -0
  19. package/dist/_chunks/libs/eventemitter3.mjs +243 -0
  20. package/dist/_chunks/libs/fast-equals.mjs +446 -0
  21. package/dist/_chunks/libs/hono.mjs +1829 -0
  22. package/dist/_chunks/libs/p-queue.mjs +449 -0
  23. package/dist/_chunks/libs/parse-ms.mjs +36 -0
  24. package/dist/_chunks/libs/picomatch.mjs +1673 -0
  25. package/dist/_chunks/libs/pretty-ms.mjs +80 -0
  26. package/dist/_chunks/libs/remeda.mjs +482 -0
  27. package/dist/_chunks/libs/strip-indent.mjs +15 -0
  28. package/dist/_chunks/libs/ufo.mjs +166 -0
  29. package/dist/_chunks/likec4lib.mjs +9 -0
  30. package/dist/_chunks/mcp.mjs +33 -0
  31. package/dist/_chunks/module.mjs +28 -0
  32. package/dist/_chunks/module2.mjs +6576 -0
  33. package/dist/_chunks/protocol.d.mts +311 -0
  34. package/dist/_chunks/protocol.mjs +78 -0
  35. package/dist/_chunks/rolldown-runtime.mjs +42 -0
  36. package/dist/ast.d.mts +4 -0
  37. package/dist/ast.mjs +4 -0
  38. package/dist/browser-worker.d.mts +1 -0
  39. package/dist/browser-worker.mjs +6 -0
  40. package/dist/browser.d.mts +11 -0
  41. package/dist/browser.mjs +27 -0
  42. package/dist/bundled.d.mts +28 -0
  43. package/dist/bundled.mjs +51 -4853
  44. package/dist/common-exports.d.mts +4 -0
  45. package/dist/common-exports.mjs +5 -0
  46. package/dist/filesystem/index.d.mts +4 -0
  47. package/dist/filesystem/index.mjs +3 -0
  48. package/dist/generated/ast.d.mts +2 -0
  49. package/dist/generated/ast.mjs +3 -0
  50. package/dist/generated/grammar.d.mts +6 -0
  51. package/dist/generated/grammar.mjs +3 -0
  52. package/dist/generated/module.d.mts +14 -0
  53. package/dist/generated/module.mjs +3 -0
  54. package/dist/generated-lib/icons.d.mts +4 -0
  55. package/dist/generated-lib/icons.mjs +3 -0
  56. package/dist/index.d.mts +4 -0
  57. package/dist/index.mjs +48 -0
  58. package/dist/likec4lib.d.mts +9 -0
  59. package/dist/likec4lib.mjs +4 -0
  60. package/dist/mcp/index.d.mts +4 -0
  61. package/dist/mcp/index.mjs +3 -0
  62. package/dist/module.d.mts +4 -0
  63. package/dist/module.mjs +3 -0
  64. package/dist/protocol.d.mts +2 -0
  65. package/dist/protocol.mjs +3 -0
  66. package/likec4lib/package.json +2 -2
  67. package/package.json +106 -63
  68. package/protocol/package.json +2 -2
  69. package/dist/LikeC4LanguageServices.d.ts +0 -115
  70. package/dist/LikeC4LanguageServices.js +0 -164
  71. package/dist/Rpc.d.ts +0 -9
  72. package/dist/Rpc.js +0 -276
  73. package/dist/ast.d.ts +0 -226
  74. package/dist/ast.js +0 -264
  75. package/dist/browser-worker.d.ts +0 -1
  76. package/dist/browser-worker.js +0 -4
  77. package/dist/browser.d.ts +0 -10
  78. package/dist/browser.js +0 -34
  79. package/dist/bundled.d.ts +0 -8
  80. package/dist/bundled.js +0 -44
  81. package/dist/documentation/documentation-provider.d.ts +0 -8
  82. package/dist/documentation/documentation-provider.js +0 -51
  83. package/dist/documentation/index.d.ts +0 -1
  84. package/dist/documentation/index.js +0 -1
  85. package/dist/empty.d.ts +0 -2
  86. package/dist/empty.js +0 -2
  87. package/dist/filesystem/ChokidarWatcher.d.ts +0 -19
  88. package/dist/filesystem/ChokidarWatcher.js +0 -133
  89. package/dist/filesystem/FileSystemWatcher.d.ts +0 -19
  90. package/dist/filesystem/FileSystemWatcher.js +0 -14
  91. package/dist/filesystem/LikeC4FileSystem.d.ts +0 -3
  92. package/dist/filesystem/LikeC4FileSystem.js +0 -140
  93. package/dist/filesystem/index.d.ts +0 -55
  94. package/dist/filesystem/index.js +0 -29
  95. package/dist/formatting/LikeC4Formatter.d.ts +0 -59
  96. package/dist/formatting/LikeC4Formatter.js +0 -637
  97. package/dist/formatting/utils.d.ts +0 -6
  98. package/dist/formatting/utils.js +0 -18
  99. package/dist/generated/ast.d.ts +0 -1411
  100. package/dist/generated/ast.js +0 -2207
  101. package/dist/generated/grammar.d.ts +0 -6
  102. package/dist/generated/grammar.js +0 -7
  103. package/dist/generated/module.d.ts +0 -14
  104. package/dist/generated/module.js +0 -27
  105. package/dist/generated-lib/icons.d.ts +0 -1
  106. package/dist/generated-lib/icons.js +0 -18
  107. package/dist/index.d.ts +0 -37
  108. package/dist/index.js +0 -54
  109. package/dist/likec4lib.d.ts +0 -6
  110. package/dist/likec4lib.js +0 -7
  111. package/dist/logger.d.ts +0 -17
  112. package/dist/logger.js +0 -81
  113. package/dist/lsp/CodeActionProvider.d.ts +0 -14
  114. package/dist/lsp/CodeActionProvider.js +0 -33
  115. package/dist/lsp/CodeLensProvider.d.ts +0 -9
  116. package/dist/lsp/CodeLensProvider.js +0 -44
  117. package/dist/lsp/CompletionProvider.d.ts +0 -13
  118. package/dist/lsp/CompletionProvider.js +0 -238
  119. package/dist/lsp/DocumentHighlightProvider.d.ts +0 -9
  120. package/dist/lsp/DocumentHighlightProvider.js +0 -10
  121. package/dist/lsp/DocumentLinkProvider.d.ts +0 -11
  122. package/dist/lsp/DocumentLinkProvider.js +0 -58
  123. package/dist/lsp/DocumentSymbolProvider.d.ts +0 -33
  124. package/dist/lsp/DocumentSymbolProvider.js +0 -317
  125. package/dist/lsp/HoverProvider.d.ts +0 -10
  126. package/dist/lsp/HoverProvider.js +0 -106
  127. package/dist/lsp/RenameProvider.d.ts +0 -5
  128. package/dist/lsp/RenameProvider.js +0 -6
  129. package/dist/lsp/SemanticTokenProvider.d.ts +0 -19
  130. package/dist/lsp/SemanticTokenProvider.js +0 -305
  131. package/dist/lsp/index.d.ts +0 -8
  132. package/dist/lsp/index.js +0 -9
  133. package/dist/mcp/MCPServerFactory.d.ts +0 -8
  134. package/dist/mcp/MCPServerFactory.js +0 -73
  135. package/dist/mcp/NoopLikeC4MCPServer.d.ts +0 -9
  136. package/dist/mcp/NoopLikeC4MCPServer.js +0 -17
  137. package/dist/mcp/interfaces.d.ts +0 -13
  138. package/dist/mcp/interfaces.js +0 -4
  139. package/dist/mcp/server/StdioLikeC4MCPServer.d.ts +0 -16
  140. package/dist/mcp/server/StdioLikeC4MCPServer.js +0 -51
  141. package/dist/mcp/server/StreamableLikeC4MCPServer.d.ts +0 -16
  142. package/dist/mcp/server/StreamableLikeC4MCPServer.js +0 -121
  143. package/dist/mcp/server/WithMCPServer.d.ts +0 -4
  144. package/dist/mcp/server/WithMCPServer.js +0 -54
  145. package/dist/mcp/tools/_common.d.ts +0 -88
  146. package/dist/mcp/tools/_common.js +0 -49
  147. package/dist/mcp/tools/find-relationships.d.ts +0 -202
  148. package/dist/mcp/tools/find-relationships.js +0 -150
  149. package/dist/mcp/tools/list-projects.d.ts +0 -194
  150. package/dist/mcp/tools/list-projects.js +0 -62
  151. package/dist/mcp/tools/open-view.d.ts +0 -200
  152. package/dist/mcp/tools/open-view.js +0 -52
  153. package/dist/mcp/tools/read-deployment.d.ts +0 -200
  154. package/dist/mcp/tools/read-deployment.js +0 -150
  155. package/dist/mcp/tools/read-element.d.ts +0 -200
  156. package/dist/mcp/tools/read-element.js +0 -218
  157. package/dist/mcp/tools/read-project-summary.d.ts +0 -198
  158. package/dist/mcp/tools/read-project-summary.js +0 -176
  159. package/dist/mcp/tools/read-view.d.ts +0 -200
  160. package/dist/mcp/tools/read-view.js +0 -203
  161. package/dist/mcp/tools/search-element.d.ts +0 -198
  162. package/dist/mcp/tools/search-element.js +0 -177
  163. package/dist/mcp/utils.d.ts +0 -18
  164. package/dist/mcp/utils.js +0 -48
  165. package/dist/model/builder/MergedExtends.d.ts +0 -13
  166. package/dist/model/builder/MergedExtends.js +0 -74
  167. package/dist/model/builder/MergedSpecification.d.ts +0 -32
  168. package/dist/model/builder/MergedSpecification.js +0 -175
  169. package/dist/model/builder/buildModel.d.ts +0 -16
  170. package/dist/model/builder/buildModel.js +0 -245
  171. package/dist/model/deployments-index.d.ts +0 -10
  172. package/dist/model/deployments-index.js +0 -102
  173. package/dist/model/fqn-index.d.ts +0 -61
  174. package/dist/model/fqn-index.js +0 -253
  175. package/dist/model/index.d.ts +0 -6
  176. package/dist/model/index.js +0 -6
  177. package/dist/model/model-builder.d.ts +0 -54
  178. package/dist/model/model-builder.js +0 -233
  179. package/dist/model/model-locator.d.ts +0 -39
  180. package/dist/model/model-locator.js +0 -240
  181. package/dist/model/model-parser-where.d.ts +0 -4
  182. package/dist/model/model-parser-where.js +0 -81
  183. package/dist/model/model-parser.d.ts +0 -645
  184. package/dist/model/model-parser.js +0 -133
  185. package/dist/model/parser/Base.d.ts +0 -69
  186. package/dist/model/parser/Base.js +0 -382
  187. package/dist/model/parser/DeploymentModelParser.d.ts +0 -71
  188. package/dist/model/parser/DeploymentModelParser.js +0 -176
  189. package/dist/model/parser/DeploymentViewParser.d.ts +0 -75
  190. package/dist/model/parser/DeploymentViewParser.js +0 -86
  191. package/dist/model/parser/FqnRefParser.d.ts +0 -66
  192. package/dist/model/parser/FqnRefParser.js +0 -382
  193. package/dist/model/parser/GlobalsParser.d.ts +0 -109
  194. package/dist/model/parser/GlobalsParser.js +0 -84
  195. package/dist/model/parser/ImportsParser.d.ts +0 -46
  196. package/dist/model/parser/ImportsParser.js +0 -24
  197. package/dist/model/parser/ModelParser.d.ts +0 -71
  198. package/dist/model/parser/ModelParser.js +0 -209
  199. package/dist/model/parser/PredicatesParser.d.ts +0 -75
  200. package/dist/model/parser/PredicatesParser.js +0 -45
  201. package/dist/model/parser/SpecificationParser.d.ts +0 -53
  202. package/dist/model/parser/SpecificationParser.js +0 -113
  203. package/dist/model/parser/ValueConverter.d.ts +0 -4
  204. package/dist/model/parser/ValueConverter.js +0 -12
  205. package/dist/model/parser/ViewsParser.d.ts +0 -112
  206. package/dist/model/parser/ViewsParser.js +0 -492
  207. package/dist/model-change/ModelChanges.d.ts +0 -18
  208. package/dist/model-change/ModelChanges.js +0 -129
  209. package/dist/model-change/changeElementStyle.d.ts +0 -16
  210. package/dist/model-change/changeElementStyle.js +0 -134
  211. package/dist/model-change/changeViewLayout.d.ts +0 -12
  212. package/dist/model-change/changeViewLayout.js +0 -28
  213. package/dist/model-change/removeManualLayoutV1.d.ts +0 -7
  214. package/dist/model-change/removeManualLayoutV1.js +0 -27
  215. package/dist/module.d.ts +0 -92
  216. package/dist/module.js +0 -143
  217. package/dist/protocol.d.ts +0 -289
  218. package/dist/protocol.js +0 -123
  219. package/dist/references/index.d.ts +0 -3
  220. package/dist/references/index.js +0 -3
  221. package/dist/references/name-provider.d.ts +0 -9
  222. package/dist/references/name-provider.js +0 -37
  223. package/dist/references/scope-computation.d.ts +0 -20
  224. package/dist/references/scope-computation.js +0 -288
  225. package/dist/references/scope-provider.d.ts +0 -40
  226. package/dist/references/scope-provider.js +0 -239
  227. package/dist/shared/NodeKindProvider.d.ts +0 -15
  228. package/dist/shared/NodeKindProvider.js +0 -57
  229. package/dist/shared/WorkspaceSymbolProvider.d.ts +0 -3
  230. package/dist/shared/WorkspaceSymbolProvider.js +0 -3
  231. package/dist/shared/index.d.ts +0 -2
  232. package/dist/shared/index.js +0 -2
  233. package/dist/test/index.d.ts +0 -1
  234. package/dist/test/index.js +0 -1
  235. package/dist/test/testServices.d.ts +0 -64
  236. package/dist/test/testServices.js +0 -210
  237. package/dist/utils/disposable.d.ts +0 -8
  238. package/dist/utils/disposable.js +0 -26
  239. package/dist/utils/elementRef.d.ts +0 -11
  240. package/dist/utils/elementRef.js +0 -33
  241. package/dist/utils/fqnRef.d.ts +0 -11
  242. package/dist/utils/fqnRef.js +0 -63
  243. package/dist/utils/index.d.ts +0 -11
  244. package/dist/utils/index.js +0 -35
  245. package/dist/utils/printDocs.d.ts +0 -2
  246. package/dist/utils/printDocs.js +0 -1
  247. package/dist/utils/projectId.d.ts +0 -4
  248. package/dist/utils/projectId.js +0 -16
  249. package/dist/utils/stringHash.d.ts +0 -1
  250. package/dist/utils/stringHash.js +0 -5
  251. package/dist/validation/DocumentValidator.d.ts +0 -11
  252. package/dist/validation/DocumentValidator.js +0 -17
  253. package/dist/validation/_shared.d.ts +0 -3
  254. package/dist/validation/_shared.js +0 -26
  255. package/dist/validation/deployment-checks.d.ts +0 -7
  256. package/dist/validation/deployment-checks.js +0 -140
  257. package/dist/validation/dynamic-view.d.ts +0 -6
  258. package/dist/validation/dynamic-view.js +0 -67
  259. package/dist/validation/element-ref.d.ts +0 -4
  260. package/dist/validation/element-ref.js +0 -12
  261. package/dist/validation/element.d.ts +0 -4
  262. package/dist/validation/element.js +0 -49
  263. package/dist/validation/imports.d.ts +0 -4
  264. package/dist/validation/imports.js +0 -46
  265. package/dist/validation/index.d.ts +0 -15
  266. package/dist/validation/index.js +0 -167
  267. package/dist/validation/property-checks.d.ts +0 -7
  268. package/dist/validation/property-checks.js +0 -108
  269. package/dist/validation/relation.d.ts +0 -6
  270. package/dist/validation/relation.js +0 -141
  271. package/dist/validation/specification.d.ts +0 -12
  272. package/dist/validation/specification.js +0 -190
  273. package/dist/validation/view-checks.d.ts +0 -4
  274. package/dist/validation/view-checks.js +0 -46
  275. package/dist/validation/view-predicates/fqn-expr-with.d.ts +0 -4
  276. package/dist/validation/view-predicates/fqn-expr-with.js +0 -43
  277. package/dist/validation/view-predicates/fqn-ref-expr.d.ts +0 -4
  278. package/dist/validation/view-predicates/fqn-ref-expr.js +0 -51
  279. package/dist/validation/view-predicates/incoming.d.ts +0 -4
  280. package/dist/validation/view-predicates/incoming.js +0 -16
  281. package/dist/validation/view-predicates/index.d.ts +0 -6
  282. package/dist/validation/view-predicates/index.js +0 -6
  283. package/dist/validation/view-predicates/outgoing.d.ts +0 -4
  284. package/dist/validation/view-predicates/outgoing.js +0 -20
  285. package/dist/validation/view-predicates/relation-expr.d.ts +0 -4
  286. package/dist/validation/view-predicates/relation-expr.js +0 -46
  287. package/dist/validation/view-predicates/relation-with.d.ts +0 -4
  288. package/dist/validation/view-predicates/relation-with.js +0 -16
  289. package/dist/validation/view.d.ts +0 -4
  290. package/dist/validation/view.js +0 -42
  291. package/dist/view-utils/assignNavigateTo.d.ts +0 -2
  292. package/dist/view-utils/assignNavigateTo.js +0 -27
  293. package/dist/view-utils/index.d.ts +0 -2
  294. package/dist/view-utils/index.js +0 -2
  295. package/dist/view-utils/manual-layout.d.ts +0 -13
  296. package/dist/view-utils/manual-layout.js +0 -149
  297. package/dist/views/ConfigurableLayouter.d.ts +0 -7
  298. package/dist/views/ConfigurableLayouter.js +0 -51
  299. package/dist/views/LikeC4ManualLayouts.d.ts +0 -42
  300. package/dist/views/LikeC4ManualLayouts.js +0 -209
  301. package/dist/views/LikeC4Views.d.ts +0 -89
  302. package/dist/views/LikeC4Views.js +0 -216
  303. package/dist/views/index.d.ts +0 -4
  304. package/dist/views/index.js +0 -11
  305. package/dist/workspace/AstNodeDescriptionProvider.d.ts +0 -7
  306. package/dist/workspace/AstNodeDescriptionProvider.js +0 -18
  307. package/dist/workspace/IndexManager.d.ts +0 -10
  308. package/dist/workspace/IndexManager.js +0 -26
  309. package/dist/workspace/LangiumDocuments.d.ts +0 -29
  310. package/dist/workspace/LangiumDocuments.js +0 -104
  311. package/dist/workspace/ProjectsManager.d.ts +0 -134
  312. package/dist/workspace/ProjectsManager.js +0 -610
  313. package/dist/workspace/WorkspaceManager.d.ts +0 -31
  314. package/dist/workspace/WorkspaceManager.js +0 -132
  315. package/dist/workspace/index.d.ts +0 -5
  316. package/dist/workspace/index.js +0 -5
@@ -0,0 +1,725 @@
1
+ import { r as __toESM } from "./rolldown-runtime.mjs";
2
+ import { r as isLikeC4Builtin } from "./likec4lib.mjs";
3
+ import { C as t$5, F as t$2, M as n, N as t$4, P as t, _ as e$1, i as t$3, o as e, u as t$1 } from "./libs/remeda.mjs";
4
+ import { t as deepEqual } from "./libs/fast-equals.mjs";
5
+ import { t as require_picomatch } from "./libs/picomatch.mjs";
6
+ import { a as joinRelativeURL, c as withTrailingSlash, d as withoutProtocol, f as withoutTrailingSlash, i as isRelative, o as joinURL, s as parseFilename, t as cleanDoubleSlashes } from "./libs/ufo.mjs";
7
+ import { errorFromLogRecord, getMessageOnlyFormatter, getTextFormatter, loggable, logger, wrapError } from "@likec4/log";
8
+ import { Disposable, OperationCancelled, URI, WorkspaceCache, isOperationCancelled } from "langium";
9
+ import { BiMap, DefaultMap, compareNaturalHierarchically, invariant, memoizeProp, nonNullable, nonexhaustive } from "@likec4/core/utils";
10
+ import { DiagnosticSeverity } from "vscode-languageserver-types";
11
+ import { isLikeC4Config, normalizeIncludeConfig, validateProjectConfig } from "@likec4/config";
12
+ import { LikeC4Model } from "@likec4/core/model";
13
+ import { nonexhaustive as nonexhaustive$1 } from "@likec4/core";
14
+ import { computeProjectsView } from "@likec4/core/compute-view";
15
+
16
+ //#region src/logger.ts
17
+ const logger$3 = logger.getChild("server");
18
+ /**
19
+ * Logs an error as warning (not critical)
20
+ */
21
+ function logWarnError(err) {
22
+ logger$3.warn(loggable(err));
23
+ }
24
+ function getLspConnectionSink(connection, props) {
25
+ const format = props?.formatter ?? getTextFormatter({ format: ({ category, message }) => {
26
+ return `${category} ${message}`;
27
+ } });
28
+ return (logObj) => {
29
+ try {
30
+ switch (logObj.level) {
31
+ case "trace":
32
+ case "debug":
33
+ connection.console.debug(format(logObj));
34
+ break;
35
+ case "info":
36
+ connection.console.info(format(logObj));
37
+ break;
38
+ case "warning":
39
+ connection.console.warn(format(logObj));
40
+ break;
41
+ case "error":
42
+ case "fatal":
43
+ connection.console.error(format(logObj));
44
+ break;
45
+ default: nonexhaustive(logObj.level);
46
+ }
47
+ } catch (e) {
48
+ console.error("Error while logging to LSP connection:", e);
49
+ }
50
+ };
51
+ }
52
+ function getTelemetrySink(connection) {
53
+ const messageOnly = getMessageOnlyFormatter();
54
+ return (logObj) => {
55
+ try {
56
+ switch (logObj.level) {
57
+ case "error":
58
+ case "fatal": {
59
+ const err = errorFromLogRecord(logObj);
60
+ if (err) connection.telemetry.logEvent({
61
+ eventName: "error",
62
+ message: `${err.name}: ${err.message}`,
63
+ category: logObj.category.join("."),
64
+ ...err.stack && { stack: err.stack }
65
+ });
66
+ else connection.telemetry.logEvent({
67
+ eventName: "error",
68
+ message: messageOnly(logObj),
69
+ category: logObj.category.join(".")
70
+ });
71
+ break;
72
+ }
73
+ }
74
+ } catch (e) {
75
+ console.error("Error while logging to LSP connection:", e);
76
+ }
77
+ };
78
+ }
79
+
80
+ //#endregion
81
+ //#region src/workspace/ProjectsManager.ts
82
+ var import_picomatch = /* @__PURE__ */ __toESM(require_picomatch(), 1);
83
+ const logger$2 = logger$3.getChild("ProjectsManager");
84
+ function normalizeUri(uri) {
85
+ if (URI.isUri(uri)) return uri.toString();
86
+ else if (typeof uri === "string") return uri.startsWith("file://") ? uri : URI.file(uri).toString();
87
+ else return uri.uri.toString();
88
+ }
89
+ /**
90
+ * Compare function to ensure consistent order
91
+ */
92
+ const compare = compareNaturalHierarchically("/", true);
93
+ const compareUri = (a, b) => compare(withoutTrailingSlash(a.path), withoutTrailingSlash(b.path));
94
+ /**
95
+ * Returns a predicate that checks if the given path is included in the project folder.
96
+ */
97
+ function isParentFolderFor(uri) {
98
+ const path = normalizeUri(uri);
99
+ return (p) => path.startsWith(p.folder);
100
+ }
101
+ function ProjectFolder(folder) {
102
+ folder = normalizeUri(folder);
103
+ return withTrailingSlash(folder);
104
+ }
105
+ const DefaultProject = {
106
+ id: "default",
107
+ config: {
108
+ name: "default",
109
+ exclude: ["**/node_modules/**"]
110
+ },
111
+ exclude: (0, import_picomatch.default)("**/node_modules/**", { dot: true }),
112
+ includeConfig: {
113
+ paths: [],
114
+ maxDepth: 3,
115
+ fileThreshold: 30
116
+ }
117
+ };
118
+ var ProjectsManager = class ProjectsManager {
119
+ /**
120
+ * The global project ID used for all documents
121
+ * that are not part of a specific project.
122
+ */
123
+ static DefaultProjectId = DefaultProject.id;
124
+ #updateListeners = [];
125
+ /**
126
+ * Configured default project ID.
127
+ * (it is used in CLI and Vite plugin)
128
+ */
129
+ #defaultProjectId = void 0;
130
+ /**
131
+ * Cached default project.
132
+ */
133
+ #defaultProject = void 0;
134
+ /**
135
+ * The mapping between project config files and project IDs.
136
+ */
137
+ #projectIdToFolder = new BiMap();
138
+ /**
139
+ * Registered projects.
140
+ * Sorted descending by the number of segments in the folder path.
141
+ * This ensures that the most specific project is used for a document.
142
+ */
143
+ #projects = [];
144
+ /**
145
+ * This is a cached lookup for performance.
146
+ */
147
+ #lookupById = new DefaultMap((id) => {
148
+ if (id === ProjectsManager.DefaultProjectId) {
149
+ const folder = ProjectFolder(this.getWorkspaceFolder());
150
+ return {
151
+ id,
152
+ config: DefaultProject.config,
153
+ folder,
154
+ folderUri: URI.parse(folder),
155
+ exclude: DefaultProject.exclude,
156
+ includeConfig: DefaultProject.includeConfig
157
+ };
158
+ }
159
+ return nonNullable(this.#projects.find((p) => p.id === id), `Project ${id} not found`);
160
+ });
161
+ #excludedDocuments = /* @__PURE__ */ new WeakMap();
162
+ constructor(services) {
163
+ this.services = services;
164
+ logger$2.debug`created`;
165
+ }
166
+ /**
167
+ * Returns:
168
+ * - configured default project ID if set
169
+ * - the default project ID if there are no projects.
170
+ * - the ID of the only project
171
+ * - undefined if there are multiple projects.
172
+ */
173
+ get defaultProjectId() {
174
+ if (this.#defaultProjectId) return this.#defaultProjectId;
175
+ if (this.#projects.length > 1) return;
176
+ return this.#projects[0]?.id ?? ProjectsManager.DefaultProjectId;
177
+ }
178
+ set defaultProjectId(id) {
179
+ if (id === this.#defaultProjectId) return;
180
+ this.#defaultProject = void 0;
181
+ if (!id || id === ProjectsManager.DefaultProjectId) {
182
+ logger$2.debug`reset default project ID`;
183
+ this.#defaultProjectId = void 0;
184
+ return;
185
+ }
186
+ invariant(this.#projects.find((p) => p.id === id), `Project "${id}" not found`);
187
+ logger$2.debug`set default project ID to ${id}`;
188
+ this.#defaultProjectId = id;
189
+ }
190
+ get default() {
191
+ if (!this.#defaultProject) {
192
+ const id = this.defaultProjectId ?? ProjectsManager.DefaultProjectId;
193
+ this.#defaultProject = this.#lookupById.get(id);
194
+ }
195
+ return this.#defaultProject;
196
+ }
197
+ get all() {
198
+ if (t(this.#projects, 1)) {
199
+ const ids = [...t$1(this.#projects, e("id")), DefaultProject.id];
200
+ if (this.#defaultProjectId) {
201
+ const idx = ids.findIndex((p) => p === this.#defaultProjectId);
202
+ if (idx > 0) {
203
+ const [defaultProject] = ids.splice(idx, 1);
204
+ return [defaultProject, ...ids];
205
+ }
206
+ }
207
+ return ids;
208
+ }
209
+ return [DefaultProject.id];
210
+ }
211
+ getProject(arg) {
212
+ const id = typeof arg === "string" ? arg : arg.likec4ProjectId || this.belongsTo(arg);
213
+ const project = this.#lookupById.get(id);
214
+ return {
215
+ id,
216
+ folderUri: project.folderUri,
217
+ config: project.config,
218
+ ...project.includePaths && { includePaths: t$1(project.includePaths, e("uri")) }
219
+ };
220
+ }
221
+ /**
222
+ * Returns all projects that include the specified folder, or inside the folder.
223
+ */
224
+ findAllProjectsByFolder(folder) {
225
+ const projectFolder = ProjectFolder(folder);
226
+ const isInsideOrIncludes = (p) => p.folder.startsWith(projectFolder) || projectFolder.startsWith(p.folder);
227
+ return this.#projects.filter(isInsideOrIncludes);
228
+ }
229
+ /**
230
+ * Validates and ensures the project ID.
231
+ * If no project ID is specified, returns default project ID
232
+ * If there are multiple projects and default project is not set, throws an error
233
+ */
234
+ ensureProjectId(projectId) {
235
+ if (projectId === ProjectsManager.DefaultProjectId) return this.defaultProjectId ?? ProjectsManager.DefaultProjectId;
236
+ if (projectId) {
237
+ invariant(this.#projectIdToFolder.has(projectId), `Project ID ${projectId} is not registered`);
238
+ return projectId;
239
+ }
240
+ return nonNullable(this.defaultProjectId, () => `Specify exact project, known: [${[...this.#projectIdToFolder.keys()].join(", ")}]`);
241
+ }
242
+ /**
243
+ * Validates and ensures the project.
244
+ */
245
+ ensureProject(projectId) {
246
+ projectId = this.ensureProjectId(projectId);
247
+ return this.getProject(projectId);
248
+ }
249
+ hasMultipleProjects() {
250
+ return this.#projects.length > 1;
251
+ }
252
+ /**
253
+ * Checks if the specified document should be excluded from processing.
254
+ */
255
+ isExcluded(document) {
256
+ if (typeof document === "string" || URI.isUri(document)) {
257
+ let docUriAsString = normalizeUri(document);
258
+ const project = this.findProjectForDocument(docUriAsString);
259
+ if (!project.exclude) return false;
260
+ const input = withoutProtocol(docUriAsString);
261
+ return project.exclude(input);
262
+ }
263
+ let isExcluded = this.#excludedDocuments.get(document);
264
+ if (isExcluded === void 0) {
265
+ isExcluded = this.isExcluded(document.uri);
266
+ this.#excludedDocuments.set(document, isExcluded);
267
+ }
268
+ return isExcluded;
269
+ }
270
+ /**
271
+ * Checks if the specified document is included by the project:
272
+ * - if the document belongs to the project and is not excluded
273
+ * - if the document is included by the project
274
+ */
275
+ isIncluded(projectId, document) {
276
+ if (typeof document !== "string" && !URI.isUri(document)) return this.isIncluded(projectId, document.uri);
277
+ if (this.belongsTo(document) === projectId) return !this.isExcluded(document);
278
+ let includePaths = this.#lookupById.get(projectId)?.includePaths;
279
+ if (!includePaths) return false;
280
+ return includePaths.some(isParentFolderFor(document));
281
+ }
282
+ /**
283
+ * Checks if it is a config file and it is not excluded by default exclude pattern
284
+ *
285
+ * @param entry The file system entry to check
286
+ */
287
+ isConfigFile(entry) {
288
+ const filename = parseFilename(entry.toString(), { strict: false })?.toLowerCase();
289
+ const isConfigFile = !!filename && isLikeC4Config(filename);
290
+ if (isConfigFile) {
291
+ if (DefaultProject.exclude(entry.path)) {
292
+ logger$2.debug`exclude config file ${entry.path}`;
293
+ return false;
294
+ }
295
+ }
296
+ return isConfigFile;
297
+ }
298
+ /**
299
+ * Registers likec4 project by config file.
300
+ */
301
+ async registerConfigFile(configFile, cancelToken) {
302
+ if (DefaultProject.exclude(configFile.path)) throw new Error(`Path to ${configFile.fsPath} is excluded by: ${DefaultProject.config.exclude.join(", ")}`);
303
+ if (!this.isConfigFile(configFile)) throw new Error(`${configFile.fsPath} is not a valid LikeC4 config filename.`);
304
+ try {
305
+ const config = await this.services.workspace.FileSystemProvider.loadProjectConfig(configFile);
306
+ const path = joinRelativeURL(configFile.path, "..");
307
+ const folderUri = configFile.with({ path });
308
+ return await this.registerProject({
309
+ config,
310
+ folderUri
311
+ }, cancelToken);
312
+ } catch (error) {
313
+ if (!isOperationCancelled(error)) {
314
+ this.services.lsp.Connection?.window.showErrorMessage(`LikeC4: Failed to register project at ${configFile.fsPath}`);
315
+ throw wrapError(error, `Failed to register project config ${configFile.fsPath}:\n`);
316
+ }
317
+ return Promise.reject(error);
318
+ }
319
+ }
320
+ /**
321
+ * Registers (or reloads) likec4 project by config file or config object.
322
+ * If there is some project registered at same folder, it will be reloaded.
323
+ */
324
+ async registerProject(opts, cancelToken) {
325
+ const config = validateProjectConfig(opts.config);
326
+ const folder = ProjectFolder(opts.folderUri);
327
+ let project = this.#projects.find((p) => p.folder === folder);
328
+ if (project && deepEqual(project.config, config)) return project;
329
+ let mustReset = false;
330
+ let id;
331
+ if (!project) {
332
+ if (this.#projectIdToFolder.has(config.name)) logger$2.warn`Project "${config.name}" already exists, generating unique ID`;
333
+ id = this.uniqueProjectId(config.name);
334
+ const includeConfig = normalizeIncludeConfig(config.include);
335
+ project = {
336
+ id,
337
+ config,
338
+ folder,
339
+ folderUri: URI.parse(folder),
340
+ includeConfig
341
+ };
342
+ mustReset = this.#projects.some((p) => p.folder.startsWith(folder) || folder.startsWith(p.folder));
343
+ this.#projects = t$2([...this.#projects, project], t$3((a, b) => compareUri(a.folderUri, b.folderUri)));
344
+ logger$2.info`register project ${project.id} folder: ${folder}`;
345
+ } else {
346
+ mustReset = true;
347
+ if (project.config.name !== config.name) {
348
+ this.#projectIdToFolder.delete(project.id);
349
+ logger$2.info`unregister project ${project.id} folder: ${folder}`;
350
+ id = this.uniqueProjectId(config.name);
351
+ project.id = id;
352
+ logger$2.info`re-register project ${project.id} folder: ${folder}`;
353
+ } else {
354
+ id = project.id;
355
+ logger$2.info`update project ${project.id} on config change`;
356
+ }
357
+ project.config = config;
358
+ const includeConfig = normalizeIncludeConfig(config.include);
359
+ project.includeConfig = includeConfig;
360
+ }
361
+ if (e$1(config.exclude)) project.exclude = DefaultProject.exclude;
362
+ else if (t(config.exclude, 1)) {
363
+ const patterns = t$1(config.exclude, (p) => {
364
+ if (!isRelative(p) && !p.startsWith("**")) p = joinURL("**", p);
365
+ return cleanDoubleSlashes(joinRelativeURL(project.folderUri.path, p));
366
+ });
367
+ project.exclude = (0, import_picomatch.default)(patterns, {
368
+ contains: true,
369
+ dot: true
370
+ });
371
+ }
372
+ if (project.includeConfig.paths && t(project.includeConfig.paths, 1)) {
373
+ project.includePaths = t$1(project.includeConfig.paths, (includePath) => {
374
+ const resolvedPath = joinRelativeURL(project.folderUri.path, includePath);
375
+ const uri = project.folderUri.with({ path: resolvedPath });
376
+ return {
377
+ uri,
378
+ folder: ProjectFolder(uri)
379
+ };
380
+ });
381
+ logger$2.debug`project ${project.id} include paths: ${project.includePaths.map((p) => p.uri.fsPath).join(", ")}`;
382
+ for (const includePath of project.includePaths) for (const otherProject of this.#projects) {
383
+ if (otherProject.id === project.id) continue;
384
+ if (includePath.folder.startsWith(otherProject.folder) || otherProject.folder.startsWith(includePath.folder)) {
385
+ mustReset = true;
386
+ logger$2.warn("Project \"{projectId}\" include path \"{includePath}\" overlaps with project \"{otherProjectId}\" folder. Files in overlapping areas will only belong to one project.", {
387
+ projectId: project.id,
388
+ includePath: includePath.folder,
389
+ otherProjectId: otherProject.id
390
+ });
391
+ }
392
+ if (otherProject.includePaths) {
393
+ for (const otherIncludePath of otherProject.includePaths) if (includePath.folder.startsWith(otherIncludePath.folder) || otherIncludePath.folder.startsWith(includePath.folder)) {
394
+ mustReset = true;
395
+ logger$2.warn("Project \"{projectId}\" include path \"{includePath}\" overlaps with project \"{otherProjectId}\" include path \"{otherIncludePath}\". Files in overlapping areas will only belong to one project.", {
396
+ projectId: project.id,
397
+ includePath: includePath.folder,
398
+ otherProjectId: otherProject.id,
399
+ otherIncludePath: otherIncludePath.folder
400
+ });
401
+ }
402
+ }
403
+ }
404
+ } else delete project.includePaths;
405
+ this.#defaultProject = void 0;
406
+ this.#projectIdToFolder.set(project.id, folder);
407
+ this.#lookupById.clear();
408
+ if (this.#activeReload) return project;
409
+ if (mustReset) await this.rebuidProject(project.id, cancelToken).catch((error) => {
410
+ if (isOperationCancelled(error)) return Promise.reject(error);
411
+ logger$2.warn("Failed to rebuild project {projectId} after config change", {
412
+ projectId: project.id,
413
+ error
414
+ });
415
+ return Promise.resolve();
416
+ });
417
+ this.notifyListeners();
418
+ return project;
419
+ }
420
+ /**
421
+ * Determines which project the given document belongs to.
422
+ * If the document does not belong to any project, returns the default project ID.
423
+ */
424
+ belongsTo(document) {
425
+ if (URI.isUri(document) || typeof document === "string") {
426
+ const documentUri = normalizeUri(document);
427
+ return this.findProjectForDocument(documentUri).id;
428
+ }
429
+ return this.documentBelongsTo.get(document, () => {
430
+ return this.findProjectForDocument(normalizeUri(document.uri));
431
+ }).id;
432
+ }
433
+ #activeReload = null;
434
+ async reloadProjects(cancelToken) {
435
+ if (this.#activeReload) {
436
+ logger$2.debug`reload projects is already in progress, waiting`;
437
+ return await this.#activeReload.catch(() => {});
438
+ }
439
+ logger$2.debug`schedule reload projects`;
440
+ this.#activeReload = Promise.resolve().then(() => this._reloadProjects(cancelToken)).catch((error) => {
441
+ if (!isOperationCancelled(error)) logger$2.warn("Failed to reload projects", { error });
442
+ return Promise.reject(error);
443
+ }).finally(() => {
444
+ this.#activeReload = null;
445
+ this.notifyListeners();
446
+ });
447
+ return await this.#activeReload;
448
+ }
449
+ async _reloadProjects(cancelToken) {
450
+ const folders = this.services.workspace.WorkspaceManager.workspaceFolders;
451
+ if (!folders) {
452
+ logger$2.warn("No workspace folders found");
453
+ return;
454
+ }
455
+ logger$2.debug`start reload projects`;
456
+ const configFiles = [];
457
+ for (const folder of folders) try {
458
+ logger$2.debug`scan projects in folder ${folder.uri}`;
459
+ const files = await this.services.workspace.FileSystemProvider.scanProjectFiles(URI.parse(folder.uri));
460
+ for (const file of files) if (file.isFile && this.isConfigFile(file.uri)) {
461
+ logger$2.debug`found config ${file.uri.fsPath}`;
462
+ configFiles.push(file.uri);
463
+ }
464
+ } catch (error) {
465
+ logger$2.error("Failed to scanProjectFiles, {folder}", {
466
+ folder: folder.uri,
467
+ error
468
+ });
469
+ }
470
+ if (configFiles.length === 0 && this.#projects.length !== 0) logger$2.warning("No config files found, but some projects were registered before");
471
+ configFiles.sort(compareUri);
472
+ this.#projects = [];
473
+ this.#projectIdToFolder.clear();
474
+ this.#lookupById.clear();
475
+ for (const uri of configFiles) {
476
+ if (cancelToken?.isCancellationRequested) break;
477
+ await this.registerConfigFile(uri, cancelToken).catch((error) => {
478
+ if (!isOperationCancelled(error)) logger$2.warn(loggable(error));
479
+ });
480
+ }
481
+ this.reset();
482
+ if (cancelToken?.isCancellationRequested) throw OperationCancelled;
483
+ await this.services.workspace.WorkspaceManager.rebuildAll(cancelToken);
484
+ }
485
+ uniqueProjectId(name) {
486
+ let id = name;
487
+ let i = 1;
488
+ while (this.#projectIdToFolder.has(id)) id = `${name}-${i++}`;
489
+ return id;
490
+ }
491
+ reset() {
492
+ logger$2.debug("reset");
493
+ this.#defaultProject = void 0;
494
+ if (this.#defaultProjectId && !this.#projectIdToFolder.has(this.#defaultProjectId)) this.#defaultProjectId = void 0;
495
+ this.services.workspace.LangiumDocuments.resetProjectIds();
496
+ this.documentBelongsTo.clear();
497
+ this.mappingsToProject.clear();
498
+ this.#lookupById.clear();
499
+ this.#excludedDocuments = /* @__PURE__ */ new WeakMap();
500
+ }
501
+ async rebuidProject(projectId, cancelToken) {
502
+ this.#defaultProject = void 0;
503
+ const project = this.#projects.find((p) => p.id === projectId) ?? this.default;
504
+ if (project.id !== projectId) logger$2.warn`Project ${projectId} not found, rebuilding default project ${project.id}`;
505
+ const log = logger$2.getChild(project.id);
506
+ const folder = project.folder;
507
+ const includePaths = project.includePaths;
508
+ const allDocs = this.services.workspace.LangiumDocuments.allKnownDocuments.filter((doc) => !isLikeC4Builtin(doc.uri)).toArray();
509
+ if (allDocs.length === 0) return;
510
+ const docs = t$2(allDocs, n((doc) => {
511
+ if (project.exclude?.(doc.uri.path)) return false;
512
+ const docUriStr = normalizeUri(doc.uri);
513
+ if (docUriStr.startsWith(folder)) return true;
514
+ if (includePaths && includePaths.some(isParentFolderFor(docUriStr))) return true;
515
+ const docdir = withTrailingSlash(joinRelativeURL(docUriStr, ".."));
516
+ return docdir.startsWith(folder) || folder.startsWith(docdir);
517
+ }), t$1((d) => d.uri));
518
+ if (docs.length === 0) {
519
+ log.debug("no documents in project, skipping rebuild");
520
+ return;
521
+ }
522
+ log.info("rebuild project documents: {docs}", { docs: docs.length });
523
+ this.reset();
524
+ await this.services.workspace.DocumentBuilder.update(docs, [], cancelToken).catch((error) => {
525
+ log.warn("Failed to rebuild project", { error });
526
+ });
527
+ }
528
+ findProjectForDocument(documentUri) {
529
+ return this.mappingsToProject.get(documentUri, () => {
530
+ const hasThisDoc = isParentFolderFor(documentUri);
531
+ const project = this.#projects.find(hasThisDoc);
532
+ if (project) return project;
533
+ return this.#projects.find(({ includePaths }) => {
534
+ return !!includePaths && includePaths.some(hasThisDoc);
535
+ }) ?? this.default;
536
+ });
537
+ }
538
+ get mappingsToProject() {
539
+ return memoizeProp(this, "_mappingsToProject", () => new WorkspaceCache(this.services));
540
+ }
541
+ /**
542
+ * The mapping between documents and projects they belong to.
543
+ * Lazy-created due to initialization order of the LanguageServer
544
+ */
545
+ get documentBelongsTo() {
546
+ return memoizeProp(this, "_documentBelongsTo", () => new WorkspaceCache(this.services));
547
+ }
548
+ /**
549
+ * Returns all include paths from all projects.
550
+ * Used by WorkspaceManager to scan additional directories for C4 files.
551
+ */
552
+ getAllIncludePaths() {
553
+ const result = [];
554
+ for (const project of this.#projects) if (project.includePaths) for (const includePath of project.includePaths) result.push({
555
+ projectId: project.id,
556
+ includePath: includePath.uri,
557
+ includeConfig: project.includeConfig
558
+ });
559
+ return result;
560
+ }
561
+ /**
562
+ * Register a listener to be called when the projects configuration has changed.
563
+ * @returns A disposable that can be used to unregister the callback.
564
+ */
565
+ onProjectsUpdate(callback) {
566
+ this.#updateListeners.push(callback);
567
+ return Disposable.create(() => {
568
+ const index = this.#updateListeners.indexOf(callback);
569
+ if (index >= 0) this.#updateListeners.splice(index, 1);
570
+ });
571
+ }
572
+ getWorkspaceFolder() {
573
+ try {
574
+ return this.services.workspace.WorkspaceManager.workspaceUri;
575
+ } catch (error) {
576
+ logger$2.warn("Failed to get workspace URI, using default folder", { error });
577
+ return URI.file("/");
578
+ }
579
+ }
580
+ notifyListeners() {
581
+ for (const listener of this.#updateListeners) try {
582
+ listener();
583
+ } catch (e) {
584
+ logger$2.warn(loggable(e));
585
+ }
586
+ }
587
+ };
588
+
589
+ //#endregion
590
+ //#region src/LikeC4LanguageServices.ts
591
+ const logger$1 = logger$3.getChild("LanguageServices");
592
+ /**
593
+ * Public Language Services
594
+ */
595
+ var DefaultLikeC4LanguageServices = class {
596
+ builder;
597
+ editor;
598
+ projectsManager;
599
+ constructor(services) {
600
+ this.services = services;
601
+ this.builder = services.likec4.ModelBuilder;
602
+ this.projectsManager = services.shared.workspace.ProjectsManager;
603
+ this.editor = services.likec4.ModelChanges;
604
+ }
605
+ get views() {
606
+ return this.services.likec4.Views;
607
+ }
608
+ get workspaceUri() {
609
+ return this.services.shared.workspace.WorkspaceManager.workspaceUri;
610
+ }
611
+ projects() {
612
+ const projectsManager = this.services.shared.workspace.ProjectsManager;
613
+ const projectsWithDocs = t$2(this.services.shared.workspace.LangiumDocuments.groupedByProject(), t$4(), t$1(([projectId, docs]) => {
614
+ const id = projectId;
615
+ const { folderUri, config } = projectsManager.getProject(id);
616
+ return {
617
+ id,
618
+ folder: folderUri,
619
+ title: config.title ?? config.name,
620
+ documents: t$1(docs, e("uri")),
621
+ config
622
+ };
623
+ }));
624
+ if (t(projectsWithDocs, 2) && projectsManager.defaultProjectId) {
625
+ const idx = projectsWithDocs.findIndex((p) => p.id === projectsManager.defaultProjectId);
626
+ if (idx > 0) {
627
+ const [defaultProject] = projectsWithDocs.splice(idx, 1);
628
+ return [defaultProject, ...projectsWithDocs];
629
+ }
630
+ return projectsWithDocs;
631
+ }
632
+ if (t(projectsWithDocs, 1)) return projectsWithDocs;
633
+ const { folderUri, config } = projectsManager.getProject(ProjectsManager.DefaultProjectId);
634
+ const documents = t$1(this.services.shared.workspace.LangiumDocuments.projectDocuments(ProjectsManager.DefaultProjectId).toArray(), e("uri"));
635
+ return [{
636
+ id: ProjectsManager.DefaultProjectId,
637
+ folder: folderUri,
638
+ title: config.title ?? config.name,
639
+ documents,
640
+ config
641
+ }];
642
+ }
643
+ project(projectId) {
644
+ projectId = this.projectsManager.ensureProjectId(projectId);
645
+ const { folderUri, config } = this.services.shared.workspace.ProjectsManager.getProject(projectId);
646
+ const documents = t$1(this.services.shared.workspace.LangiumDocuments.projectDocuments(projectId).toArray(), e("uri"));
647
+ return {
648
+ id: projectId,
649
+ folder: folderUri,
650
+ title: config.title ?? config.name,
651
+ documents,
652
+ config
653
+ };
654
+ }
655
+ async diagrams(project, cancelToken) {
656
+ const projectId = this.projectsManager.ensureProjectId(project);
657
+ return await this.views.diagrams(projectId, cancelToken);
658
+ }
659
+ async computedModel(project, cancelToken) {
660
+ const projectId = this.projectsManager.ensureProjectId(project);
661
+ return await this.builder.computeModel(projectId, cancelToken);
662
+ }
663
+ async layoutedModel(project, cancelToken) {
664
+ const projectId = this.projectsManager.ensureProjectId(project);
665
+ const model = await this.builder.computeModel(projectId, cancelToken);
666
+ if (!model) throw new Error("Failed to compute model, empty project?");
667
+ const layouted = await this.views.layoutAllViews(projectId, cancelToken);
668
+ return LikeC4Model.create({
669
+ ...model.$data,
670
+ _stage: "layouted",
671
+ views: t$2(layouted, t$1(e("diagram")), t$5(e("id")))
672
+ });
673
+ }
674
+ async projectsOverview(cancelToken) {
675
+ const allProjects = this.services.shared.workspace.ProjectsManager.all;
676
+ const models = [];
677
+ for (const project of allProjects) {
678
+ const model = await this.builder.computeModel(project, cancelToken);
679
+ if (cancelToken?.isCancellationRequested) throw new Error("Operation cancelled");
680
+ if (model === LikeC4Model.EMPTY) {
681
+ logger$1.debug(`Project ${project} is empty, skipping`);
682
+ continue;
683
+ }
684
+ models.push(model);
685
+ }
686
+ if (!t(models, 1)) throw new Error("No models found");
687
+ const projectsView = computeProjectsView(models);
688
+ return await this.views.layouter.layoutProjectsView(projectsView);
689
+ }
690
+ getErrors() {
691
+ return this.services.shared.workspace.LangiumDocuments.allExcludingBuiltin.toArray().flatMap((doc) => {
692
+ return (doc.diagnostics ?? []).filter((d) => d.severity === DiagnosticSeverity.Error).map(({ message, range }) => ({
693
+ message,
694
+ line: range.start.line,
695
+ range,
696
+ sourceFsPath: doc.uri.fsPath
697
+ }));
698
+ });
699
+ }
700
+ locate(params) {
701
+ switch (true) {
702
+ case "element" in params: return this.services.likec4.ModelLocator.locateElement(params.element, params.projectId);
703
+ case "relation" in params: return this.services.likec4.ModelLocator.locateRelation(params.relation, params.projectId);
704
+ case "view" in params: return this.services.likec4.ModelLocator.locateView(params.view, params.projectId);
705
+ case "deployment" in params: return this.services.likec4.ModelLocator.locateDeploymentElement(params.deployment, params.projectId);
706
+ default: nonexhaustive$1(params);
707
+ }
708
+ }
709
+ async dispose() {
710
+ try {
711
+ logger$1.debug("disposing LikeC4LanguageServices");
712
+ await this.services.shared.workspace.FileSystemWatcher.dispose();
713
+ if (this.services.mcp.Server.isStarted) await this.services.mcp.Server.stop();
714
+ this.services.Rpc.dispose();
715
+ this.services.likec4.ModelBuilder.dispose();
716
+ } catch (e) {
717
+ logger$1.error(loggable(e));
718
+ } finally {
719
+ logger$1.debug("LikeC4LanguageServices disposed");
720
+ }
721
+ }
722
+ };
723
+
724
+ //#endregion
725
+ export { logWarnError as a, getTelemetrySink as i, ProjectsManager as n, logger$3 as o, getLspConnectionSink as r, DefaultLikeC4LanguageServices as t };