@likec4/language-services 1.52.0 → 1.54.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.
@@ -1,7 +1,7 @@
1
1
  import { configureLanguageServerLogger } from "@likec4/language-server";
2
2
  import { isColorSupported } from "std-env";
3
3
  function configureLogger(options) {
4
- const opt = options?.configureLogger ?? "console";
4
+ const opt = options?.configureLogger ?? false;
5
5
  if (opt === false) return;
6
6
  if (opt === "stderr" || options?.mcp === "stdio") {
7
7
  configureLanguageServerLogger({
@@ -3,8 +3,10 @@ import { extname } from "pathe";
3
3
  import k from "tinyrainbow";
4
4
  import { LikeC4ProjectConfigOps, isLikeC4JsonConfig } from "@likec4/config";
5
5
  import { URI, UriUtils } from "langium";
6
- import { entries, map, partition, pipe, prop } from "remeda";
7
- import { DiagnosticSeverity } from "vscode-languageserver-types";
6
+ import { entries, flatMap, hasAtLeast, join, map, partition, pipe, prop } from "remeda";
7
+ const isErrorDiagnostic = (diagnostic) => {
8
+ return diagnostic.severity === 1;
9
+ };
8
10
  var LikeC4 = class {
9
11
  langium;
10
12
  logger;
@@ -97,8 +99,8 @@ Please specify a project folder`);
97
99
  return await this.languageServices.layoutedModel(projectId);
98
100
  }
99
101
  getErrors() {
100
- return this.LangiumDocuments.all.toArray().flatMap((doc) => {
101
- return (doc.diagnostics ?? []).filter((d) => d.severity === DiagnosticSeverity.Error).map(({ message, range }) => ({
102
+ return [...this.LangiumDocuments.userDocuments].flatMap((doc) => {
103
+ return (doc.diagnostics?.filter(isErrorDiagnostic) ?? []).map(({ message, range }) => ({
102
104
  message,
103
105
  line: range.start.line,
104
106
  range,
@@ -107,8 +109,8 @@ Please specify a project folder`);
107
109
  });
108
110
  }
109
111
  hasErrors() {
110
- return this.LangiumDocuments.all.some((doc) => {
111
- return doc.diagnostics?.some((d) => d.severity === DiagnosticSeverity.Error) ?? false;
112
+ return this.LangiumDocuments.userDocuments.some((doc) => {
113
+ return doc.diagnostics && doc.diagnostics.some(isErrorDiagnostic);
112
114
  });
113
115
  }
114
116
  /**
@@ -116,28 +118,33 @@ Please specify a project folder`);
116
118
  */
117
119
  printErrors() {
118
120
  let hasErrors = false;
119
- for (const doc of this.LangiumDocuments.all) {
120
- const errors = doc.diagnostics?.filter((e) => e.severity === 1);
121
- if (errors && errors.length > 0) {
122
- hasErrors = true;
123
- const messages = errors.flatMap((validationError) => {
124
- const line = validationError.range.start.line;
125
- const messages = validationError.message.split("\n");
126
- if (messages.length > 10) {
127
- messages.length = 10;
128
- messages.push("...");
129
- }
130
- return messages.map((message, i) => {
131
- if (i === 0) return " " + k.dim(`Line ${line}: `) + k.red(message);
132
- return " ".repeat(10) + k.red(message);
133
- });
134
- }).join("\n");
135
- this.logger.error(`Invalid ${doc.uri.fsPath}\n${messages}`);
136
- }
121
+ for (const doc of this.LangiumDocuments.userDocuments) {
122
+ const errors = doc.diagnostics?.filter(isErrorDiagnostic) ?? [];
123
+ if (!hasAtLeast(errors, 1)) continue;
124
+ hasErrors = true;
125
+ const messages = pipe(errors, flatMap((validationError) => {
126
+ const line = validationError.range.start.line;
127
+ const messages = validationError.message.split("\n");
128
+ if (messages.length > 5) {
129
+ messages.length = 5;
130
+ messages.push("...");
131
+ }
132
+ return messages.map((message, i) => {
133
+ if (i === 0) return " " + k.dim(`Line ${line}: `) + k.red(message);
134
+ return " ".repeat(10) + k.red(message);
135
+ });
136
+ }), join("\n"));
137
+ this.logger.error(`Invalid ${doc.uri.fsPath}\n${messages}`);
137
138
  }
138
139
  return hasErrors;
139
140
  }
140
141
  /**
142
+ * Returns the number of parsed documents in the workspace
143
+ */
144
+ documentCount() {
145
+ return [...this.LangiumDocuments.userDocuments].length;
146
+ }
147
+ /**
141
148
  * @returns a function to dispose the listener
142
149
  */
143
150
  onModelUpdate(listener) {
@@ -77,6 +77,10 @@ declare class LikeC4 {
77
77
  * @returns true if there are errors
78
78
  */
79
79
  printErrors(): boolean;
80
+ /**
81
+ * Returns the number of parsed documents in the workspace
82
+ */
83
+ documentCount(): number;
80
84
  /**
81
85
  * @returns a function to dispose the listener
82
86
  */
@@ -3,7 +3,6 @@ import { i as LikeC4Langium, n as InitOptions, r as LikeC4, t as FromWorkspaceOp
3
3
  //#region src/node/index.d.ts
4
4
  /**
5
5
  * Create a LikeC4 instance from a workspace directory
6
- * The instance is cached in globalThis to avoid creating multiple instances for the same workspace
7
6
  *
8
7
  * @param path - The workspace directory path
9
8
  * @param options - Optional configuration options
@@ -1,6 +1,5 @@
1
1
  import { i as LikeC4, n as handleInitOptions, r as DefaultInitOptions, t as createFromSources } from "../_chunks/createFromSources.mjs";
2
2
  import { t as configureLogger$1 } from "../_chunks/configureLogger.mjs";
3
- import { memoizeProp } from "@likec4/core";
4
3
  import { loggable, rootLogger } from "@likec4/log";
5
4
  import defu from "defu";
6
5
  import { basename, resolve } from "pathe";
@@ -44,46 +43,44 @@ function createLanguageServices$1(opts) {
44
43
  }
45
44
  /**
46
45
  * Create a LikeC4 instance from a workspace directory
47
- * The instance is cached in globalThis to avoid creating multiple instances for the same workspace
48
46
  *
49
47
  * @param path - The workspace directory path
50
48
  * @param options - Optional configuration options
51
49
  * @returns A Promise that resolves to a LikeC4 instance
52
50
  */
53
51
  async function fromWorkspace(path, options) {
54
- configureLogger$1(options);
55
52
  const workspacePath = resolve(path);
56
53
  const workspaceUri = withTrailingSlash(pathToFileURL(workspacePath).toString());
57
- return memoizeProp(globalThis, "likec4:" + workspacePath, async () => {
58
- const logger = rootLogger.getChild("lang");
59
- const langium = createLanguageServices$1(defu(options, {
60
- ...DefaultInitOptions,
61
- useFileSystem: true,
62
- manualLayouts: true,
63
- watch: false,
64
- mcp: false
65
- }));
66
- const workspace = {
67
- name: basename(workspacePath),
68
- uri: workspaceUri
69
- };
70
- const WorkspaceManager = langium.shared.workspace.WorkspaceManager;
71
- logger.info(`${k.dim("workspace:")} ${workspacePath}`);
72
- WorkspaceManager.initialize({
73
- capabilities: {},
74
- processId: null,
75
- rootUri: null,
76
- workspaceFolders: [workspace]
77
- });
78
- await WorkspaceManager.initializeWorkspace([workspace]);
79
- const userDocuments = langium.shared.workspace.LangiumDocuments.userDocuments.toArray();
80
- if (userDocuments.length === 0) {
81
- logger.error(`no LikeC4 sources found`);
82
- if (options?.throwIfInvalid) throw new Error(`no LikeC4 sources found`);
83
- }
84
- logger.info(`${k.dim("workspace:")} found ${userDocuments.length} source files`);
85
- return handleInitOptions(langium, rootLogger, options);
54
+ const logger = rootLogger.getChild("lang");
55
+ const opts = defu(options, {
56
+ ...DefaultInitOptions,
57
+ useFileSystem: true,
58
+ manualLayouts: true,
59
+ watch: false,
60
+ mcp: false
61
+ });
62
+ configureLogger$1(opts);
63
+ const langium = createLanguageServices$1(opts);
64
+ const workspace = {
65
+ name: basename(workspacePath),
66
+ uri: workspaceUri
67
+ };
68
+ const WorkspaceManager = langium.shared.workspace.WorkspaceManager;
69
+ logger.info(`${k.dim("workspace:")} ${workspacePath}`);
70
+ WorkspaceManager.initialize({
71
+ capabilities: {},
72
+ processId: null,
73
+ rootUri: null,
74
+ workspaceFolders: [workspace]
86
75
  });
76
+ await WorkspaceManager.initializeWorkspace([workspace]);
77
+ const userDocuments = langium.shared.workspace.LangiumDocuments.userDocuments.toArray();
78
+ if (userDocuments.length === 0) {
79
+ logger.error(`no LikeC4 sources found`);
80
+ if (options?.throwIfInvalid) throw new Error(`no LikeC4 sources found`);
81
+ }
82
+ logger.info(`${k.dim("workspace:")} found ${userDocuments.length} source files`);
83
+ return handleInitOptions(langium, rootLogger, options);
87
84
  }
88
85
  /**
89
86
  * Create a LikeC4 instance from the current working directory
@@ -3,7 +3,6 @@ import { i as LikeC4Langium, n as InitOptions, r as LikeC4, t as FromWorkspaceOp
3
3
  //#region src/node/without-mcp/index.d.ts
4
4
  /**
5
5
  * Create a LikeC4 instance from a workspace directory
6
- * The instance is cached in globalThis to avoid creating multiple instances for the same workspace
7
6
  *
8
7
  * @param path - The workspace directory path
9
8
  * @param options - Optional configuration options
@@ -1,6 +1,5 @@
1
- import { i as LikeC4, n as handleInitOptions, t as createFromSources } from "../../_chunks/createFromSources.mjs";
1
+ import { i as LikeC4, n as handleInitOptions, r as DefaultInitOptions, t as createFromSources } from "../../_chunks/createFromSources.mjs";
2
2
  import { t as configureLogger$1 } from "../../_chunks/configureLogger.mjs";
3
- import { memoizeProp } from "@likec4/core";
4
3
  import { rootLogger } from "@likec4/log";
5
4
  import defu from "defu";
6
5
  import { basename, resolve } from "pathe";
@@ -33,47 +32,45 @@ function createLanguageServices$1(opts) {
33
32
  }
34
33
  /**
35
34
  * Create a LikeC4 instance from a workspace directory
36
- * The instance is cached in globalThis to avoid creating multiple instances for the same workspace
37
35
  *
38
36
  * @param path - The workspace directory path
39
37
  * @param options - Optional configuration options
40
38
  * @returns A Promise that resolves to a LikeC4 instance
41
39
  */
42
40
  async function fromWorkspace(path, options) {
43
- configureLogger$1(options);
44
41
  const workspacePath = resolve(path);
45
42
  const folderUri = pathToFileURL(workspacePath).toString();
46
43
  const workspaceUri = folderUri.endsWith("/") ? folderUri : folderUri + "/";
47
- return memoizeProp(globalThis, "likec4:" + workspacePath, async () => {
48
- const logger = rootLogger.getChild("lang");
49
- const mergedOptions = defu(options, {
50
- useFileSystem: true,
51
- manualLayouts: true,
52
- watch: false
53
- });
54
- if (mergedOptions.mcp) throw new Error("MCP server is not supported in this build");
55
- const langium = createLanguageServices$1(mergedOptions);
56
- const workspace = {
57
- name: basename(workspacePath),
58
- uri: workspaceUri
59
- };
60
- const WorkspaceManager = langium.shared.workspace.WorkspaceManager;
61
- logger.info(`${k.dim("workspace:")} ${workspacePath}`);
62
- WorkspaceManager.initialize({
63
- capabilities: {},
64
- processId: null,
65
- rootUri: null,
66
- workspaceFolders: [workspace]
67
- });
68
- await WorkspaceManager.initializeWorkspace([workspace]);
69
- const userDocuments = langium.shared.workspace.LangiumDocuments.userDocuments.toArray();
70
- if (userDocuments.length === 0) {
71
- logger.error(`no LikeC4 sources found`);
72
- throw new Error(`no LikeC4 sources found`);
73
- }
74
- logger.info(`${k.dim("workspace:")} found ${userDocuments.length} source files`);
75
- return handleInitOptions(langium, rootLogger, options);
44
+ const logger = rootLogger.getChild("lang");
45
+ const mergedOptions = defu(options, {
46
+ ...DefaultInitOptions,
47
+ useFileSystem: true,
48
+ manualLayouts: true,
49
+ watch: false
50
+ });
51
+ configureLogger$1(mergedOptions);
52
+ if (mergedOptions.mcp) throw new Error("MCP server is not supported in this build");
53
+ const langium = createLanguageServices$1(mergedOptions);
54
+ const workspace = {
55
+ name: basename(workspacePath),
56
+ uri: workspaceUri
57
+ };
58
+ const WorkspaceManager = langium.shared.workspace.WorkspaceManager;
59
+ logger.info(`${k.dim("workspace:")} ${workspacePath}`);
60
+ WorkspaceManager.initialize({
61
+ capabilities: {},
62
+ processId: null,
63
+ rootUri: null,
64
+ workspaceFolders: [workspace]
76
65
  });
66
+ await WorkspaceManager.initializeWorkspace([workspace]);
67
+ const userDocuments = langium.shared.workspace.LangiumDocuments.userDocuments.toArray();
68
+ if (userDocuments.length === 0) {
69
+ logger.error(`no LikeC4 sources found`);
70
+ throw new Error(`no LikeC4 sources found`);
71
+ }
72
+ logger.info(`${k.dim("workspace:")} found ${userDocuments.length} source files`);
73
+ return handleInitOptions(langium, rootLogger, options);
77
74
  }
78
75
  /**
79
76
  * Create a LikeC4 instance from the current working directory
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@likec4/language-services",
3
3
  "description": "LikeC4 Language Services",
4
- "version": "1.52.0",
4
+ "version": "1.54.0",
5
5
  "license": "MIT",
6
6
  "bugs": "https://github.com/likec4/likec4/issues",
7
7
  "homepage": "https://likec4.dev",
@@ -69,7 +69,7 @@
69
69
  "access": "public"
70
70
  },
71
71
  "dependencies": {
72
- "defu": "^6.1.4",
72
+ "defu": "^6.1.6",
73
73
  "remeda": "^2.33.6",
74
74
  "langium": "3.5.0",
75
75
  "tinyrainbow": "^3.0.3",
@@ -78,24 +78,24 @@
78
78
  "std-env": "^3.10.0",
79
79
  "type-fest": "^4.41.0",
80
80
  "vscode-languageserver-types": "3.17.5",
81
- "@likec4/config": "1.52.0",
82
- "@likec4/core": "1.52.0",
83
- "@likec4/generators": "1.52.0",
81
+ "@likec4/config": "1.54.0",
82
+ "@likec4/core": "1.54.0",
83
+ "@likec4/language-server": "1.54.0",
84
+ "@likec4/generators": "1.54.0",
85
+ "@likec4/layouts": "1.54.0",
84
86
  "@likec4/icons": "1.46.4",
85
- "@likec4/language-server": "1.52.0",
86
- "@likec4/layouts": "1.52.0",
87
- "@likec4/log": "1.52.0"
87
+ "@likec4/log": "1.54.0"
88
88
  },
89
89
  "devDependencies": {
90
- "@types/node": "~22.19.11",
91
- "obuild": "^0.4.31",
92
- "oxlint": "1.43.0",
90
+ "@types/node": "~22.19.15",
91
+ "obuild": "0.4.31",
92
+ "oxlint": "1.55.0",
93
93
  "tsx": "4.21.0",
94
- "turbo": "2.8.13",
94
+ "turbo": "2.8.21",
95
95
  "typescript": "5.9.3",
96
- "vitest": "4.0.18",
96
+ "vitest": "4.1.0",
97
97
  "@likec4/devops": "1.42.0",
98
- "@likec4/tsconfig": "1.52.0"
98
+ "@likec4/tsconfig": "1.54.0"
99
99
  },
100
100
  "scripts": {
101
101
  "typecheck": "tsc -b --verbose",