knip 2.33.2 → 2.33.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.
Files changed (78) hide show
  1. package/README.md +2 -0
  2. package/dist/WorkspaceWorker.js +12 -17
  3. package/dist/binaries/bash-parser.js +1 -1
  4. package/dist/index.js +17 -16
  5. package/dist/plugins/_template/index.js +14 -3
  6. package/dist/plugins/_template/types.d.ts +1 -0
  7. package/dist/plugins/angular/index.js +11 -11
  8. package/dist/plugins/ava/index.js +13 -12
  9. package/dist/plugins/babel/index.js +8 -5
  10. package/dist/plugins/capacitor/index.js +4 -2
  11. package/dist/plugins/changesets/index.js +7 -5
  12. package/dist/plugins/commitizen/index.js +4 -3
  13. package/dist/plugins/commitizen/types.d.ts +1 -1
  14. package/dist/plugins/commitlint/index.js +4 -2
  15. package/dist/plugins/cspell/index.js +4 -2
  16. package/dist/plugins/cspell/types.d.ts +1 -1
  17. package/dist/plugins/cypress/index.js +7 -4
  18. package/dist/plugins/drizzle/index.js +4 -4
  19. package/dist/plugins/eslint/fallback.js +6 -1
  20. package/dist/plugins/eslint/helpers.d.ts +2 -2
  21. package/dist/plugins/eslint/helpers.js +7 -7
  22. package/dist/plugins/eslint/index.d.ts +0 -1
  23. package/dist/plugins/eslint/index.js +3 -4
  24. package/dist/plugins/gatsby/index.js +5 -8
  25. package/dist/plugins/github-actions/index.d.ts +1 -1
  26. package/dist/plugins/github-actions/index.js +5 -4
  27. package/dist/plugins/husky/index.js +4 -2
  28. package/dist/plugins/jest/index.js +8 -8
  29. package/dist/plugins/jest/types.d.ts +3 -0
  30. package/dist/plugins/jest/types.js +1 -0
  31. package/dist/plugins/lefthook/index.js +5 -4
  32. package/dist/plugins/lint-staged/index.js +7 -7
  33. package/dist/plugins/markdownlint/index.js +5 -4
  34. package/dist/plugins/mocha/index.js +8 -7
  35. package/dist/plugins/mocha/types.d.ts +4 -0
  36. package/dist/plugins/mocha/types.js +1 -0
  37. package/dist/plugins/npm-package-json-lint/index.js +4 -3
  38. package/dist/plugins/nx/index.js +5 -4
  39. package/dist/plugins/nyc/index.js +4 -3
  40. package/dist/plugins/nyc/types.d.ts +3 -0
  41. package/dist/plugins/nyc/types.js +1 -0
  42. package/dist/plugins/playwright/index.d.ts +1 -1
  43. package/dist/plugins/playwright/index.js +7 -6
  44. package/dist/plugins/playwright-ct/index.js +11 -6
  45. package/dist/plugins/postcss/index.js +6 -5
  46. package/dist/plugins/prettier/index.js +3 -3
  47. package/dist/plugins/prettier/types.d.ts +8 -0
  48. package/dist/plugins/prettier/types.js +1 -0
  49. package/dist/plugins/release-it/index.js +10 -9
  50. package/dist/plugins/remark/index.js +6 -5
  51. package/dist/plugins/remix/index.js +1 -5
  52. package/dist/plugins/rollup/index.js +1 -1
  53. package/dist/plugins/semantic-release/index.js +5 -4
  54. package/dist/plugins/semantic-release/types.d.ts +1 -1
  55. package/dist/plugins/storybook/index.js +13 -11
  56. package/dist/plugins/stryker/index.js +9 -6
  57. package/dist/plugins/stylelint/index.js +6 -5
  58. package/dist/plugins/typedoc/index.js +4 -3
  59. package/dist/plugins/typedoc/types.d.ts +1 -1
  60. package/dist/plugins/typescript/index.js +13 -10
  61. package/dist/plugins/vite/index.js +4 -2
  62. package/dist/plugins/vitest/index.d.ts +2 -2
  63. package/dist/plugins/vitest/index.js +8 -5
  64. package/dist/plugins/vitest/types.d.ts +1 -0
  65. package/dist/plugins/webpack/index.js +25 -15
  66. package/dist/plugins/webpack/types.d.ts +2 -1
  67. package/dist/types/config.d.ts +1 -1
  68. package/dist/types/plugins.d.ts +1 -1
  69. package/dist/typescript/SourceFileManager.js +3 -3
  70. package/dist/util/debug.d.ts +3 -3
  71. package/dist/util/debug.js +10 -8
  72. package/dist/util/glob.js +1 -1
  73. package/dist/util/path.js +1 -1
  74. package/dist/util/plugin.js +7 -1
  75. package/dist/util/require.js +1 -1
  76. package/dist/version.d.ts +1 -1
  77. package/dist/version.js +1 -1
  78. package/package.json +1 -1
