@likec4/language-server 1.49.0 → 1.50.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 (41) hide show
  1. package/dist/_chunks/ConfigurableLayouter.mjs +1 -1
  2. package/dist/_chunks/LikeC4FileSystem.mjs +3 -3
  3. package/dist/_chunks/WithMCPServer.mjs +686 -13
  4. package/dist/_chunks/common-exports.mjs +0 -0
  5. package/dist/_chunks/libs/@msgpack/msgpack.mjs +1 -1
  6. package/dist/_chunks/libs/eventemitter3.mjs +1 -1
  7. package/dist/_chunks/libs/fast-equals.mjs +1 -1
  8. package/dist/_chunks/libs/p-queue.mjs +1 -1
  9. package/dist/_chunks/libs/picomatch.mjs +1 -1
  10. package/dist/_chunks/libs/pretty-ms.mjs +1 -1
  11. package/dist/_chunks/libs/remeda.mjs +2 -1
  12. package/dist/_chunks/libs/ufo.mjs +1 -1
  13. package/dist/_chunks/likec4lib.mjs +2 -0
  14. package/dist/_chunks/{index.d.mts → module.d.mts} +247 -7
  15. package/dist/_chunks/module.mjs +34 -0
  16. package/dist/_chunks/noop.mjs +1 -0
  17. package/dist/_chunks/protocol.d.mts +315 -0
  18. package/dist/_chunks/rolldown-runtime.mjs +1 -1
  19. package/dist/_chunks/utils.mjs +1 -1
  20. package/dist/_chunks/workspace.mjs +1 -0
  21. package/dist/browser/index.d.mts +7 -2
  22. package/dist/browser/index.mjs +1 -1
  23. package/dist/browser/worker.mjs +1 -1
  24. package/dist/bundled.d.mts +2 -2
  25. package/dist/bundled.mjs +1 -1
  26. package/dist/filesystem/index.d.mts +3 -2
  27. package/dist/filesystem/index.mjs +1 -1
  28. package/dist/index.d.mts +2 -38
  29. package/dist/index.mjs +1 -1
  30. package/dist/likec4lib.mjs +1 -1
  31. package/dist/mcp/index.d.mts +3 -2
  32. package/dist/mcp/index.mjs +1 -1
  33. package/dist/module.d.mts +2 -125
  34. package/dist/module.mjs +1 -1
  35. package/dist/protocol.d.mts +1 -314
  36. package/dist/protocol.mjs +1 -1
  37. package/package.json +15 -15
  38. package/dist/_chunks/LikeC4Views.mjs +0 -34
  39. package/dist/_chunks/ProjectsManager.mjs +0 -1
  40. package/dist/_chunks/icons.mjs +0 -2
  41. package/dist/_chunks/logger.mjs +0 -1
