knip 2.28.0 → 2.29.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.
@@ -6,7 +6,7 @@ import { getJSDocTags, isInModuleBlock } from './typescript/ast-helpers.js';
6
6
  import { createHosts } from './typescript/createHosts.js';
7
7
  import { getImportsAndExports } from './typescript/getImportsAndExports.js';
8
8
  import { SourceFileManager } from './typescript/SourceFileManager.js';
9
- import { isMaybePackageName } from './util/modules.js';
9
+ import { isMaybePackageName, sanitizeSpecifier } from './util/modules.js';
10
10
  import { dirname, extname, isInNodeModules, join } from './util/path.js';
11
11
  import { timerify } from './util/Performance.js';
12
12
  const baseCompilerOptions = {
@@ -128,7 +128,7 @@ export class ProjectPrincipal {
128
128
  }
129
129
  }
130
130
  else {
131
- const sanitizedSpecifier = specifier.replace(/^([?!|-]+)?([^!?]+).*/, '$2');
131
+ const sanitizedSpecifier = sanitizeSpecifier(specifier);
132
132
  if (isMaybePackageName(sanitizedSpecifier)) {
133
133
  external.add(sanitizedSpecifier);
134
134
  }
@@ -9,7 +9,7 @@ const productionEntryFilePatternsWithoutSrc = [
9
9
  'app/**/{error,layout,loading,not-found,page,template}.{js,jsx,ts,tsx}',
10
10
  'instrumentation.{js,ts}',
11
11
  'app/{manifest,sitemap,robots}.{js,ts}',
12
- 'app/**/{icon,apple-icon}-image.{js,ts,tsx}',
12
+ 'app/**/{icon,apple-icon}.{js,ts,tsx}',
13
13
  'app/**/{opengraph,twitter}-image.{js,ts,tsx}',
14
14
  'pages/**/*.{js,jsx,ts,tsx}',
15
15
  ];
@@ -5,7 +5,7 @@ import { getEnvPackageName, getExternalReporters } from './helpers.js';
5
5
  export const NAME = 'Vitest';
6
6
  export const ENABLERS = ['vitest'];
7
7
  export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
8
- export const CONFIG_FILE_PATTERNS = ['vitest.config.ts'];
8
+ export const CONFIG_FILE_PATTERNS = ['vitest.config.ts', 'vitest.{workspace,projects}.{ts,js,json}'];
9
9
  export const ENTRY_FILE_PATTERNS = [];
10
10
  export const findVitestDeps = (config) => {
11
11
  if (!config || !config.test)
@@ -18,8 +18,20 @@ export const findVitestDeps = (config) => {
18
18
  const globalSetup = cfg.globalSetup ? [cfg.globalSetup].flat() : [];
19
19
  return compact([...environments, ...reporters, ...coverage, ...setupFiles, ...globalSetup]);
20
20
  };
21
+ const findVitestWorkspaceDeps = (config) => {
22
+ let deps = [];
23
+ for (const cfg of config) {
24
+ if (typeof cfg === 'string')
25
+ continue;
26
+ deps = [...deps, ...findVitestDeps(cfg)];
27
+ }
28
+ return compact(deps);
29
+ };
21
30
  const findVitestDependencies = async (configFilePath) => {
22
31
  const config = await load(configFilePath);
32
+ if (Array.isArray(config)) {
33
+ return findVitestWorkspaceDeps(config);
34
+ }
23
35
  return findVitestDeps(config);
24
36
  };
25
37
  export const findDependencies = timerify(findVitestDependencies);
@@ -9,3 +9,4 @@ export interface VitestConfig {
9
9
  setupFiles?: string | string[];
10
10
  };
11
11
  }
12
+ export type VitestWorkspaceConfig = (string | VitestConfig)[];
@@ -1,9 +1,7 @@
1
- import { existsSync } from 'node:fs';
2
1
  import { isBuiltin } from 'node:module';
3
- import { resolve, dirname } from 'node:path';
4
2
  import ts from 'typescript';
5
3
  import { getOrSet } from '../util/map.js';
6
- import { isMaybePackageName } from '../util/modules.js';
4
+ import { isMaybePackageName, sanitizeSpecifier } from '../util/modules.js';
7
5
  import { isInNodeModules } from '../util/path.js';
8
6
  import { isDeclarationFileExtension, isAccessExpression, getAccessExpressionName, getJSDocTags, } from './ast-helpers.js';
9
7
  import getExportVisitors from './visitors/exports/index.js';
@@ -60,13 +58,14 @@ export const getImportsAndExports = (sourceFile, options) => {
60
58
  if (!isInNodeModules(filePath)) {
61
59
  addInternalImport({ identifier, specifier, symbol, filePath, isReExport });
62
60
  }
63
- if (!isMaybePackageName(specifier))
61
+ const sanitizedSpecifier = sanitizeSpecifier(specifier);
62
+ if (!isMaybePackageName(sanitizedSpecifier))
64
63
  return;
65
64
  if (isDeclarationFileExtension(module.resolvedModule.extension)) {
66
- externalImports.add(specifier);
65
+ externalImports.add(sanitizedSpecifier);
67
66
  }
68
67
  else {
69
- externalImports.add(module.resolvedModule.packageId?.name ?? specifier);
68
+ externalImports.add(module.resolvedModule.packageId?.name ?? sanitizedSpecifier);
70
69
  }
71
70
  }
72
71
  else {
@@ -75,13 +74,7 @@ export const getImportsAndExports = (sourceFile, options) => {
75
74
  }
76
75
  }
77
76
  else {
78
- const filePath = resolve(dirname(sourceFile.fileName), specifier);
79
- if (existsSync(filePath)) {
80
- unresolvedImports.add(filePath);
81
- }
82
- else {
83
- unresolvedImports.add(specifier);
84
- }
77
+ unresolvedImports.add(specifier);
85
78
  }
86
79
  };
