@likec4/language-server 1.52.0 → 1.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/LikeC4FileSystem.mjs +2 -2
- package/dist/_chunks/mcp.mjs +15 -15
- package/dist/_chunks/module.d.mts +79 -8
- package/dist/_chunks/module.mjs +20 -20
- package/dist/_chunks/noop.mjs +1 -1
- package/dist/_chunks/noop2.mjs +1 -0
- package/dist/_chunks/protocol.d.mts +10 -3
- package/dist/_chunks/utils.mjs +1 -1
- package/dist/browser/index.mjs +1 -1
- package/dist/browser/worker.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/mcp/index.mjs +1 -1
- package/dist/module.mjs +1 -1
- package/package.json +20 -18
- package/dist/_chunks/workspace.mjs +0 -1
package/dist/browser/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_chunks/likec4lib.mjs";import{n as e,r as t,t as n}from"../_chunks/noop.mjs";import"../_chunks/utils.mjs";import{
|
|
1
|
+
import"../_chunks/likec4lib.mjs";import{n as e,r as t,t as n}from"../_chunks/noop.mjs";import"../_chunks/utils.mjs";import{t as r}from"../_chunks/module.mjs";import{t as i}from"../_chunks/noop2.mjs";import"../_chunks/common-exports.mjs";import{configureLogger as a,getConsoleSink as o,getTextFormatter as s}from"@likec4/log";import{startLanguageServer as c}from"langium/lsp";import{BrowserMessageReader as l,BrowserMessageWriter as u,createConnection as d}from"vscode-languageserver/browser";function startLanguageServer(e){let t=d(new l(e),new u(e));a({sinks:{console:o({formatter:s({format:({level:e,category:t,message:n})=>`${e} ${t} ${n}`})})},loggers:[{category:`likec4`,sinks:[`console`],lowestLevel:`debug`}]});let n=r({connection:t});return c(n.shared),n}export{n as NoFileSystem,e as NoFileSystemWatcher,t as NoLikeC4ManualLayouts,i as NoMCPServer,r as createLanguageServices,startLanguageServer};
|
package/dist/browser/worker.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_chunks/likec4lib.mjs";import"../_chunks/noop.mjs";import"../_chunks/utils.mjs";import"../_chunks/
|
|
1
|
+
import"../_chunks/likec4lib.mjs";import"../_chunks/noop.mjs";import"../_chunks/utils.mjs";import"../_chunks/module.mjs";import"../_chunks/noop2.mjs";import"../_chunks/common-exports.mjs";import{startLanguageServer as e}from"./index.mjs";function errToString(e){switch(!0){case e instanceof Error:return e.message;case typeof e==`object`&&!!e:try{return JSON.stringify(e)}catch{return`[unserializable value]`}case typeof e==`string`:return e;case e==null:return``;case typeof e==`number`||typeof e==`boolean`:return String(e);case typeof e==`symbol`:return e.toString();default:return`unknown`}}const log=(e,t)=>{let n=t==null?e:`${e} ${errToString(t)}`;try{console.error(`[LikeC4 LSP worker]`,n)}catch{}};self.onerror=e=>(log(`Uncaught error`,e.message??e.error),!1),self.onunhandledrejection=e=>{log(`Unhandled rejection`,e.reason)};try{e(self)}catch(e){throw log(`Failed to start language server`,e),e}
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./_chunks/likec4lib.mjs";import{n as e,r as t,t as n}from"./_chunks/noop.mjs";import{
|
|
1
|
+
import"./_chunks/likec4lib.mjs";import{n as e,r as t,t as n}from"./_chunks/noop.mjs";import{ii as r,oi as i}from"./_chunks/utils.mjs";import{r as a,t as o}from"./_chunks/LikeC4FileSystem.mjs";import{i as s,t as c}from"./_chunks/module.mjs";import{t as l}from"./_chunks/noop2.mjs";import"./_chunks/common-exports.mjs";import{t as u}from"./_chunks/mcp.mjs";import{configureLogger as d,getAnsiColorFormatter as f,getConsoleSink as p,getConsoleStderrSink as m,getTextFormatter as h}from"@likec4/log";import{isEmpty as g}from"remeda";import{startLanguageServer as _}from"langium/lsp";import{GraphvizWasmAdapter as v,QueueGraphvizLayoter as y}from"@likec4/layouts";import{GraphvizBinaryAdapter as b}from"@likec4/layouts/graphviz/binary";import{defu as x}from"defu";import{isDevelopment as S}from"std-env";import C from"which";function configureLanguageServerLogger({lspConnection:e,enableTelemetry:t=!!e,useStdErr:n=!1,logLevel:a=S?`debug`:`warning`,nonBlocking:o=!1,colors:s=!1}={}){let c=!!e&&t&&!S;d({reset:!0,sinks:{console:n?m({formatter:h()}):p({formatter:s?f():h(),nonBlocking:o}),...c&&{telemetry:r(e)}},loggers:[{category:[`likec4`],sinks:[`console`,...c?[`telemetry`]:[]],lowestLevel:a}]}),i.trace(`logger configured`)}function graphvizBinPath(){try{return C.sync(`dot`)}catch(e){return i.error(`Error checking for native Graphviz:`,{error:e}),null}}const w={likec4:{Layouter(e){i.debug(`Creating ConfigurableLayouter`);let t=e.likec4.Graphviz,n=new y({graphviz:t});return e.shared.workspace.ConfigurationProvider.onConfigurationSectionUpdate(t=>{if(i.debug(`Configuration update: {update}`,{update:t}),t.section!==e.LanguageMetaData.languageId){i.debug(`Ignoring configuration update as it is not for ${e.LanguageMetaData.languageId}`);return}try{let{mode:r,path:a}=t.configuration.graphviz??{mode:`wasm`,path:``};if(r!==`wasm`){let t=g(a)?graphvizBinPath():a;if(!g(t)){n.changePort(new b(t)),i.info`use graphviz binary: ${t}`;return}i.warn(`No Graphviz binaries found on PATH, use graphviz wasm`),e.shared.lsp.Connection?.window.showWarningMessage(`No Graphviz binaries found on PATH, set path to binaries in settings.`)}n.changePort(new v),i.info(`use graphviz wasm`)}catch(e){i.error(`Failed to update configuration`,{error:e})}}),n}}};function startLanguageServer(e){let t=e?.connection,n=x(e,{enableWatcher:!0,enableMCP:`sse`,enableManualLayouts:!0,graphviz:`wasm`,configureLogger:!1});n.configureLogger!==!1&&(n.configureLogger===`stderr`||n.enableMCP===`stdio`?configureLanguageServerLogger({lspConnection:t,enableTelemetry:!1,useStdErr:!0}):n.configureLogger===`console`&&configureLanguageServerLogger({lspConnection:t})),t?i.info(`Starting LikeC4 language server`):i.warn(`Starting LikeC4 language server (headless - no LSP connection)`);let r=c({...t&&{connection:t},...o(n.enableWatcher),...!!n.enableMCP&&u(n.enableMCP),...n.enableManualLayouts&&a,...s(n.graphviz===`binary`?new b:new v)},t?{likec4:{...w.likec4}}:void 0);return _(r.shared),r}export{n as NoFileSystem,e as NoFileSystemWatcher,t as NoLikeC4ManualLayouts,l as NoMCPServer,o as WithFileSystem,a as WithLikeC4ManualLayouts,u as WithMCPServer,configureLanguageServerLogger,c as createLanguageServices,startLanguageServer};
|
package/dist/mcp/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_chunks/likec4lib.mjs";import"../_chunks/utils.mjs";import{
|
|
1
|
+
import"../_chunks/likec4lib.mjs";import"../_chunks/utils.mjs";import{t as e}from"../_chunks/noop2.mjs";import{t}from"../_chunks/mcp.mjs";export{e as NoMCPServer,t as WithMCPServer};
|
package/dist/module.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./_chunks/likec4lib.mjs";import{r as e,t}from"./_chunks/noop.mjs";import"./_chunks/utils.mjs";import{
|
|
1
|
+
import"./_chunks/likec4lib.mjs";import{r as e,t}from"./_chunks/noop.mjs";import"./_chunks/utils.mjs";import{a as n,i as r,n as i,r as a,t as o}from"./_chunks/module.mjs";import{t as s}from"./_chunks/noop2.mjs";export{t as NoFileSystem,e as NoLikeC4ManualLayouts,s as NoMCPServer,r as WithGraphviz,n as WithWasmGraphviz,o as createLanguageServices,i as createLikeC4Module,a as createSharedServices};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@likec4/language-server",
|
|
3
3
|
"description": "LikeC4 Language Server",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.53.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bugs": "https://github.com/likec4/likec4/issues",
|
|
7
7
|
"homepage": "https://likec4.dev",
|
|
@@ -117,18 +117,19 @@
|
|
|
117
117
|
},
|
|
118
118
|
"dependencies": {
|
|
119
119
|
"@hono/mcp": "^0.2.4",
|
|
120
|
-
"@hono/node-server": "^1.19.
|
|
121
|
-
"@hpcc-js/wasm-graphviz": "1.21.
|
|
120
|
+
"@hono/node-server": "^1.19.11",
|
|
121
|
+
"@hpcc-js/wasm-graphviz": "1.21.2",
|
|
122
122
|
"chokidar": "^5.0.0",
|
|
123
123
|
"defu": "^6.1.4",
|
|
124
124
|
"fast-equals": "^6.0.0",
|
|
125
125
|
"fdir": "6.4.0",
|
|
126
|
-
"hono": "^4.12.
|
|
126
|
+
"hono": "^4.12.8",
|
|
127
127
|
"immer": "^11.1.4",
|
|
128
128
|
"indent-string": "^5.0.0",
|
|
129
129
|
"json5": "^2.2.3",
|
|
130
130
|
"langium": "3.5.0",
|
|
131
131
|
"nano-spawn": "^2.0.0",
|
|
132
|
+
"p-limit": "7.3.0",
|
|
132
133
|
"p-queue": "8.1.1",
|
|
133
134
|
"picomatch": "^4.0.3",
|
|
134
135
|
"pretty-ms": "^9.3.0",
|
|
@@ -137,23 +138,24 @@
|
|
|
137
138
|
"strip-indent": "^4.1.1",
|
|
138
139
|
"type-fest": "^4.41.0",
|
|
139
140
|
"ufo": "1.6.3",
|
|
141
|
+
"unstorage": "^1.17.4",
|
|
140
142
|
"vscode-jsonrpc": "8.2.1",
|
|
143
|
+
"vscode-languageserver": "9.0.1",
|
|
141
144
|
"vscode-languageserver-protocol": "3.17.5",
|
|
142
145
|
"vscode-languageserver-textdocument": "1.0.11",
|
|
143
146
|
"vscode-languageserver-types": "3.17.5",
|
|
144
|
-
"vscode-languageserver": "9.0.1",
|
|
145
147
|
"vscode-uri": "3.1.0",
|
|
146
148
|
"which": "^5.0.0",
|
|
147
149
|
"zod": "^3.25.76",
|
|
148
|
-
"@likec4/
|
|
149
|
-
"@likec4/
|
|
150
|
-
"@likec4/
|
|
151
|
-
"@likec4/log": "1.
|
|
150
|
+
"@likec4/core": "1.53.0",
|
|
151
|
+
"@likec4/layouts": "1.53.0",
|
|
152
|
+
"@likec4/config": "1.53.0",
|
|
153
|
+
"@likec4/log": "1.53.0"
|
|
152
154
|
},
|
|
153
155
|
"peerDependencies": {
|
|
154
156
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
155
157
|
"bundle-require": "^5.1.0",
|
|
156
|
-
"esbuild": "0.27.
|
|
158
|
+
"esbuild": "0.27.4"
|
|
157
159
|
},
|
|
158
160
|
"peerDependenciesMeta": {
|
|
159
161
|
"esbuild": {
|
|
@@ -169,22 +171,22 @@
|
|
|
169
171
|
"devDependencies": {
|
|
170
172
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
171
173
|
"@types/natural-compare-lite": "^1.4.2",
|
|
172
|
-
"@types/node": "~22.19.
|
|
174
|
+
"@types/node": "~22.19.15",
|
|
173
175
|
"@types/picomatch": "^4.0.2",
|
|
174
176
|
"@types/vscode": "^1.106.1",
|
|
175
177
|
"@types/which": "^3.0.4",
|
|
176
178
|
"bundle-require": "^5.1.0",
|
|
177
|
-
"esbuild": "0.27.
|
|
179
|
+
"esbuild": "0.27.4",
|
|
178
180
|
"langium-cli": "3.5.2",
|
|
179
|
-
"obuild": "
|
|
180
|
-
"oxlint": "1.
|
|
181
|
+
"obuild": "0.4.31",
|
|
182
|
+
"oxlint": "1.55.0",
|
|
181
183
|
"tsx": "4.21.0",
|
|
182
|
-
"turbo": "2.8.
|
|
184
|
+
"turbo": "2.8.17",
|
|
183
185
|
"typescript": "5.9.3",
|
|
184
|
-
"vitest": "4.0
|
|
186
|
+
"vitest": "4.1.0",
|
|
185
187
|
"@likec4/devops": "1.42.0",
|
|
186
|
-
"@likec4/
|
|
187
|
-
"@likec4/
|
|
188
|
+
"@likec4/icons": "1.46.4",
|
|
189
|
+
"@likec4/tsconfig": "1.53.0"
|
|
188
190
|
},
|
|
189
191
|
"scripts": {
|
|
190
192
|
"typecheck": "tsc -b --verbose",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as e,i as t,n,r}from"./likec4lib.mjs";import{B as i,Bt as a,Ct as o,H as s,Hn as c,I as ee,J as te,Kt as l,N as u,Tr as d,Tt as f,U as ne,V as p,X as re,at as ie,cn as ae,en as oe,ln as se,mt as ce,n as le,nr as ue,nt as m,o as de,qt as h,sn as g,ut as _,wr as v,yt as y,z as b}from"./utils.mjs";import{AstUtils as x,DefaultAstNodeDescriptionProvider as fe,DefaultIndexManager as pe,DefaultLangiumDocuments as me,DefaultWorkspaceManager as he,Disposable as S,URI as C,UriUtils as w,isAstNode as ge,isOperationCancelled as T,stream as E}from"langium";import{DefaultMap as D,compareNaturalHierarchically as O,invariant as k,isString as A,nonNullable as j,nonexhaustive as M,stringHash as N}from"@likec4/core/utils";import{loggable as P,wrapError as F}from"@likec4/log";import{clamp as I,find as L,groupBy as _e,hasAtLeast as R,isEmptyish as z,isNullish as B,isTruthy as ve,map as V,pipe as ye,prop as H,purry as U,uniqueBy as be}from"remeda";import{invariant as W}from"@likec4/core";import{LikeC4ProjectConfigOps as G}from"@likec4/config";import K from"picomatch";import{cleanDoubleSlashes as xe,hasProtocol as Se,isRelative as Ce,joinRelativeURL as we,joinURL as Te,withTrailingSlash as Ee,withoutProtocol as q,withoutTrailingSlash as J}from"ufo";import De from"pretty-ms";import{URI as Y}from"vscode-uri";const X=Symbol.for(`idattr`),Oe={writeId(e,t){return e[X]=t,e},readId(e){return e[X]}},ke={writeId(e,t){return B(t)?e[X]=void 0:e[X]=t,e},readId(e){return e[X]}};function isLikeC4LangiumDocument(e){return e?.textDocument.languageId===de.languageId}function parseMarkdownAsString(e){return e?.markdown||e?.text}function parseAstPercent(e){let t=parseFloat(e);return isNaN(t)?100:I(t,{min:0,max:100})}function parseAstOpacityProperty({value:e}){return parseAstPercent(e)}function parseAstSizeValue({value:e}){switch(e){case`xs`:case`sm`:case`md`:case`lg`:case`xl`:return e;case`xsmall`:return`xs`;case`small`:return`sm`;case`medium`:return`md`;case`large`:return`lg`;case`xlarge`:return`xl`;default:M(e)}}function parseAstIconPositionValue({value:e}){switch(e){case`left`:case`right`:case`top`:case`bottom`:return e;default:M(e)}}function toRelationshipStyle(e,t){let n={};if(!e||e.length===0)return n;for(let r of e)if(t(r))switch(!0){case ee(r):{let e=toColor(r);ve(e)&&(n.color=e);break}case oe(r):n.line=r.value;break;case u(r):switch(r.key){case`head`:n.head=r.value;break;case`tail`:n.tail=r.value;break;default:M(r)}break;default:M(r)}return n}function toColor(e){return e?.themeColor??e?.customColor?.$refText}function toAutoLayout(e){let t=e.rankSep,n=e.nodeSep,r;switch(e.direction){case`TopBottom`:r=`TB`;break;case`BottomTop`:r=`BT`;break;case`LeftRight`:r=`LR`;break;case`RightLeft`:r=`RL`;break;default:M(e.direction)}return{direction:r,...n&&{nodeSep:n},...t&&{rankSep:t}}}function toAstViewLayoutDirection(e){switch(e){case`TB`:return`TopBottom`;case`BT`:return`BottomTop`;case`LR`:return`LeftRight`;case`RL`:return`RightLeft`;default:M(e)}}function getViewRulePredicateContainer(e){return x.getContainerOfType(e,e=>ue(e)||re(e)||ie(e))}const _isModel=e=>g(e)||_(e)||f(e)||y(e)||m(e)||ce(e),_isDeployment=e=>ae(e)||te(e)||ne(e)||o(e)||i(e);function isFqnRefInsideGlobals(e){for(;;){if(_isDeployment(e)||_isModel(e))return!1;if(a(e)||se(e))return!0;if(e.$container)e=e.$container;else return!1}}function isFqnRefInsideModel(e){for(;;){if(_isDeployment(e))return!1;if(_isModel(e))return!0;if(e.$container)e=e.$container;else return!1}}function isFqnRefInsideDeployment(e){for(;;){if(_isModel(e))return!1;if(_isDeployment(e))return!0;if(e.$container)e=e.$container;else return!1}}const Ae={mcpServer:()=>new NoopLikeC4MCPServer,mcpServerFactory:()=>new NoopLikeC4MCPServerFactory};var NoopLikeC4MCPServer=class{get mcp(){throw Error(`NoopLikeC4MCPServer does not have a McpServer`)}get isStarted(){return!1}get port(){return NaN}start(){return Promise.resolve()}stop(){return Promise.resolve()}},NoopLikeC4MCPServerFactory=class{create(e){throw Error(`NoopLikeC4MCPServerFactory`)}},AstNodeDescriptionProvider=class extends fe{constructor(e){super(e),this.services=e}createDescription(e,t,n){n??=x.getDocument(e);let i=super.createDescription(e,t,n);return r(n.uri)||(n.likec4ProjectId??=this.services.shared.workspace.ProjectsManager.ownerProjectId(n),i.likec4ProjectId=n.likec4ProjectId),i}},IndexManager=class extends pe{constructor(e){super(e),this.services=e}async updateContent(e,t){e.likec4ProjectId=this.services.workspace.ProjectsManager.ownerProjectId(e),await super.updateContent(e,t)}projectElements(e,t,n){let r=this.services.workspace.ProjectsManager;return E(this.symbolIndex.keys()).filter(t=>n&&!n.has(t)?!1:r.isIncluded(e,t)).flatMap(e=>this.getFileDescriptions(e,t))}};const je=O(`/`),ensureOrder=(e,t)=>je(e.uri.path,t.uri.path),isLikeC4UserDocument=e=>isLikeC4LangiumDocument(e)&&t(e);var LangiumDocuments=class extends me{constructor(e){super(e),this.services=e}get projectsManager(){return this.services.workspace.ProjectsManager}addDocument(e){let t=e.uri.toString();if(this.documentMap.has(t))throw Error(`A document with the URI '${t}' is already present.`);let n=[...this.documentMap.values(),e].sort(ensureOrder);this.documentMap.clear();for(let e of n)this.documentMap.set(e.uri.toString(),e);isLikeC4UserDocument(e)&&(e.likec4ProjectId=this.projectsManager.ownerProjectId(e))}getDocument(e){let t=super.getDocument(e);return isLikeC4UserDocument(t)&&(t.likec4ProjectId=this.projectsManager.ownerProjectId(t)),t}get userDocuments(){return E(this.documentMap.values()).filter(e=>isLikeC4UserDocument(e)&&!this.projectsManager.isExcluded(e))}get all(){return E(this.documentMap.values()).map(e=>(isLikeC4UserDocument(e)&&(e.likec4ProjectId=this.projectsManager.ownerProjectId(e)),e))}projectDocuments(e){let t=this.services.workspace.ProjectsManager;return E(this.documentMap.values()).filter(n=>isLikeC4UserDocument(n)&&t.isIncluded(e,n)?(n.likec4ProjectId=e,!0):!1)}groupedByProject(){let e=this.services.workspace.ProjectsManager;return ye(this.userDocuments.toArray(),V(t=>(t.likec4ProjectId=e.ownerProjectId(t),t)),_e(H(`likec4ProjectId`)))}resetProjectIds(){let e=[];for(let t of this.documentMap.values())delete t.likec4ProjectId,isLikeC4UserDocument(t)&&!this.projectsManager.isExcluded(t)&&e.push(t.uri);return e}},ADisposable=class{toDispose=[];isDisposed=!1;onDispose(...e){this.toDispose.push(...e)}dispose(){this.throwIfDisposed(),this.isDisposed=!0;let e;for(;e=this.toDispose.pop();)try{e.dispose()}catch(e){v(e)}}throwIfDisposed(){if(this.isDisposed)throw Error(`This has already been disposed`)}};function elementRef(e){try{let t=c(e)?e.el.ref:e.modelElement.value.ref;return t?.$type===`Imported`&&(t=t.imported.ref),t?.$type===`Element`?t:void 0}catch{return}}function readStrictFqn(e){let t=[e.$type===`StrictFqnRef`?e.value.$refText:e.el.$refText],n=e.parent;for(;n;)t.push(n.$type===`StrictFqnRef`?n.value.$refText:n.el.$refText),n=n.parent;return t.length===1?t[0]:t.reverse().join(`.`)}function referenceableParent(e){for(;e.parent;)e=e.parent;return e.value.ref??null}function instanceRef(e){let t;for(;t=e.value?.ref;){if(s(t))return null;if(b(t))return t;if(B(e.parent))return null;e=e.parent}return null}function importsRef(e){let t=referenceableParent(e);return t?.$type===`Imported`?t:null}function isReferenceToDeploymentModel(e){let t;for(;t=e.value?.ref;){if(p(t))return!0;if(B(e.parent))return!1;e=e.parent}return!1}function projectIdFrom(e){if(l(e)){for(;e.$type===`Imported`&&e.$container;)e=e.$container;W(h(e))}if(h(e))return e.project;let t=ge(e)?x.getDocument(e):e;return t.likec4ProjectId?t.likec4ProjectId:(d.warn`Document ${t.uri.fsPath} does not have a project ID assigned, this may lead to unexpected behavior.`,$.DefaultProjectId)}function stringHash$1(...e){return N(e.length>1?e.join(`:::`):e[0])}function safeCall(e){try{return e()}catch(e){d.trace(`Safe call failed`,{error:e});return}}function performanceNow(){try{return globalThis.performance.now()}catch{return Date.now()}}function performanceMark(){let e=performanceNow();return{get ms(){return performanceNow()-e},get pretty(){return De(performanceNow()-e)}}}const Z=d.getChild(`projects`);function isLangiumDocument(e){return typeof e==`object`&&`uri`in e&&`textDocument`in e}function normalizeUri(e){return isLangiumDocument(e)?e.uri.toString():typeof e==`string`?Se(e,{acceptRelative:!1,strict:!0})?e:C.file(e).toString():e.toString()}const Me=O(`/`,!0),compareUri=(e,t)=>Me(J(e.path),J(t.path));function isParentFolderFor(e){return t=>e.startsWith(A(t)?t:t.folder)}function _overlaps(e,t){let n=A(e)?e:e.folder,r=A(t)?t:t.folder;return n.startsWith(r)||r.startsWith(n)}function overlaps(...e){return U(_overlaps,e)}function _includes(e,t){return t.startsWith(e.folder)||e.includePaths?.some(isParentFolderFor(t))?!_excludes(e,t):!1}function _excludes(e,t){return e.exclude?.(q(t))??!1}function includes(...e){return U(_includes,e)}function excludes(...e){return U(_excludes,e)}function ProjectFolder(e){return e=normalizeUri(e),Ee(e)}const compareProjectByFolder=(e,t)=>compareUri(e.folderUri,t.folderUri);function ensureProjectsOrder(e){return e.sort(compareProjectByFolder)}const Q={id:`default`,config:{name:`default`,exclude:[`**/node_modules/**`]},exclude:K(`**/node_modules/**`,{dot:!0}),includeConfig:{paths:[],maxDepth:3,fileThreshold:30}};function isExcludedByDefault(e){return Q.exclude(q(e))}function parseRegisterOptions(e){if(`configUri`in e){k(!z(e.configUri),`configUri is emptyish`);let t=C.isUri(e.configUri)?e.configUri:C.parse(normalizeUri(e.configUri)),n=ProjectFolder(w.dirname(t));return{configUri:t,folder:n,folderUri:C.parse(n)}}k(!z(e.folderUri),`folderUri is emptyish`);let t=ProjectFolder(e.folderUri),n=C.parse(t);return{configUri:w.joinPath(n,`likec4.config.json`),folder:t,folderUri:n}}var $=class ProjectsManager{static DefaultProjectId=Q.id;#e=[];#t=void 0;#n=[];#r=new D(e=>{if(e===ProjectsManager.DefaultProjectId){let t=this.getWorkspaceFolder(),n=w.joinPath(t,`likec4.config.json`),r=ProjectFolder(t);return{id:e,config:Q.config,folder:r,folderUri:C.parse(r),configUri:n,exclude:Q.exclude,includeConfig:{...Q.includeConfig}}}return j(this.#n.find(t=>t.id===e),`Project ${e} not found`)});#i=new D(e=>{let t=normalizeUri(e),n=this.#a.get(t);return n?excludes(n,t)?!this.#n.some(includes(t)):!1:isExcludedByDefault(t)});#a=new D(e=>{let t=isParentFolderFor(e);return this.#n.find(t)??this.#n.find(includes(e))??null});constructor(e){this.services=e,Z.debug`created`}get defaultProjectId(){if(this.#t)return this.#t;if(!(this.#n.length>1))return R(this.#n,1)?this.#n[0].id:ProjectsManager.DefaultProjectId}set defaultProjectId(e){if(e!==this.#t){if(this.#t=void 0,!e||e===ProjectsManager.DefaultProjectId){Z.debug`reset default project ID`;return}k(this.#n.find(t=>t.id===e),`Project "${e}" not found`),Z.debug`set default project ID to ${e}`,this.#t=e}}get default(){return this.#r.get(this.defaultProjectId??ProjectsManager.DefaultProjectId)}get all(){if(R(this.#n,1)){let e=[...V(this.#n,H(`id`)),Q.id];if(this.#t){let t=e.findIndex(e=>e===this.#t);t>0&&(e.splice(t,1),e.unshift(this.#t))}return e}return[Q.id]}getProject(e){let t=typeof e==`string`?e:e.likec4ProjectId??this.ownerProjectId(e);return this.#r.get(t)}findOverlaped(e){let t=overlaps(ProjectFolder(e));return this.#n.filter(e=>t(e)||!!e.includePaths&&!!L(e.includePaths,t))}ensureProjectId(e){return e===ProjectsManager.DefaultProjectId?this.defaultProjectId??ProjectsManager.DefaultProjectId:e?(k(this.#n.some(t=>e===t.id),`Project ID ${e} is not registered`),e):j(this.defaultProjectId,()=>`Specify exact project, known: [${V(this.#n,H(`id`)).join(`, `)}]`)}ensureProject(e){return e=this.ensureProjectId(e),this.getProject(e)}hasMultipleProjects(){return this.#n.length>1}isExcluded(...e){let t=e.length===1?e[0]:e[1];return isLangiumDocument(t)&&r(t)?!0:e.length===1?this.#i.get(normalizeUri(t)):excludes(this.#r.get(e[0]),normalizeUri(t))}isIncluded(e,t){let n=normalizeUri(t);return R(this.#n,1)?e===ProjectsManager.DefaultProjectId?!this.#a.get(n)&&!isExcludedByDefault(n):includes(this.#r.get(e),normalizeUri(t)):!isExcludedByDefault(n)}async registerConfigFile(e,t){if(isExcludedByDefault(normalizeUri(e)))throw Error(`Failed to register project config, path ${e.fsPath} is excluded by: ${Q.config.exclude.map(e=>`"${e}"`).join(`, `)}`);try{let n=await this.services.workspace.FileSystemProvider.loadProjectConfig(e);return await this.registerProject({config:n,configUri:e},t)}catch(t){if(!T(t))throw F(t,`Failed to register project config ${e.fsPath}:\n`);return Promise.reject(t)}}async registerProject(e,t){let n=G.validate(e.config),{configUri:r,folder:i,folderUri:a}=parseRegisterOptions(e),o=G.normalizeInclude(n.include),s=this.#n.find(e=>e.folder===i);return s?(s.config.name!==n.name&&(Z.info`project name changed from ${s.config.name} to ${n.name}`,Z.info`unregistering ${s.id}`,s.id=this.uniqueProjectId(n.name),Z.info`register ${s.id}`),this.warnIfConfigOverride(s,r),s.config=n,s.folder=i,s.folderUri=a,s.configUri=r,s.includeConfig=o):(s={id:this.uniqueProjectId(n.name),config:n,folder:i,configUri:r,folderUri:a,includeConfig:o},this.#n=ensureProjectsOrder([...this.#n,s]),Z.info`register ${s.id}`),safeCall(()=>this.updateIncludesExcludes(s)),this.#o?s:(this.resetCaches(),this.notifyListeners(),await this.rebuildProject(s.id,t).catch(e=>T(e)?Promise.reject(e):(Z.warn(`Failed to rebuild project {projectId} after config change`,{projectId:s.id,error:e}),Promise.resolve())),s)}ownerProjectId(e){return this.#a.get(normalizeUri(e))?.id??this.#t??ProjectsManager.DefaultProjectId}#o=null;async reloadProjects(e){return this.#o?(Z.debug`reload projects is already in progress, waiting`,await this.#o.catch(()=>{})):(Z.debug`schedule reload projects`,this.#o=Promise.resolve().then(()=>this._reloadProjects(e)).catch(e=>(T(e)||Z.warn(`Failed to reload projects`,{error:e}),Promise.reject(e))).finally(()=>{this.#o=null,this.notifyListeners()}),await this.#o)}async _reloadProjects(e){let t=this.services.workspace.WorkspaceManager.workspaceFolders;if(!t||t.length===0){Z.warn(`Failed to reloadProjects, no workspace folders found`);return}Z.debug`start reload projects`;let n=[];for(let e of t){let t=C.parse(e.uri);Z.debug`scan projects in ${t.fsPath}`;try{let e=await this.services.workspace.FileSystemProvider.scanProjectFiles(t);for(let r of e)Z.debug`found config ${w.relative(t,r.uri)}`,n.push(r.uri)}catch(e){Z.warn(`Failed on scanProjectFiles in {folder}`,{folder:t.fsPath,error:e})}}if(n.length===0){if(this.#n.length===0){Z.warning(`No config files found`);return}Z.warning(`no config files found, but {count} projects were registered before`,{count:this.#n.length}),Z.warning(`reset`)}n.sort(compareUri);let r=new Map(this.#n.map(e=>[e.configUri.toString(),e]));this.#n=[],this.#r.clear();for(let e of n)try{await this.registerConfigFile(e)}catch(t){Z.warn(P(t));let n=r.get(e.toString());n&&(Z.debug`Update failed, restore project ${n.id}`,await this.registerProject(n).catch(e=>{Z.warn(`fail to restore project ${n.id}, ignoring`,{error:e})}))}this.resetCaches(),this.notifyListeners(),await this.services.workspace.WorkspaceManager.rebuildAll(e)}uniqueProjectId(e){let t=new Set(V(this.#n,H(`id`))),n=e;if(!t.has(n))return n;Z.warn`Project "${e}" already exists, generating unique ID`;let r=1;for(;t.has(n);)n=`${e}-${r++}`;return n}resetCaches(){Z.trace(`resetCaches`),this.#t&&!this.#n.some(e=>e.id===this.#t)&&(this.#t=void 0),this.#r.clear(),this.#a.clear(),this.#i.clear()}async rebuildProject(e,t){let n=this.#n.find(t=>t.id===e);if(!n)return e===ProjectsManager.DefaultProjectId?Z.info`Rebuilding all documents `:Z.warn`Project ${e} not found, rebuilding all`,await this.services.workspace.WorkspaceManager.rebuildAll(t);let r=Z.getChild(n.id),i=this.services.workspace.LangiumDocuments.userDocuments.filter(e=>includes(n,normalizeUri(e))).map(e=>e.uri).toArray();if(i.length===0){r.debug`no documents found for project ${n.id}, skipping rebuild`;return}r.info(`rebuild project documents: {docs}`,{docs:i.length}),this.resetCaches(),await this.services.workspace.DocumentBuilder.update(i,[],t).catch(e=>{r.warn(`Failed to rebuild project`,{error:e})})}getAllIncludePaths(){let e=[];for(let t of this.#n)if(t.includePaths)for(let n of t.includePaths)e.push({projectId:t.id,includePath:n.uri,includeConfig:t.includeConfig});return e}onProjectsUpdate(e){return this.#e.push(e),S.create(()=>{let t=this.#e.indexOf(e);t>=0&&this.#e.splice(t,1)})}getWorkspaceFolder(){try{return this.services.workspace.WorkspaceManager.workspaceUri}catch(e){return Z.warn(`Failed to get workspace URI, using default folder`,{error:e}),C.file(`/`)}}notifyListeners(){for(let e of this.#e)try{e()}catch(e){Z.warn(P(e))}}updateIncludesExcludes(e){let t=e.config;switch(delete e.includePaths,delete e.exclude,!0){case B(t.exclude):e.exclude=Q.exclude;break;case t.exclude&&R(t.exclude,1):e.exclude=K(V(t.exclude,t=>(!Ce(t)&&!t.startsWith(`**`)&&(t=Te(`**`,t)),xe(we(e.folderUri.path,t)))),{contains:!0,dot:!0});break}let n=e.includeConfig.paths;if(!R(n,1))return e;e.includePaths=V(n,t=>{let n=w.resolvePath(e.folderUri,t);return{uri:n,folder:ProjectFolder(n)}}),Z.debug`project ${e.id} include paths: ${e.includePaths.map(e=>e.uri.fsPath).join(`, `)}`;for(let t of e.includePaths)for(let n of this.#n)n.id!==e.id&&(overlaps(t,n)&&Z.warn(`Project "{projectId}" include path "{includePath}" overlaps with project "{otherProjectId}" folder. Files in overlapping areas will only belong to one project.`,{projectId:e.id,includePath:t.folder,otherProjectId:n.id}),n.includePaths?.forEach(r=>{overlaps(t,r)&&Z.warn(`Project "{projectId}" include path "{includePath}" overlaps with project "{otherProjectId}" include path "{otherIncludePath}". Files in overlapping areas will only belong to one project.`,{projectId:e.id,includePath:t.folder,otherProjectId:n.id,otherIncludePath:r.folder})}));return e}warnIfConfigOverride(e,t){try{let[n,r]=V([e.configUri,t],w.basename);n!==r&&Z.warn`config ${r} overrides ${n} in folder ${e.folder}`}catch{}}},LikeC4WorkspaceManager=class extends he{documentFactory;fileSystemProvider;#e=[];initialBuildOptions={eagerLinking:!0,validation:!0};constructor(e){super(e),this.services=e,this.documentFactory=e.workspace.LangiumDocumentFactory,this.fileSystemProvider=e.workspace.FileSystemProvider}async performStartup(e){this.folders??=e;let t=[];for(let n of e)try{let e=Y.parse(n.uri),r=await this.fileSystemProvider.scanProjectFiles(e);t.push(...r),this.services.workspace.FileSystemWatcher.watch(e.fsPath)}catch(e){v(e)}let n=this.services.workspace.ProjectsManager;for(let e of t)try{await n.registerConfigFile(e.uri)}catch(e){v(e)}return await super.performStartup(e)}async loadAdditionalDocuments(t,r){r(this.documentFactory.fromString(e,Y.parse(n)));let i=this.services.workspace.ProjectsManager.getAllIncludePaths(),a=0,o=[];for(let{projectId:e,includePath:t,includeConfig:n}of i)try{d.debug`scanning include path ${t.fsPath} for project ${e}`;let r=await this.fileSystemProvider.readDirectory(t,{recursive:!0,maxDepth:n.maxDepth});o.push(...r),r.length===0&&d.debug`loaded ${r.length} files from include path ${t.fsPath}`}catch(e){d.warn(`Failed to scan include path ${t.fsPath}`,{error:e})}for(let e of be(o,e=>e.uri.path))try{r(await this.langiumDocuments.getOrCreateDocument(e.uri)),a++}catch(t){d.warn(`Failed to load document ${e.uri.fsPath}`,{error:t})}if(i.length>0&&a>0){let e=Math.min(...i.map(e=>e.includeConfig.fileThreshold));a>e?d.warn(`Loaded ${a} files from include paths (threshold: ${e}). Large include directories may slow workspace initialization. Consider adjusting "include.fileThreshold" or "include.maxDepth" in your project configuration.`):d.info`loaded ${a} total files from ${i.length} include paths`}}includeEntry(e,t,n){let r=w.basename(t.uri);return t.isDirectory?!le(r):t.isFile?(n.fileExtensions.includes(w.extname(t.uri))||n.fileNames.includes(r))&&!this.services.workspace.ProjectsManager.isExcluded(t.uri):!1}workspace(){return this.folders&&R(this.folders,1)?this.folders[0]:null}async rebuildAll(e){let t=this.services.workspace.LangiumDocuments.resetProjectIds();d.info(`invalidate and rebuild all {docs} documents`,{docs:t.length}),this.forceCleanCaches(),await this.documentBuilder.update(t,[],e)}get workspaceUri(){let e=this.workspace();return W(e,`Workspace not initialized`),Y.parse(e.uri)}get workspaceURL(){let e=this.workspace();return W(e,`Workspace not initialized`),new URL(e.uri)}forceCleanCaches(){for(let e of this.#e)e();this.services.workspace.ManualLayouts.clearCaches(),this.services.workspace.Cache.clear()}onForceCleanCache(e){return this.#e.push(e),S.create(()=>{this.#e=this.#e.filter(t=>t!==e)})}};export{toAstViewLayoutDirection as A,isFqnRefInsideModel as C,parseAstPercent as D,parseAstOpacityProperty as E,toColor as M,toRelationshipStyle as N,parseAstSizeValue as O,isFqnRefInsideGlobals as S,parseAstIconPositionValue as T,NoopLikeC4MCPServer as _,stringHash$1 as a,getViewRulePredicateContainer as b,instanceRef as c,readStrictFqn as d,ADisposable as f,Ae as g,AstNodeDescriptionProvider as h,safeCall as i,toAutoLayout as j,parseMarkdownAsString as k,isReferenceToDeploymentModel as l,IndexManager as m,$ as n,projectIdFrom as o,LangiumDocuments as p,performanceMark as r,importsRef as s,LikeC4WorkspaceManager as t,elementRef as u,ke as v,isLikeC4LangiumDocument as w,isFqnRefInsideDeployment as x,Oe as y};
|