@knip/language-server 0.0.2 → 0.0.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knip/language-server",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -12,7 +12,7 @@
12
12
  "dependencies": {
13
13
  "vscode-languageserver": "^9.0.1",
14
14
  "vscode-languageserver-textdocument": "^1.0.12",
15
- "knip": "5.75.1"
15
+ "knip": "5.76.0"
16
16
  },
17
17
  "engines": {
18
18
  "node": ">=18.18.0"
package/src/constants.js CHANGED
@@ -8,6 +8,8 @@ export const REQUEST_RESTART = 'knip.restart';
8
8
 
9
9
  export const REQUEST_FILE_NODE = 'knip.getFileNode';
10
10
 
11
+ export const REQUEST_PACKAGE_JSON = 'knip.getPackageJson';
12
+
11
13
  export const REQUEST_RESULTS = 'knip.getResults';
12
14
 
13
15
  export const SESSION_LOADING = 'session-loading';
package/src/server.js CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  import {
14
14
  DEFAULT_JSDOC_TAGS,
15
15
  REQUEST_FILE_NODE,
16
+ REQUEST_PACKAGE_JSON,
16
17
  REQUEST_RESTART,
17
18
  REQUEST_RESULTS,
18
19
  REQUEST_START,
@@ -117,6 +118,8 @@ export class LanguageServer {
117
118
  return this.getFileDescriptor(fileURLToPath(params.uri), { isShowContention });
118
119
  });
119
120
 
121
+ this.connection.onRequest(REQUEST_PACKAGE_JSON, () => this.getPackageJsonDescriptor());
122
+
120
123
  this.connection.onCodeAction(params => this.handleCodeAction(params));
121
124
 
122
125
  this.connection.onDidChangeWatchedFiles(params => this.handleFileChanges(params));
@@ -172,8 +175,19 @@ export class LanguageServer {
172
175
  const config = await this.getConfig();
173
176
  if (!config?.enabled) return;
174
177
 
178
+ const configFilePath = config.configFilePath
179
+ ? path.isAbsolute(config.configFilePath)
180
+ ? config.configFilePath
181
+ : path.resolve(this.cwd ?? process.cwd(), config.configFilePath)
182
+ : undefined;
183
+
184
+ if (configFilePath) {
185
+ this.cwd = path.dirname(configFilePath);
186
+ process.chdir(this.cwd);
187
+ }
188
+
175
189
  this.connection.console.log('Creating options');
176
- const options = await createOptions({ cwd: this.cwd, isSession: true });
190
+ const options = await createOptions({ cwd: this.cwd, isSession: true, args: { config: configFilePath } });
177
191
  this.rules = options.rules;
178
192
 
179
193
  this.connection.console.log('Building module graph...');
@@ -211,6 +225,7 @@ export class LanguageServer {
211
225
  */
212
226
  async handleFileChanges(params) {
213
227
  this.fileCache = undefined;
228
+ this.packageJsonCache = undefined;
214
229
  if (!this.session) return;
215
230
 
216
231
  /** @type {{ type: "added" | "deleted" | "modified"; filePath: string }[]} */
@@ -243,6 +258,7 @@ export class LanguageServer {
243
258
  getFileDescriptor(filePath, options) {
244
259
  if (!this.session) return SESSION_LOADING;
245
260
  const relPath = toPosix(path.relative(this.cwd ?? process.cwd(), filePath));
261
+ if (relPath.startsWith('..')) return;
246
262
  if (this.fileCache?.filePath === relPath) return this.fileCache.file;
247
263
  const startTime = performance.now();
248
264
  const file = this.session.describeFile(relPath, options);
@@ -256,10 +272,23 @@ export class LanguageServer {
256
272
  this.connection.console.log(
257
273
  ` ↳ imports: ${Math.round(m.imports)}ms, exports: ${Math.round(m.exports)}ms, cycles: ${Math.round(m.cycles)}ms, contention: ${Math.round(m.contention)}ms`
258
274
  );
259
- this.fileCache = { filePath: relPath, file };
260
- return file;
275
+ } else {
276
+ this.connection.console.log(`File not in project (${relPath})`);
261
277
  }
262
- this.connection.console.log(`File not in project (${relPath})`);
278
+ this.fileCache = { filePath: relPath, file };
279
+ return file;
280
+ }
281
+
282
+ /**
283
+ * @returns {import('knip/session').PackageJsonFile & { dependenciesUsage: Record<string, import('knip/session').DependencyNodes> } | typeof SESSION_LOADING}
284
+ */
285
+ getPackageJsonDescriptor() {
286
+ if (!this.session) return SESSION_LOADING;
287
+ if (this.packageJsonCache) return this.packageJsonCache;
288
+ const result = this.session.describePackageJson();
289
+ // Convert Map to object for JSON serialization
290
+ this.packageJsonCache = { dependenciesUsage: Object.fromEntries(result.dependenciesUsage) };
291
+ return this.packageJsonCache;
263
292
  }
264
293
 
265
294
  /**
package/src/types.d.ts CHANGED
@@ -2,6 +2,7 @@ import type { Issue, IssueType } from 'knip/session';
2
2
 
3
3
  export type Config = {
4
4
  enabled: boolean;
5
+ configFilePath?: string;
5
6
  editor: {
6
7
  exports: {
7
8
  codelens: {