87
80
  const maybeAddNamespaceAccessAsImport = ({ namespace, member }) => {
@@ -1,11 +1,29 @@
1
+ import { existsSync } from 'node:fs';
1
2
  import ts from 'typescript';
3
+ import { sanitizeSpecifier } from '../util/modules.js';
4
+ import { dirname, extname, isInternal, join } from '../util/path.js';
2
5
  import { ensureRealFilePath, isVirtualFilePath } from './utils.js';
3
6
  export function createCustomModuleResolver(customSys, compilerOptions, virtualFileExtensions) {
4
7
  function resolveModuleNames(moduleNames, containingFile) {
5
8
  return moduleNames.map(moduleName => resolveModuleName(moduleName, containingFile));
6
9
  }
7
10
  function resolveModuleName(name, containingFile) {
8
- const tsResolvedModule = ts.resolveModuleName(name, containingFile, compilerOptions, ts.sys).resolvedModule;
11
+ const sanitizedSpecifier = sanitizeSpecifier(name);
12
+ const tsResolvedModule = ts.resolveModuleName(sanitizedSpecifier, containingFile, compilerOptions, ts.sys).resolvedModule;
13
+ if (!tsResolvedModule) {
14
+ const extension = extname(sanitizedSpecifier);
15
+ if (extension && isInternal(sanitizedSpecifier) && !virtualFileExtensions.includes(extension)) {
16
+ const resolvedFileName = join(dirname(containingFile), sanitizedSpecifier);
17
+ if (existsSync(resolvedFileName)) {
18
+ return {
19
+ resolvedFileName,
20
+ extension,
21
+ isExternalLibraryImport: false,
22
+ resolvedUsingTsExtension: false,
23
+ };
24
+ }
25
+ }
26
+ }
9
27
  if (virtualFileExtensions.length === 0)
10
28
  return tsResolvedModule;
11
29
  if (tsResolvedModule && !isVirtualFilePath(tsResolvedModule.resolvedFileName, virtualFileExtensions)) {
@@ -6,3 +6,4 @@ export declare const isDefinitelyTyped: (packageName: string) => boolean;
6
6
  export declare const getDefinitelyTypedFor: (packageName: string) => string;
7
7
  export declare const getPackageFromDefinitelyTyped: (typedDependency: string) => string;
8
8
  export declare const getEntryPathFromManifest: (cwd: string, dir: string, manifest: PackageJson) => Promise<string[]>;
9
+ export declare const sanitizeSpecifier: (specifier: string) => string;
@@ -50,3 +50,4 @@ export const getEntryPathFromManifest = (cwd, dir, manifest) => {
50
50
  }
51
51
  return _glob({ cwd, workingDir: dir, patterns: Array.from(entryPaths) });
52
52
  };
53
+ export const sanitizeSpecifier = (specifier) => specifier.replace(/^([?!|-]+)?([^!?]+).*/, '$2');
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "2.28.0";
1
+ export declare const version = "2.29.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '2.28.0';
1
+ export const version = '2.29.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "2.28.0",
3
+ "version": "2.29.0",
4
4
  "description": "Find unused files, dependencies and exports in your TypeScript and JavaScript projects",
5
5
  "homepage": "https://github.com/webpro/knip",
6
6
  "repository": "github:webpro/knip",