@@ -1 +1 @@
1
- import{i as logger}from"./logger.mjs";import{C as e}from"./libs/remeda.mjs";import{GraphvizWasmAdapter,QueueGraphvizLayoter}from"@likec4/layouts";import{GraphvizBinaryAdapter}from"@likec4/layouts/graphviz/binary";import which from"which";function graphvizBinPath(){try{return which.sync(`dot`)}catch(t){return logger.error(`Error checking for native Graphviz:`,{error:t}),null}}const ConfigurableLayouter={likec4:{Layouter(i){logger.debug(`Creating ConfigurableLayouter`);let a=new QueueGraphvizLayoter;return i.shared.workspace.ConfigurationProvider.onConfigurationSectionUpdate(r=>{if(logger.debug(`Configuration update: {update}`,{update:r}),r.section!==i.LanguageMetaData.languageId){logger.debug(`Ignoring configuration update as it is not for ${i.LanguageMetaData.languageId}`);return}try{let{mode:o,path:s}=r.configuration.graphviz??{mode:`wasm`,path:``};if(o!==`wasm`){let n=e(s)?graphvizBinPath():s;if(!e(n)){a.changePort(new GraphvizBinaryAdapter(n)),logger.info`use graphviz binary: ${n}`;return}logger.warn(`No Graphviz binaries found on PATH, use graphviz wasm`),i.shared.lsp.Connection?.window.showWarningMessage(`No Graphviz binaries found on PATH, set path to binaries in settings.`)}a.changePort(new GraphvizWasmAdapter),logger.info(`use graphviz wasm`)}catch(t){logger.error(`Failed to update configuration`,{error:t})}}),a}}};export{ConfigurableLayouter as t};
1
+ import{Er as e}from"./utils.mjs";import{C as t}from"./libs/remeda.mjs";import{GraphvizWasmAdapter as n,QueueGraphvizLayoter as r}from"@likec4/layouts";import{GraphvizBinaryAdapter as i}from"@likec4/layouts/graphviz/binary";import a from"which";function graphvizBinPath(){try{return a.sync(`dot`)}catch(t){return e.error(`Error checking for native Graphviz:`,{error:t}),null}}const o={likec4:{Layouter(a){e.debug(`Creating ConfigurableLayouter`);let o=new r;return a.shared.workspace.ConfigurationProvider.onConfigurationSectionUpdate(r=>{if(e.debug(`Configuration update: {update}`,{update:r}),r.section!==a.LanguageMetaData.languageId){e.debug(`Ignoring configuration update as it is not for ${a.LanguageMetaData.languageId}`);return}try{let{mode:s,path:c}=r.configuration.graphviz??{mode:`wasm`,path:``};if(s!==`wasm`){let n=t(c)?graphvizBinPath():c;if(!t(n)){o.changePort(new i(n)),e.info`use graphviz binary: ${n}`;return}e.warn(`No Graphviz binaries found on PATH, use graphviz wasm`),a.shared.lsp.Connection?.window.showWarningMessage(`No Graphviz binaries found on PATH, set path to binaries in settings.`)}o.changePort(new n),e.info(`use graphviz wasm`)}catch(t){e.error(`Failed to update configuration`,{error:t})}}),o}}};export{o as t};
@@ -1,3 +1,3 @@
1
- import{t as LibIcons}from"./icons.mjs";import{isLikeC4Builtin}from"../likec4lib.mjs";import{n as excludeNodeModules,r as hasLikeC4Ext,t as ensureOrder,wr as NoFileSystemWatcher}from"./utils.mjs";import{i as logger$2}from"./logger.mjs";import{t as PQueue}from"./libs/p-queue.mjs";import{D as t,o as e}from"./libs/remeda.mjs";import{isLikeC4Config,loadConfig}from"@likec4/config/node";import{fdir}from"fdir";import{SimpleCache,URI,UriUtils}from"langium";import{NodeFileSystemProvider}from"langium/node";import{mkdirSync,statSync}from"node:fs";import{unlink,writeFile}from"node:fs/promises";import{basename,dirname}from"node:path";import{objectHash,onNextTick}from"@likec4/core/utils";import chokidar from"chokidar";import JSON5 from"json5";import{Position,Range}from"vscode-languageserver-types";const layoutsLogger=logger$2.getChild(`manual-layouts`),isManualLayoutFile=n=>n.endsWith(`.likec4.snap`);function fileName(n){return`${n}.likec4.snap`}function getManualLayoutsOutDir(n){return UriUtils.resolvePath(n.folderUri,n.config.manualLayouts?.outDir??`.likec4`)}const WithLikeC4ManualLayouts={manualLayouts:n=>new DefaultLikeC4ManualLayouts(n)},RELATIVE_PATH_PREFIX=`file://./`;var DefaultLikeC4ManualLayouts=class{cache;constructor(n){this.services=n,this.cache=new SimpleCache,onNextTick(()=>{n.workspace.ProjectsManager.onProjectsUpdate(()=>{this.clearCaches()})})}async read(n){return await this.cache.get(n.id,async()=>{let r=layoutsLogger.getChild(n.id),i=this.services.workspace.FileSystemProvider,a=getManualLayoutsOutDir(n),o=[];try{let s=await i.scanDirectory(a,isManualLayoutFile);if(s.length===0)return null;for(let a of s)try{let r=await i.readFile(a.uri),s=JSON5.parse(r),c=this.resolveIconPathsAfterRead(s,n.folderUri);o.push({...c,_layout:`manual`})}catch(n){r.warn(`Failed to read view snapshot ${a.uri.fsPath}`,{err:n})}o.length&&r.debug`read manual layouts for ${n.id}, found ${o.length}`}catch(i){r.warn(`Failed to read manual layouts for ${n.folderUri.fsPath}`,{err:i})}if(o.length===0)return null;let s=t(o,e(`id`));return{hash:objectHash(s),views:s}})}async write(n,r){let i=layoutsLogger.getChild(n.id),a=getManualLayoutsOutDir(n),o=UriUtils.joinPath(a,fileName(r.id));if(`manualLayout`in r){let{manualLayout:n,...i}=r;r=i}let s=JSON5.stringify(this.normalizeIconPathsForWrite(r,n.folderUri),{space:2,quote:`'`}),c={uri:o.toString(),range:Range.create(Position.create(0,0),Position.create(s.split(`
2
- `).length-1,1))};i.debug`write snapshot of ${r.id} in project ${n.id} to ${o.fsPath}`;let l=this.services.workspace.FileSystemProvider;try{await l.writeFile(o,s+`
3
- `)}catch(n){i.warn(`Failed to write snapshot ${r.id} to ${o.fsPath}`,{err:n})}return this.cache.delete(n.id),c}async remove(n,r){let i=layoutsLogger.getChild(n.id),a=getManualLayoutsOutDir(n),o=UriUtils.joinPath(a,fileName(r));i.debug`delete snapshot of ${r} in project ${n.id}. File: ${o.fsPath}`;let s={uri:o.toString(),range:Range.create(0,0,0,0)};this.cache.delete(n.id);try{if(!await this.services.workspace.FileSystemProvider.deleteFile(o))return i.warn`Snapshot ${r} did not exist at ${o.fsPath}`,null}catch(n){i.warn(`Failed to delete snapshot ${r} from ${o.fsPath}`,{err:n})}return s}clearCaches(){layoutsLogger.trace`clear caches`,this.cache.clear()}normalizeIconPathsForWrite(n,r){let i=n.nodes.map(n=>{if(!n.icon||typeof n.icon!=`string`)return n;if(n.icon.startsWith(`file://`)){let i=URI.parse(n.icon),a=UriUtils.relative(r,i);return a.startsWith(`..`)?n:{...n,icon:`${RELATIVE_PATH_PREFIX}${a}`}}return n});return{...n,nodes:i}}resolveIconPathsAfterRead(n,r){let i=n.nodes.map(n=>{if(!n.icon||typeof n.icon!=`string`)return n;if(n.icon.startsWith(RELATIVE_PATH_PREFIX)){let i=n.icon.substring(9),a=UriUtils.joinPath(r,i);return{...n,icon:a.toString()}}return n});return{...n,nodes:i}}};const logger$1=logger$2.getChild(`chokidar`),WithChokidarWatcher={fileSystemWatcher:n=>new ChokidarFileSystemWatcher(n)},isAnyLikeC4File=n=>{let r=basename(n);return hasLikeC4Ext(r)||isLikeC4Config(r)||isManualLayoutFile(r)};var ChokidarFileSystemWatcher=class{watcher;queue=new PQueue({concurrency:1,timeout:5e3});constructor(n){this.services=n}watch(n){if(this.watcher){logger$1.debug`add watching folder: ${n}`,this.watcher.add(n);return}this.watcher=this.createWatcher(n)}async dispose(){if(this.watcher){let n=this.watcher;this.watcher=void 0,await n.close()}}createWatcher(n){logger$1.debug`create watcher for folder: ${n}`;let r=chokidar.watch(n,{ignored:[n=>n.includes(`node_modules`)||n.includes(`.git`),(n,r)=>!!r?.isFile()&&!isAnyLikeC4File(n)],followSymlinks:!0,ignoreInitial:!0}),onAddOrChange=(n,r)=>{r?.isDirectory()||this.enqueueFileOp(`addOrChange: `+n,async()=>{await this.onAddOrChange(n)})};return r.on(`add`,onAddOrChange).on(`change`,onAddOrChange).on(`unlink`,(n,r)=>{r?.isDirectory()||this.enqueueFileOp(`remove: `+n,async()=>{await this.onRemove(n)})}).on(`unlinkDir`,n=>{this.enqueueFileOp(`removeDir: `+n,async()=>{await this.onRemoveDir(n)})}),r}enqueueFileOp(n,r){this.queue.add(async()=>{try{await r()}catch(r){logger$1.warn(`Failed on {fileop}`,{fileop:n,error:r})}}).catch(r=>{logger$1.error(`Error on {fileop}`,{fileop:n,error:r})})}async onAddOrChange(n){let r=this.services.workspace,i=basename(n),o=URI.file(n);switch(!0){case isLikeC4Config(i):logger$1.debug`project file changed: ${n}`,r.ManualLayouts.clearCaches(),await r.ProjectsManager.registerConfigFile(o);break;case hasLikeC4Ext(i):logger$1.debug`file changed: ${n}`,await r.DocumentBuilder.update([o],[]);break;case isManualLayoutFile(i):{logger$1.debug`manual layout file changed: ${n}`,r.ManualLayouts.clearCaches();let i=r.ProjectsManager.ownerProjectId(o);await r.ProjectsManager.rebuildProject(i);break}default:logger$1.warn`Unknown file change: ${n}`}}async onRemove(n){let r=this.services.workspace,i=basename(n),o=URI.file(n);switch(!0){case isLikeC4Config(i):logger$1.debug`project file removed: ${n}`,r.ManualLayouts.clearCaches(),await r.ProjectsManager.reloadProjects();break;case hasLikeC4Ext(i):logger$1.debug`file removed: ${n}`,await r.DocumentBuilder.update([],[o]);break;case isManualLayoutFile(i):{logger$1.debug`manual layout file removed: ${n}`;let i=r.ProjectsManager.ownerProjectId(o);r.ManualLayouts.clearCaches(),await r.ProjectsManager.rebuildProject(i);break}default:logger$1.warn`Unknown file removal: ${n}`}}async onRemoveDir(n){logger$1.debug`directory removed: ${n}`;let r=this.services.workspace;r.ProjectsManager.findOverlaped(n).length>0&&(r.ManualLayouts.clearCaches(),await r.ProjectsManager.reloadProjects())}};const logger=logger$2.getChild(`filesystem`);function isLikeC4ConfigFile(n,r=!1){return!r&&isLikeC4Config(basename(n))}function isLikeC4File(n,r=!1){return!r&&hasLikeC4Ext(basename(n))}const WithFileSystem=(n=!0)=>({fileSystemProvider:()=>new SymLinkTraversingFileSystemProvider,...n?WithChokidarWatcher:NoFileSystemWatcher});var SymLinkTraversingFileSystemProvider=class extends NodeFileSystemProvider{async readFile(i){if(isLikeC4Builtin(i))return Promise.resolve(LibIcons);try{return await super.readFile(i)}catch(n){return logger.warn(`Failed to read file ${i.fsPath}`,{error:n}),``}}async readDirectory(n,r){let a=r?.recursive??!0,s=r?.maxDepth??1/0,c=[];try{let r=new fdir().withSymlinks({resolvePaths:!1}).exclude(excludeNodeModules).withFullPaths().filter(isLikeC4File);a?s!==1/0&&(r=r.withMaxDepth(s)):r=r.withMaxDepth(1);let o=await r.crawl(n.fsPath).withPromise();for(let n of o)c.push({isFile:!0,isDirectory:!1,uri:URI.file(n)})}catch(r){logger.warn(`Failed to read directory ${n.fsPath}`,{error:r})}return c.sort(ensureOrder)}async scanProjectFiles(n){return await this.scanDirectory(n,isLikeC4ConfigFile)}async scanDirectory(n,r){let a=[];try{let o=await new fdir().withSymlinks({resolvePaths:!1}).exclude(excludeNodeModules).withFullPaths().filter(r).crawl(n.fsPath).withPromise();for(let n of o)a.push({isFile:!0,isDirectory:!1,uri:URI.file(n)})}catch(r){logger.warn(`Failed to scan directory {path}`,{path:n.fsPath,error:r})}return a}async loadProjectConfig(n){return await loadConfig(n)}async writeFile(n,r){let i=dirname(n.fsPath),a=statSync(i,{throwIfNoEntry:!1});if(a?.isFile())throw Error(`Cannot create directory ${i} because a file with the same name exists.`);return a||(logger.debug(`creating directory {path}`,{path:i}),mkdirSync(i,{recursive:!0})),logger.debug(`writing file {path}`,{path:n.fsPath}),await writeFile(n.fsPath,r,{encoding:`utf-8`})}async deleteFile(n){try{let r=n.fsPath,i=statSync(r,{throwIfNoEntry:!1});return i?.isFile()||i?.isSymbolicLink()?(await unlink(r),logger.debug(`deleted file {path}`,{path:r}),!0):(logger.warn(`deleteFile failed: {path} does not exist, or is not a file`,{path:r}),!1)}catch(r){logger.warn(`Failed to delete file ${n.fsPath}`,{error:r})}return!1}};export{WithChokidarWatcher as n,WithLikeC4ManualLayouts as r,WithFileSystem as t};
1
+ import{a as e,r as t}from"./likec4lib.mjs";import{n}from"./noop.mjs";import{Er as r,n as i,r as a,t as o}from"./utils.mjs";import{t as s}from"./libs/p-queue.mjs";import{D as c,o as l}from"./libs/remeda.mjs";import{isLikeC4Config as u,loadConfig as d}from"@likec4/config/node";import{fdir as f}from"fdir";import{SimpleCache as p,URI as m,UriUtils as h}from"langium";import{NodeFileSystemProvider as g}from"langium/node";import{mkdirSync as _,statSync as v}from"node:fs";import{unlink as y,writeFile as b}from"node:fs/promises";import{basename as x,dirname as S}from"node:path";import{objectHash as C,onNextTick as w}from"@likec4/core/utils";import T from"chokidar";import E from"json5";import{Position as D,Range as O}from"vscode-languageserver-types";const k=r.getChild(`manual-layouts`),isManualLayoutFile=e=>e.endsWith(`.likec4.snap`);function fileName(e){return`${e}.likec4.snap`}function getManualLayoutsOutDir(e){return h.resolvePath(e.folderUri,e.config.manualLayouts?.outDir??`.likec4`)}const A={manualLayouts:e=>new DefaultLikeC4ManualLayouts(e)},j=`file://./`;var DefaultLikeC4ManualLayouts=class{cache;constructor(e){this.services=e,this.cache=new p,w(()=>{e.workspace.ProjectsManager.onProjectsUpdate(()=>{this.clearCaches()})})}async read(e){return await this.cache.get(e.id,async()=>{let t=k.getChild(e.id),n=this.services.workspace.FileSystemProvider,r=getManualLayoutsOutDir(e),i=[];try{let a=await n.scanDirectory(r,isManualLayoutFile);if(a.length===0)return null;for(let r of a)try{let t=await n.readFile(r.uri),a=E.parse(t),o=this.resolveIconPathsAfterRead(a,e.folderUri);i.push({...o,_layout:`manual`})}catch(e){t.warn(`Failed to read view snapshot ${r.uri.fsPath}`,{err:e})}i.length&&t.debug`read manual layouts for ${e.id}, found ${i.length}`}catch(n){t.warn(`Failed to read manual layouts for ${e.folderUri.fsPath}`,{err:n})}if(i.length===0)return null;let a=c(i,l(`id`));return{hash:C(a),views:a}})}async write(e,t){let n=k.getChild(e.id),r=getManualLayoutsOutDir(e),i=h.joinPath(r,fileName(t.id));if(`manualLayout`in t){let{manualLayout:e,...n}=t;t=n}let a=E.stringify(this.normalizeIconPathsForWrite(t,e.folderUri),{space:2,quote:`'`}),o={uri:i.toString(),range:O.create(D.create(0,0),D.create(a.split(`
2
+ `).length-1,1))};n.debug`write snapshot of ${t.id} in project ${e.id} to ${i.fsPath}`;let s=this.services.workspace.FileSystemProvider;try{await s.writeFile(i,a+`
3
+ `)}catch(e){n.warn(`Failed to write snapshot ${t.id} to ${i.fsPath}`,{err:e})}return this.cache.delete(e.id),o}async remove(e,t){let n=k.getChild(e.id),r=getManualLayoutsOutDir(e),i=h.joinPath(r,fileName(t));n.debug`delete snapshot of ${t} in project ${e.id}. File: ${i.fsPath}`;let a={uri:i.toString(),range:O.create(0,0,0,0)};this.cache.delete(e.id);try{if(!await this.services.workspace.FileSystemProvider.deleteFile(i))return n.warn`Snapshot ${t} did not exist at ${i.fsPath}`,null}catch(e){n.warn(`Failed to delete snapshot ${t} from ${i.fsPath}`,{err:e})}return a}clearCaches(){k.trace`clear caches`,this.cache.clear()}normalizeIconPathsForWrite(e,t){let n=e.nodes.map(e=>{if(!e.icon||typeof e.icon!=`string`)return e;if(e.icon.startsWith(`file://`)){let n=m.parse(e.icon),r=h.relative(t,n);return r.startsWith(`..`)?e:{...e,icon:`${j}${r}`}}return e});return{...e,nodes:n}}resolveIconPathsAfterRead(e,t){let n=e.nodes.map(e=>{if(!e.icon||typeof e.icon!=`string`)return e;if(e.icon.startsWith(j)){let n=e.icon.substring(9),r=h.joinPath(t,n);return{...e,icon:r.toString()}}return e});return{...e,nodes:n}}};const M=r.getChild(`chokidar`),N={fileSystemWatcher:e=>new ChokidarFileSystemWatcher(e)},isAnyLikeC4File=e=>{let t=x(e);return a(t)||u(t)||isManualLayoutFile(t)};var ChokidarFileSystemWatcher=class{watcher;queue=new s({concurrency:1,timeout:5e3});constructor(e){this.services=e}watch(e){if(this.watcher){M.debug`add watching folder: ${e}`,this.watcher.add(e);return}this.watcher=this.createWatcher(e)}async dispose(){if(this.watcher){let e=this.watcher;this.watcher=void 0,await e.close()}}createWatcher(e){M.debug`create watcher for folder: ${e}`;let t=T.watch(e,{ignored:[e=>e.includes(`node_modules`)||e.includes(`.git`),(e,t)=>!!t?.isFile()&&!isAnyLikeC4File(e)],followSymlinks:!0,ignoreInitial:!0}),onAddOrChange=(e,t)=>{t?.isDirectory()||this.enqueueFileOp(`addOrChange: `+e,async()=>{await this.onAddOrChange(e)})};return t.on(`add`,onAddOrChange).on(`change`,onAddOrChange).on(`unlink`,(e,t)=>{t?.isDirectory()||this.enqueueFileOp(`remove: `+e,async()=>{await this.onRemove(e)})}).on(`unlinkDir`,e=>{this.enqueueFileOp(`removeDir: `+e,async()=>{await this.onRemoveDir(e)})}),t}enqueueFileOp(e,t){this.queue.add(async()=>{try{await t()}catch(t){M.warn(`Failed on {fileop}`,{fileop:e,error:t})}}).catch(t=>{M.error(`Error on {fileop}`,{fileop:e,error:t})})}async onAddOrChange(e){let t=this.services.workspace,n=x(e),r=m.file(e);switch(!0){case u(n):M.debug`project file changed: ${e}`,t.ManualLayouts.clearCaches(),await t.ProjectsManager.registerConfigFile(r);break;case a(n):M.debug`file changed: ${e}`,await t.DocumentBuilder.update([r],[]);break;case isManualLayoutFile(n):{M.debug`manual layout file changed: ${e}`,t.ManualLayouts.clearCaches();let n=t.ProjectsManager.ownerProjectId(r);await t.ProjectsManager.rebuildProject(n);break}default:M.warn`Unknown file change: ${e}`}}async onRemove(e){let t=this.services.workspace,n=x(e),r=m.file(e);switch(!0){case u(n):M.debug`project file removed: ${e}`,t.ManualLayouts.clearCaches(),await t.ProjectsManager.reloadProjects();break;case a(n):M.debug`file removed: ${e}`,await t.DocumentBuilder.update([],[r]);break;case isManualLayoutFile(n):{M.debug`manual layout file removed: ${e}`;let n=t.ProjectsManager.ownerProjectId(r);t.ManualLayouts.clearCaches(),await t.ProjectsManager.rebuildProject(n);break}default:M.warn`Unknown file removal: ${e}`}}async onRemoveDir(e){M.debug`directory removed: ${e}`;let t=this.services.workspace;t.ProjectsManager.findOverlaped(e).length>0&&(t.ManualLayouts.clearCaches(),await t.ProjectsManager.reloadProjects())}};const P=r.getChild(`filesystem`);function isLikeC4ConfigFile(e,t=!1){return!t&&u(x(e))}function isLikeC4File(e,t=!1){return!t&&a(x(e))}const WithFileSystem=(e=!0)=>({fileSystemProvider:()=>new SymLinkTraversingFileSystemProvider,...e?N:n});var SymLinkTraversingFileSystemProvider=class extends g{async readFile(n){if(t(n))return Promise.resolve(e);try{return await super.readFile(n)}catch(e){return P.warn(`Failed to read file ${n.fsPath}`,{error:e}),``}}async readDirectory(e,t){let n=t?.recursive??!0,r=t?.maxDepth??1/0,a=[];try{let t=new f().withSymlinks({resolvePaths:!1}).exclude(i).withFullPaths().filter(isLikeC4File);n?r!==1/0&&(t=t.withMaxDepth(r)):t=t.withMaxDepth(1);let o=await t.crawl(e.fsPath).withPromise();for(let e of o)a.push({isFile:!0,isDirectory:!1,uri:m.file(e)})}catch(t){P.warn(`Failed to read directory ${e.fsPath}`,{error:t})}return a.sort(o)}async scanProjectFiles(e){return await this.scanDirectory(e,isLikeC4ConfigFile)}async scanDirectory(e,t){let n=[];try{let r=await new f().withSymlinks({resolvePaths:!1}).exclude(i).withFullPaths().filter(t).crawl(e.fsPath).withPromise();for(let e of r)n.push({isFile:!0,isDirectory:!1,uri:m.file(e)})}catch(t){P.warn(`Failed to scan directory {path}`,{path:e.fsPath,error:t})}return n}async loadProjectConfig(e){return await d(e)}async writeFile(e,t){let n=S(e.fsPath),r=v(n,{throwIfNoEntry:!1});if(r?.isFile())throw Error(`Cannot create directory ${n} because a file with the same name exists.`);return r||(P.debug(`creating directory {path}`,{path:n}),_(n,{recursive:!0})),P.debug(`writing file {path}`,{path:e.fsPath}),await b(e.fsPath,t,{encoding:`utf-8`})}async deleteFile(e){try{let t=e.fsPath,n=v(t,{throwIfNoEntry:!1});return n?.isFile()||n?.isSymbolicLink()?(await y(t),P.debug(`deleted file {path}`,{path:t}),!0):(P.warn(`deleteFile failed: {path} does not exist, or is not a file`,{path:t}),!1)}catch(t){P.warn(`Failed to delete file ${e.fsPath}`,{error:t})}return!1}};export{N as n,A as r,WithFileSystem as t};