@@ -8,27 +8,30 @@ export const ENABLERS = ['typescript'];
8
8
  export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
9
9
  export const CONFIG_FILE_PATTERNS = ['tsconfig.json', 'tsconfig.*.json'];
10
10
  const resolveExtensibleConfig = async (configFilePath) => {
11
- const config = await load(configFilePath);
12
- config.extends = config.extends ? [config.extends].flat() : [];
13
- if (config?.extends) {
14
- for (const extend of [config.extends].flat()) {
11
+ const localConfig = await load(configFilePath);
12
+ if (!localConfig)
13
+ return;
14
+ localConfig.extends = localConfig.extends ? [localConfig.extends].flat() : [];
15
+ if (localConfig?.extends) {
16
+ for (const extend of [localConfig.extends].flat()) {
15
17
  if (isInternal(extend)) {
16
18
  const presetConfigPath = toAbsolute(extend, dirname(configFilePath));
17
19
  const presetConfig = await resolveExtensibleConfig(presetConfigPath);
18
- config.extends.push(...(presetConfig.extends ? [presetConfig.extends].flat() : []));
20
+ localConfig.extends.push(...(presetConfig?.extends ? [presetConfig.extends].flat() : []));
19
21
  }
20
22
  }
21
23
  }
22
- return config;
24
+ return localConfig;
23
25
  };
24
- export const findTypeScriptDependencies = async (configFilePath, { isProduction }) => {
26
+ export const findTypeScriptDependencies = async (configFilePath, options) => {
27
+ const { isProduction } = options;
25
28
  if (isProduction)
26
29
  return [];
27
30
  const { compilerOptions } = await loadTSConfig(configFilePath);
28
- const config = await resolveExtensibleConfig(configFilePath);
29
- if (!compilerOptions || !config)
31
+ const localConfig = await resolveExtensibleConfig(configFilePath);
32
+ if (!compilerOptions || !localConfig)
30
33
  return [];
31
- const extend = config.extends ? [config.extends].flat().filter(extend => !isInternal(extend)) : [];
34
+ const extend = localConfig.extends ? [localConfig.extends].flat().filter(extend => !isInternal(extend)) : [];
32
35
  const types = compilerOptions.types ?? [];
33
36
  const plugins = Array.isArray(compilerOptions?.plugins)
34
37
  ? compilerOptions.plugins.map(plugin => (typeof plugin === 'object' && 'name' in plugin ? plugin.name : ''))
@@ -6,7 +6,9 @@ export const ENABLERS = ['vite'];
6
6
  export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
7
7
  export const CONFIG_FILE_PATTERNS = ['vite.config.{js,ts}'];
8
8
  const findViteDependencies = async (configFilePath, options) => {
9
- const config = await load(configFilePath);
10
- return findVitestDeps(config, options);
9
+ const localConfig = await load(configFilePath);
10
+ if (!localConfig)
11
+ return [];
12
+ return findVitestDeps(localConfig, options);
11
13
  };
12
14
  export const findDependencies = timerify(findViteDependencies);
@@ -1,9 +1,9 @@
1
- import type { VitestConfig } from './types.js';
1
+ import type { VitestConfigOrFn } from './types.js';
2
2
  import type { IsPluginEnabledCallback, GenericPluginCallback, GenericPluginCallbackOptions } from '../../types/plugins.js';
3
3
  export declare const NAME = "Vitest";
4
4
  export declare const ENABLERS: string[];
5
5
  export declare const isEnabled: IsPluginEnabledCallback;
6
6
  export declare const CONFIG_FILE_PATTERNS: string[];
7
7
  export declare const ENTRY_FILE_PATTERNS: string[];
8
- export declare const findVitestDeps: (config: VitestConfig, options: GenericPluginCallbackOptions) => any[];
8
+ export declare const findVitestDeps: (localConfig: VitestConfigOrFn, options: GenericPluginCallbackOptions) => any[];
9
9
  export declare const findDependencies: GenericPluginCallback;
@@ -8,11 +8,12 @@ export const ENABLERS = ['vitest'];
8
8
  export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
9
9
  export const CONFIG_FILE_PATTERNS = ['vitest.config.ts', 'vitest.{workspace,projects}.{ts,js,json}'];
10
10
  export const ENTRY_FILE_PATTERNS = ['**/*.{test,spec}.?(c|m)[jt]s?(x)'];
11
- export const findVitestDeps = (config, options) => {
11
+ export const findVitestDeps = (localConfig, options) => {
12
12
  const { isProduction } = options;
13
- if (!config || !config.test)
13
+ localConfig = typeof localConfig === 'function' ? localConfig() : localConfig;
14
+ if (!localConfig || !localConfig.test)
14
15
  return [];
15
- const testConfig = config.test;
16
+ const testConfig = localConfig.test;
16
17
  const entryPatterns = (options.config?.entry ?? testConfig.include ?? ENTRY_FILE_PATTERNS).map(toEntryPattern);
17
18
  if (isProduction)
18
19
  return entryPatterns;
@@ -24,7 +25,9 @@ export const findVitestDeps = (config, options) => {
24
25
  return [...entryPatterns, ...environments, ...reporters, ...coverage, ...setupFiles, ...globalSetup];
25
26
  };
26
27
  const findVitestDependencies = async (configFilePath, options) => {
27
- const config = await load(configFilePath);
28
- return compact([config].flat().flatMap(cfg => (!cfg || typeof cfg === 'string' ? [] : findVitestDeps(cfg, options))));
28
+ const localConfig = await load(configFilePath);
29
+ return compact([localConfig]
30
+ .flat()
31
+ .flatMap(config => (!config || typeof config === 'string' ? [] : findVitestDeps(config, options))));
29
32
  };
30
33
  export const findDependencies = timerify(findVitestDependencies);
@@ -10,4 +10,5 @@ export interface VitestConfig {
10
10
  setupFiles?: string | string[];
11
11
  };
12
12
  }
13
+ export type VitestConfigOrFn = VitestConfig | (() => VitestConfig);
13
14
  export type VitestWorkspaceConfig = (string | VitestConfig)[];
@@ -1,7 +1,8 @@
1
1
  import { compact } from '../../util/array.js';
2
- import { join } from '../../util/path.js';
2
+ import { join, relative } from '../../util/path.js';
3
3
  import { timerify } from '../../util/Performance.js';
4
4
  import { hasDependency, load } from '../../util/plugin.js';
5
+ import { toEntryPattern, toProductionEntryPattern } from '../../util/protocols.js';
5
6
  import { getDependenciesFromConfig } from '../babel/index.js';
6
7
  export const NAME = 'Webpack';
7
8
  export const ENABLERS = ['webpack'];
@@ -43,20 +44,23 @@ const resolveUseItem = (use) => {
43
44
  return [use.loader];
44
45
  return [];
45
46
  };
46
- const findWebpackDependencies = async (configFilePath, { manifest, isProduction }) => {
47
- if (isProduction)
48
- return [];
49
- const config = await load(configFilePath);
50
- if (!config)
47
+ const findWebpackDependencies = async (configFilePath, options) => {
48
+ const { manifest, isProduction, cwd } = options;
49
+ const localConfig = await load(configFilePath);
50
+ if (!localConfig)
51
51
  return [];
52
- const passes = typeof config === 'function' ? [false, true] : [false];
53
- const dependencies = passes.flatMap(isProduction => {
52
+ const passes = typeof localConfig === 'function' ? [false, true] : [false];
53
+ const dependencies = new Set();
54
+ const entryPatterns = new Set();
55
+ for (const isProduction of passes) {
54
56
  const env = { production: isProduction };
55
57
  const argv = { mode: isProduction ? 'production' : 'development' };
56
- const resolvedConfig = typeof config === 'function' ? config(env, argv) : config;
57
- return [resolvedConfig].flat().flatMap(options => {
58
- const dependencies = (options.module?.rules?.flatMap(resolveRuleSetDependencies) ?? []).map(loader => loader.replace(/\?.*/, ''));
58
+ const resolvedConfig = typeof localConfig === 'function' ? await localConfig(env, argv) : localConfig;
59
+ for (const options of [resolvedConfig].flat()) {
59
60
  const entries = [];
61
+ for (const loader of options.module?.rules?.flatMap(resolveRuleSetDependencies) ?? []) {
62
+ dependencies.add(loader.replace(/\?.*/, ''));
63
+ }
60
64
  if (typeof options.entry === 'string')
61
65
  entries.push(options.entry);
62
66
  else if (Array.isArray(options.entry))
@@ -73,12 +77,18 @@ const findWebpackDependencies = async (configFilePath, { manifest, isProduction
73
77
  entries.push(entry['filename']);
74
78
  });
75
79
  }
76
- return [...dependencies, ...entries.map(entry => (options.context ? join(options.context, entry) : entry))];
77
- });
78
- });
80
+ entries.forEach(entry => {
81
+ const item = relative(cwd, join(options.context ? options.context : cwd, entry));
82
+ const value = options.mode === 'development' ? toEntryPattern(item) : toProductionEntryPattern(item);
83
+ entryPatterns.add(value);
84
+ });
85
+ }
86
+ }
87
+ if (isProduction)
88
+ return [...entryPatterns];
79
89
  const scripts = Object.values(manifest.scripts ?? {});
80
90
  const webpackCLI = scripts.some(script => script?.includes('webpack ')) ? ['webpack-cli'] : [];
81
91
  const webpackDevServer = scripts.some(script => script?.includes('webpack serve')) ? ['webpack-dev-server'] : [];
82
- return compact([...dependencies, ...webpackCLI, ...webpackDevServer]);
92
+ return compact([...entryPatterns, ...dependencies, ...webpackCLI, ...webpackDevServer]);
83
93
  };
84
94
  export const findDependencies = timerify(findWebpackDependencies);
@@ -6,5 +6,6 @@ export type Env = {
6
6
  export type Argv = {
7
7
  mode: Mode;
8
8
  };
9
- export type WebpackConfig = Configuration | ((env: Env, argv: Argv) => Configuration);
9
+ type Configurations = Configuration | Configuration[];
10
+ export type WebpackConfig = Configurations | ((env: Env, argv: Argv) => Configurations) | (() => Promise<Configuration>);
10
11
  export {};
@@ -12,7 +12,7 @@ export type EnsuredPluginConfiguration = {
12
12
  entry: NormalizedGlob | null;
13
13
  project: NormalizedGlob | null;
14
14
  };
15
- export type PluginConfiguration = EnsuredPluginConfiguration | boolean;
15
+ type PluginConfiguration = EnsuredPluginConfiguration | boolean;
16
16
  export type PluginsConfiguration = Record<PluginName, PluginConfiguration>;
17
17
  interface BaseWorkspaceConfiguration {
18
18
  entry: NormalizedGlob;
@@ -12,7 +12,7 @@ export type IsPluginEnabledCallback = (options: IsPluginEnabledCallbackOptions)
12
12
  export type GenericPluginCallbackOptions = {
13
13
  cwd: string;
14
14
  manifest: PackageJsonWithPlugins;
15
- config?: EnsuredPluginConfiguration;
15
+ config: EnsuredPluginConfiguration;
16
16
  isProduction: boolean;
17
17
  };
18
18
  export type GenericPluginCallback = (configFilePath: string, options: GenericPluginCallbackOptions) => Promise<string[]> | string[];
@@ -22,14 +22,14 @@ export class SourceFileManager {
22
22
  const contents = ts.sys.readFile(filePath);
23
23
  if (typeof contents !== 'string') {
24
24
  if (isInternal(filePath))
25
- debugLog(`Unable to read ${filePath}`);
25
+ debugLog('*', `Unable to read ${filePath}`);
26
26
  return this.createSourceFile(filePath, '');
27
27
  }
28
28
  const ext = extname(filePath);
29
29
  const compiler = this.syncCompilers?.get(ext);
30
30
  const compiled = compiler ? compiler(contents, filePath) : contents;
31
31
  if (compiler)
32
- debugLog(`Compiled ${filePath}`);
32
+ debugLog('*', `Compiled ${filePath}`);
33
33
  return this.createSourceFile(filePath, compiled);
34
34
  }
35
35
  getSnapshot(filePath) {
@@ -50,7 +50,7 @@ export class SourceFileManager {
50
50
  const compiler = this.asyncCompilers?.get(ext);
51
51
  if (compiler) {
52
52
  const compiled = await compiler(contents, filePath);
53
- debugLog(`Compiled ${filePath}`);
53
+ debugLog('*', `Compiled ${filePath}`);
54
54
  this.createSourceFile(filePath, compiled);
55
55
  }
56
56
  }
@@ -1,3 +1,3 @@
1
- export declare const debugLog: (message: string) => void;
2
- export declare const debugLogObject: (name: string, obj: unknown) => void;
3
- export declare const debugLogArray: (name: string, sourceFiles: string[] | Set<string>) => void;
1
+ export declare const debugLog: (context: string, message: string) => void;
2
+ export declare const debugLogObject: (context: string, name: string, obj: unknown | (() => unknown)) => void;
3
+ export declare const debugLogArray: (context: string | [string, string], message: string, elements: string[] | Set<string>) => void;
@@ -1,9 +1,11 @@
1
1
  import util from 'node:util';
2
+ import chalk from 'chalk';
2
3
  import parsedArgValues from './cli-arguments.js';
3
4
  const { debug, 'debug-file-filter': debugFileFilter } = parsedArgValues;
4
5
  const IS_ENABLED = debug ?? false;
5
6
  const FILE_FILTER = debugFileFilter;
6
7
  const inspectOptions = { maxArrayLength: null, depth: null, colors: true };
8
+ const ctx = (text) => typeof text === 'string' ? chalk.yellow(`[${text}]`) : `${chalk.yellow(`[${text[0]}]`)} ${chalk.cyan(text[1])}`;
7
9
  const logArray = (collection) => {
8
10
  if (FILE_FILTER) {
9
11
  const fileFilter = new RegExp(FILE_FILTER);
@@ -14,21 +16,21 @@ const logArray = (collection) => {
14
16
  console.log(util.inspect(collection.sort(), inspectOptions));
15
17
  }
16
18
  };
17
- export const debugLog = (message) => {
19
+ export const debugLog = (context, message) => {
18
20
  if (!IS_ENABLED)
19
21
  return;
20
- console.log(`[knip] ${message}`);
22
+ console.log(`${ctx(context)} ${message}`);
21
23
  };
22
- export const debugLogObject = (name, obj) => {
24
+ export const debugLogObject = (context, name, obj) => {
23
25
  if (!IS_ENABLED)
24
26
  return;
25
- console.log(`[knip] ${name}`);
26
- console.log(util.inspect(obj, inspectOptions));
27
+ console.log(`${ctx(context)} ${name}`);
28
+ console.log(util.inspect(typeof obj === 'function' ? obj() : obj, inspectOptions));
27
29
  };
28
- export const debugLogArray = (name, sourceFiles) => {
30
+ export const debugLogArray = (context, message, elements) => {
29
31
  if (!IS_ENABLED)
30
32
  return;
31
- const collection = Array.from(sourceFiles);
32
- console.debug(`[knip] ${name} (${collection.length})`);
33
+ const collection = Array.from(elements);
34
+ console.debug(`${ctx(context)} ${message} (${collection.length})`);
33
35
  logArray(collection);
34
36
  };
package/dist/util/glob.js CHANGED
@@ -24,7 +24,7 @@ const glob = async ({ cwd, workingDir = cwd, patterns, ignore = [], gitignore =
24
24
  if (globPatterns[0].startsWith('!'))
25
25
  return [];
26
26
  const ignorePatterns = compact([...ignore, ...GLOBAL_IGNORE_PATTERNS]);
27
- debugLogObject(`Globbing (${relativePath || ROOT_WORKSPACE_NAME})`, { cwd, globPatterns, ignorePatterns });
27
+ debugLogObject(relativePath || ROOT_WORKSPACE_NAME, `Glob options`, { cwd, globPatterns, ignorePatterns });
28
28
  return globby(globPatterns, {
29
29
  cwd,
30
30
  ignore: ignorePatterns,
package/dist/util/path.js CHANGED
@@ -6,7 +6,7 @@ export const join = path.posix.join;
6
6
  export const toPosix = (value) => value.split(path.sep).join(path.posix.sep);
7
7
  export const cwd = toPosix(process.cwd());
8
8
  export const resolve = (...paths) => paths.length === 1 ? path.posix.join(cwd, paths[0]) : path.posix.resolve(...paths);
9
- export const relative = (from, to) => path.posix.relative(to ? toPosix(from) : cwd, toPosix(to ?? from));
9
+ export const relative = (from, to) => toPosix(path.relative(to ? from : cwd, to ?? from));
10
10
  export const isInNodeModules = (filePath) => filePath.includes('node_modules');
11
11
  export const toAbsolute = (id, base) => (isAbsolute(id) ? id : join(base, id));
12
12
  export const toRelative = (id) => (isAbsolute(id) ? relative(id) : id);
@@ -19,7 +19,13 @@ export const normalizePluginConfig = (pluginConfig) => {
19
19
  }
20
20
  else {
21
21
  const isObject = typeof pluginConfig !== 'string' && !Array.isArray(pluginConfig);
22
- const config = isObject ? arrayify(pluginConfig.config) : pluginConfig ? arrayify(pluginConfig) : null;
22
+ const config = isObject
23
+ ? 'config' in pluginConfig
24
+ ? arrayify(pluginConfig.config)
25
+ : null
26
+ : pluginConfig
27
+ ? arrayify(pluginConfig)
28
+ : null;
23
29
  const entry = isObject && 'entry' in pluginConfig ? arrayify(pluginConfig.entry) : null;
24
30
  const project = isObject && 'project' in pluginConfig ? arrayify(pluginConfig.project) : entry;
25
31
  return { config, entry, project };
@@ -12,7 +12,7 @@ const tryResolve = (specifier, from) => {
12
12
  return resolve(specifier);
13
13
  }
14
14
  catch {
15
- debugLog(`Unable to resolve ${specifier} (from ${from})`);
15
+ debugLog('*', `Unable to resolve ${specifier} (from ${from})`);
16
16
  }
17
17
  };
18
18
  const resolveSpecifier = (dir, specifier) => {
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "2.33.2";
1
+ export declare const version = "2.33.4";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '2.33.2';
1
+ export const version = '2.33.4';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "2.33.2",
3
+ "version": "2.33.4",
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",