knip 5.53.0 → 5.54.1

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 (90) hide show
  1. package/dist/IssueFixer.d.ts +1 -1
  2. package/dist/IssueFixer.js +13 -3
  3. package/dist/PrincipalFactory.js +3 -17
  4. package/dist/ProjectPrincipal.d.ts +2 -2
  5. package/dist/ProjectPrincipal.js +14 -3
  6. package/dist/WorkspaceWorker.d.ts +0 -1
  7. package/dist/WorkspaceWorker.js +4 -19
  8. package/dist/cli.js +2 -1
  9. package/dist/graph/build.js +8 -5
  10. package/dist/index.js +15 -4
  11. package/dist/plugins/ava/index.d.ts +1 -2
  12. package/dist/plugins/ava/index.js +2 -7
  13. package/dist/plugins/bun/index.d.ts +2 -2
  14. package/dist/plugins/bun/index.js +2 -2
  15. package/dist/plugins/cucumber/index.d.ts +1 -2
  16. package/dist/plugins/cucumber/index.js +2 -5
  17. package/dist/plugins/cypress/index.d.ts +1 -2
  18. package/dist/plugins/cypress/index.js +6 -9
  19. package/dist/plugins/cypress/types.d.ts +8 -0
  20. package/dist/plugins/eleventy/helpers.d.ts +10 -2
  21. package/dist/plugins/eleventy/index.d.ts +3 -6
  22. package/dist/plugins/eleventy/index.js +11 -16
  23. package/dist/plugins/eleventy/types.d.ts +9 -7
  24. package/dist/plugins/expo/index.d.ts +2 -5
  25. package/dist/plugins/expo/index.js +4 -6
  26. package/dist/plugins/github-action/index.d.ts +2 -2
  27. package/dist/plugins/github-action/index.js +2 -2
  28. package/dist/plugins/index.d.ts +14 -28
  29. package/dist/plugins/jest/index.d.ts +1 -2
  30. package/dist/plugins/jest/index.js +4 -12
  31. package/dist/plugins/karma/index.d.ts +1 -3
  32. package/dist/plugins/karma/index.js +0 -10
  33. package/dist/plugins/ladle/index.d.ts +1 -2
  34. package/dist/plugins/ladle/index.js +4 -7
  35. package/dist/plugins/metro/index.d.ts +2 -3
  36. package/dist/plugins/metro/index.js +17 -14
  37. package/dist/plugins/mocha/index.d.ts +1 -2
  38. package/dist/plugins/mocha/index.js +2 -6
  39. package/dist/plugins/msw/index.d.ts +2 -2
  40. package/dist/plugins/msw/index.js +2 -2
  41. package/dist/plugins/netlify/index.d.ts +1 -2
  42. package/dist/plugins/netlify/index.js +4 -7
  43. package/dist/plugins/node/index.d.ts +2 -2
  44. package/dist/plugins/node/index.js +2 -2
  45. package/dist/plugins/nuxt/index.d.ts +2 -2
  46. package/dist/plugins/nuxt/index.js +2 -2
  47. package/dist/plugins/playwright/index.d.ts +1 -3
  48. package/dist/plugins/playwright/index.js +5 -7
  49. package/dist/plugins/playwright-ct/index.d.ts +0 -1
  50. package/dist/plugins/playwright-ct/index.js +1 -2
  51. package/dist/plugins/postcss/index.js +3 -1
  52. package/dist/plugins/preconstruct/index.d.ts +1 -1
  53. package/dist/plugins/preconstruct/index.js +2 -2
  54. package/dist/plugins/react-cosmos/index.d.ts +1 -2
  55. package/dist/plugins/react-cosmos/index.js +4 -6
  56. package/dist/plugins/react-router/index.d.ts +2 -2
  57. package/dist/plugins/react-router/index.js +2 -2
  58. package/dist/plugins/relay/index.d.ts +2 -2
  59. package/dist/plugins/relay/index.js +2 -2
  60. package/dist/plugins/rspack/index.js +2 -3
  61. package/dist/plugins/size-limit/index.d.ts +2 -1
  62. package/dist/plugins/size-limit/index.js +10 -0
  63. package/dist/plugins/storybook/index.d.ts +1 -2
  64. package/dist/plugins/storybook/index.js +2 -5
  65. package/dist/plugins/svelte/index.d.ts +2 -1
  66. package/dist/plugins/svelte/index.js +7 -0
  67. package/dist/plugins/vite/index.d.ts +0 -1
  68. package/dist/plugins/vite/index.js +1 -2
  69. package/dist/plugins/vitest/index.d.ts +1 -3
  70. package/dist/plugins/vitest/index.js +38 -24
  71. package/dist/plugins/vitest/types.d.ts +12 -0
  72. package/dist/plugins/vue/index.js +2 -5
  73. package/dist/plugins/webpack/index.d.ts +1 -5
  74. package/dist/plugins/webpack/index.js +36 -17
  75. package/dist/plugins/wrangler/index.d.ts +2 -2
  76. package/dist/plugins/wrangler/index.js +2 -2
  77. package/dist/plugins.js +1 -1
  78. package/dist/schema/configuration.d.ts +8 -8
  79. package/dist/types/cli.d.ts +1 -0
  80. package/dist/types/config.d.ts +0 -2
  81. package/dist/types/project.d.ts +0 -1
  82. package/dist/util/cli-arguments.d.ts +2 -1
  83. package/dist/util/cli-arguments.js +2 -0
  84. package/dist/util/glob-core.d.ts +5 -6
  85. package/dist/util/glob-core.js +30 -31
  86. package/dist/util/input.d.ts +7 -1
  87. package/dist/util/input.js +7 -0
  88. package/dist/version.d.ts +1 -1
  89. package/dist/version.js +1 -1
  90. package/package.json +5 -3
@@ -1,6 +1,6 @@
1
1
  import { compact } from '../../util/array.js';
2
- import { toDeferResolve, toDeferResolveEntry, toDeferResolveProductionEntry, toDependency, } from '../../util/input.js';
3
- import { isInternal } from '../../util/path.js';
2
+ import { toAlias, toDeferResolve, toDeferResolveEntry, toDeferResolveProductionEntry, toDependency, } from '../../util/input.js';
3
+ import { isInternal, join, toAbsolute } from '../../util/path.js';
4
4
  import { hasDependency } from '../../util/plugin.js';
5
5
  import { getDependenciesFromConfig } from '../babel/index.js';
6
6
  const title = 'webpack';
@@ -47,7 +47,8 @@ const resolveUseItem = (use) => {
47
47
  return [use.loader];
48
48
  return [];
49
49
  };
50
- export const findWebpackDependenciesFromConfig = async ({ config, cwd }) => {
50
+ export const findWebpackDependenciesFromConfig = async (config, options) => {
51
+ const { cwd } = options;
51
52
  const passes = typeof config === 'function' ? [false, true] : [false];
52
53
  const inputs = new Set();
53
54
  for (const isProduction of passes) {
@@ -55,12 +56,12 @@ export const findWebpackDependenciesFromConfig = async ({ config, cwd }) => {
55
56
  const env = { production: isProduction, mode };
56
57
  const argv = { mode };
57
58
  const resolvedConfig = typeof config === 'function' ? await config(env, argv) : config;
58
- for (const options of [resolvedConfig].flat()) {
59
+ for (const opts of [resolvedConfig].flat()) {
59
60
  const entries = [];
60
- for (const loader of options.module?.rules?.flatMap(resolveRuleSetDependencies) ?? []) {
61
+ for (const loader of opts.module?.rules?.flatMap(resolveRuleSetDependencies) ?? []) {
61
62
  inputs.add(toDeferResolve(loader.replace(/\?.*/, '')));
62
63
  }
63
- for (const plugin of options?.plugins ?? []) {
64
+ for (const plugin of opts?.plugins ?? []) {
64
65
  if (plugin && plugin.constructor.name === 'ProvidePlugin') {
65
66
  const providePluginInstance = plugin;
66
67
  if (providePluginInstance.definitions) {
@@ -71,12 +72,12 @@ export const findWebpackDependenciesFromConfig = async ({ config, cwd }) => {
71
72
  }
72
73
  }
73
74
  }
74
- if (typeof options.entry === 'string')
75
- entries.push(options.entry);
76
- else if (Array.isArray(options.entry))
77
- entries.push(...options.entry);
78
- else if (typeof options.entry === 'object') {
79
- for (const entry of Object.values(options.entry)) {
75
+ if (typeof opts.entry === 'string')
76
+ entries.push(opts.entry);
77
+ else if (Array.isArray(opts.entry))
78
+ entries.push(...opts.entry);
79
+ else if (typeof opts.entry === 'object') {
80
+ for (const entry of Object.values(opts.entry)) {
80
81
  if (typeof entry === 'string')
81
82
  entries.push(entry);
82
83
  else if (Array.isArray(entry))
@@ -92,20 +93,38 @@ export const findWebpackDependenciesFromConfig = async ({ config, cwd }) => {
92
93
  inputs.add(toDependency(entry));
93
94
  }
94
95
  else {
95
- const dir = options.context ? options.context : cwd;
96
- const input = options.mode === 'development'
96
+ const dir = opts.context ? opts.context : cwd;
97
+ const input = opts.mode === 'development'
97
98
  ? toDeferResolveEntry(entry, { dir })
98
99
  : toDeferResolveProductionEntry(entry, { dir });
99
100
  inputs.add(input);
100
101
  }
101
102
  }
103
+ if (opts.resolve?.alias) {
104
+ const addStar = (value) => (value.endsWith('*') ? value : join(value, '*').replace(/\/\*\*$/, '/*'));
105
+ for (const [alias, value] of Object.entries(opts.resolve.alias)) {
106
+ if (!value)
107
+ continue;
108
+ const prefixes = Array.isArray(value) ? value : [value];
109
+ if (alias.endsWith('$')) {
110
+ inputs.add(toAlias(alias.slice(0, -1), prefixes));
111
+ }
112
+ else {
113
+ if (alias.length > 1)
114
+ inputs.add(toAlias(alias, prefixes));
115
+ for (const prefix of prefixes) {
116
+ inputs.add(toAlias(addStar(alias), [addStar(toAbsolute(prefix, options.configFileDir))]));
117
+ }
118
+ }
119
+ }
120
+ }
102
121
  }
103
122
  }
104
- return inputs;
123
+ return Array.from(inputs);
105
124
  };
106
125
  const resolveConfig = async (localConfig, options) => {
107
- const { cwd, manifest } = options;
108
- const inputs = await findWebpackDependenciesFromConfig({ config: localConfig, cwd });
126
+ const { manifest } = options;
127
+ const inputs = await findWebpackDependenciesFromConfig(localConfig, options);
109
128
  const scripts = Object.values(manifest.scripts ?? {});
110
129
  const webpackCLI = scripts.some(script => script && /(?<=^|\s)webpack(?=\s|$)/.test(script)) ? ['webpack-cli'] : [];
111
130
  const webpackDevServer = scripts.some(script => script?.includes('webpack serve')) ? ['webpack-dev-server'] : [];
@@ -1,10 +1,10 @@
1
- import type { IsPluginEnabled, ResolveEntryPaths } from '../../types/config.js';
1
+ import type { IsPluginEnabled, ResolveConfig } from '../../types/config.js';
2
2
  import type { WranglerConfig } from './types.js';
3
3
  declare const _default: {
4
4
  title: string;
5
5
  enablers: string[];
6
6
  isEnabled: IsPluginEnabled;
7
7
  config: string[];
8
- resolveEntryPaths: ResolveEntryPaths<WranglerConfig>;
8
+ resolveConfig: ResolveConfig<WranglerConfig>;
9
9
  };
10
10
  export default _default;
@@ -4,7 +4,7 @@ const title = 'Wrangler';
4
4
  const enablers = ['wrangler'];
5
5
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
6
6
  const config = ['wrangler.{json,toml}'];
7
- const resolveEntryPaths = async (config) => {
7
+ const resolveConfig = async (config) => {
8
8
  return (config.main ? [config.main] : []).map(id => toProductionEntry(id));
9
9
  };
10
10
  export default {
@@ -12,5 +12,5 @@ export default {
12
12
  enablers,
13
13
  isEnabled,
14
14
  config,
15
- resolveEntryPaths,
15
+ resolveConfig,
16
16
  };
package/dist/plugins.js CHANGED
@@ -3,7 +3,7 @@ import { timerify } from './util/Performance.js';
3
3
  import parsedArgValues from './util/cli-arguments.js';
4
4
  const PMap = Plugins;
5
5
  const { performance: isEnabled = false } = parsedArgValues;
6
- const timerifyMethods = ['resolve', 'resolveConfig', 'resolveEntryPaths'];
6
+ const timerifyMethods = ['resolve', 'resolveConfig', 'resolveAST'];
7
7
  const PluginEntries = Object.entries(PMap);
8
8
  if (isEnabled) {
9
9
  for (const [, plugin] of PluginEntries) {
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- export declare const knipConfigurationSchema: z.ZodObject<z.objectUtil.extendShape<z.objectUtil.extendShape<z.objectUtil.extendShape<{
2
+ export declare const knipConfigurationSchema: z.ZodObject<{
3
3
  $schema: z.ZodOptional<z.ZodString>;
4
4
  rules: z.ZodOptional<z.ZodRecord<z.ZodUnion<[z.ZodLiteral<"files">, z.ZodLiteral<"dependencies">, z.ZodLiteral<"devDependencies">, z.ZodLiteral<"optionalPeerDependencies">, z.ZodLiteral<"unlisted">, z.ZodLiteral<"binaries">, z.ZodLiteral<"unresolved">, z.ZodLiteral<"exports">, z.ZodLiteral<"types">, z.ZodLiteral<"nsExports">, z.ZodLiteral<"nsTypes">, z.ZodLiteral<"duplicates">, z.ZodLiteral<"enumMembers">, z.ZodLiteral<"classMembers">]>, z.ZodEnum<["error", "warn", "off"]>>>;
5
5
  entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
@@ -18,11 +18,11 @@ export declare const knipConfigurationSchema: z.ZodObject<z.objectUtil.extendSha
18
18
  asyncCompilers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodFunction<z.ZodTuple<[z.ZodString, z.ZodString], z.ZodUnknown>, z.ZodPromise<z.ZodString>>>>;
19
19
  tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
20
20
  treatConfigHintsAsErrors: z.ZodOptional<z.ZodBoolean>;
21
- }, {
21
+ } & {
22
22
  include: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"files">, z.ZodLiteral<"dependencies">, z.ZodLiteral<"devDependencies">, z.ZodLiteral<"optionalPeerDependencies">, z.ZodLiteral<"unlisted">, z.ZodLiteral<"binaries">, z.ZodLiteral<"unresolved">, z.ZodLiteral<"exports">, z.ZodLiteral<"types">, z.ZodLiteral<"nsExports">, z.ZodLiteral<"nsTypes">, z.ZodLiteral<"duplicates">, z.ZodLiteral<"enumMembers">, z.ZodLiteral<"classMembers">]>, "many">>;
23
23
  exclude: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"files">, z.ZodLiteral<"dependencies">, z.ZodLiteral<"devDependencies">, z.ZodLiteral<"optionalPeerDependencies">, z.ZodLiteral<"unlisted">, z.ZodLiteral<"binaries">, z.ZodLiteral<"unresolved">, z.ZodLiteral<"exports">, z.ZodLiteral<"types">, z.ZodLiteral<"nsExports">, z.ZodLiteral<"nsTypes">, z.ZodLiteral<"duplicates">, z.ZodLiteral<"enumMembers">, z.ZodLiteral<"classMembers">]>, "many">>;
24
- }>, {
25
- workspaces: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<z.objectUtil.extendShape<{
24
+ } & {
25
+ workspaces: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
26
26
  entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
27
27
  project: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
28
28
  paths: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
@@ -32,7 +32,7 @@ export declare const knipConfigurationSchema: z.ZodObject<z.objectUtil.extendSha
32
32
  ignoreMembers: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
33
33
  ignoreUnresolved: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
34
34
  includeEntryExports: z.ZodOptional<z.ZodBoolean>;
35
- }, {
35
+ } & {
36
36
  angular: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
37
37
  config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
38
38
  entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
@@ -1346,7 +1346,7 @@ export declare const knipConfigurationSchema: z.ZodObject<z.objectUtil.extendSha
1346
1346
  entry?: string | string[] | undefined;
1347
1347
  project?: string | string[] | undefined;
1348
1348
  }>]>>;
1349
- }>, "strip", z.ZodTypeAny, {
1349
+ }, "strip", z.ZodTypeAny, {
1350
1350
  node?: string | boolean | string[] | {
1351
1351
  config?: string | string[] | undefined;
1352
1352
  entry?: string | string[] | undefined;
@@ -2377,7 +2377,7 @@ export declare const knipConfigurationSchema: z.ZodObject<z.objectUtil.extendSha
2377
2377
  ignoreUnresolved?: (string | RegExp)[] | undefined;
2378
2378
  includeEntryExports?: boolean | undefined;
2379
2379
  }>>>;
2380
- }>, {
2380
+ } & {
2381
2381
  angular: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
2382
2382
  config: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
2383
2383
  entry: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
@@ -3691,7 +3691,7 @@ export declare const knipConfigurationSchema: z.ZodObject<z.objectUtil.extendSha
3691
3691
  entry?: string | string[] | undefined;
3692
3692
  project?: string | string[] | undefined;
3693
3693
  }>]>>;
3694
- }>, "strict", z.ZodTypeAny, {
3694
+ }, "strict", z.ZodTypeAny, {
3695
3695
  exclude?: ("dependencies" | "exports" | "files" | "devDependencies" | "optionalPeerDependencies" | "unlisted" | "binaries" | "unresolved" | "types" | "nsExports" | "nsTypes" | "duplicates" | "enumMembers" | "classMembers")[] | undefined;
3696
3696
  tags?: string[] | undefined;
3697
3697
  include?: ("dependencies" | "exports" | "files" | "devDependencies" | "optionalPeerDependencies" | "unlisted" | "binaries" | "unresolved" | "types" | "nsExports" | "nsTypes" | "duplicates" | "enumMembers" | "classMembers")[] | undefined;
@@ -11,6 +11,7 @@ export interface CommandLineOptions {
11
11
  isExportsShorthand: boolean;
12
12
  isFilesShorthand: boolean;
13
13
  isFix: boolean;
14
+ isFormat: boolean;
14
15
  isDisableConfigHints: boolean;
15
16
  isIncludeEntryExports: boolean;
16
17
  isIncludeLibs: boolean;
@@ -90,7 +90,6 @@ export interface PluginOptions extends BaseOptions {
90
90
  enabledPlugins: string[];
91
91
  getInputsFromScripts: GetInputsFromScriptsPartial;
92
92
  }
93
- export type ResolveEntryPaths<T = any> = (config: T, options: PluginOptions) => Promise<Input[]> | Input[];
94
93
  export type ResolveConfig<T = any> = (config: T, options: PluginOptions) => Promise<Input[]> | Input[];
95
94
  export type Resolve = (options: PluginOptions) => Promise<Input[]> | Input[];
96
95
  export type GetSourceFile = (filePath: string) => ts.SourceFile | undefined;
@@ -110,7 +109,6 @@ export interface Plugin {
110
109
  entry?: string[];
111
110
  production?: string[];
112
111
  project?: string[];
113
- resolveEntryPaths?: ResolveEntryPaths;
114
112
  resolveConfig?: ResolveConfig;
115
113
  resolve?: Resolve;
116
114
  resolveFromAST?: ResolveFromAST;
@@ -6,7 +6,6 @@ export type PrincipalOptions = {
6
6
  cwd: string;
7
7
  isFile: boolean;
8
8
  compilerOptions: ts.CompilerOptions;
9
- paths: Paths;
10
9
  compilers: [SyncCompilers, AsyncCompilers];
11
10
  pkgName: string;
12
11
  isIsolateWorkspaces: boolean;
@@ -1,4 +1,4 @@
1
- export declare const helpText = "\u2702\uFE0F Find unused dependencies, exports and files in your JavaScript and TypeScript projects\n\nUsage: knip [options]\n\nOptions:\n -c, --config [file] Configuration file path (default: [.]knip.json[c], knip.(js|ts), knip.config.(js|ts) or package.json#knip)\n -t, --tsConfig [file] TypeScript configuration path (default: tsconfig.json)\n --production Analyze only production source files (e.g. no test files, devDependencies)\n --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n -W, --workspace [dir] Analyze a single workspace (default: analyze all configured workspaces)\n --directory [dir] Run process from a different directory (default: cwd)\n --cache Enable caching\n --cache-location Change cache location (default: node_modules/.cache/knip)\n --watch Watch mode\n --no-gitignore Don't use .gitignore\n --include Report only provided issue type(s), can be comma-separated or repeated (1)\n --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)\n --dependencies Shortcut for --include dependencies,unlisted,binaries,unresolved\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --files Shortcut for --include files\n --fix Fix issues\n --fix-type Fix only issues of type, can be comma-separated or repeated (2)\n --allow-remove-files Allow Knip to remove files (with --fix)\n --include-libs Include type definitions from external dependencies (default: false)\n --include-entry-exports Include entry files when reporting unused exports\n --isolate-workspaces Isolate workspaces into separate programs\n -n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)\n --preprocessor Preprocess the results before providing it to the reporter(s), can be repeated\n --preprocessor-options Pass extra options to the preprocessor (as JSON string, see --reporter-options example)\n --reporter Select reporter: symbols, compact, codeowners, json, codeclimate, markdown, disclosure, can be repeated (default: symbols)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --tags Include or exclude tagged exports\n --no-config-hints Suppress configuration hints\n --treat-config-hints-as-errors Exit with non-zero code (1) if there are any configuration hints\n --no-exit-code Always exit with code zero (0)\n --max-issues Maximum number of issues before non-zero exit code (default: 0)\n -d, --debug Show debug output\n --trace Show trace output\n --trace-export [name] Show trace output for named export(s)\n --trace-file [file] Show trace output for exports in file\n --performance Measure count and running time of key functions and display stats table\n --memory Measure memory usage and display data table\n --memory-realtime Log memory usage in realtime\n -h, --help Print this help text\n -V, --version Print version\n\n(1) Issue types: files, dependencies, unlisted, unresolved, exports, nsExports, classMembers, types, nsTypes, enumMembers, duplicates\n(2) Fixable issue types: dependencies, exports, types\n\nExamples:\n\n$ knip\n$ knip --production\n$ knip --workspace packages/client --include files,dependencies\n$ knip -c ./config/knip.json --reporter compact\n$ knip --reporter codeowners --reporter-options '{\"path\":\".github/CODEOWNERS\"}'\n$ knip --tags=-lintignore\n\nWebsite: https://knip.dev";
1
+ export declare const helpText = "\u2702\uFE0F Find unused dependencies, exports and files in your JavaScript and TypeScript projects\n\nUsage: knip [options]\n\nOptions:\n -c, --config [file] Configuration file path (default: [.]knip.json[c], knip.(js|ts), knip.config.(js|ts) or package.json#knip)\n -t, --tsConfig [file] TypeScript configuration path (default: tsconfig.json)\n --production Analyze only production source files (e.g. no test files, devDependencies)\n --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n -W, --workspace [dir] Analyze a single workspace (default: analyze all configured workspaces)\n --directory [dir] Run process from a different directory (default: cwd)\n --cache Enable caching\n --cache-location Change cache location (default: node_modules/.cache/knip)\n --watch Watch mode\n --no-gitignore Don't use .gitignore\n --include Report only provided issue type(s), can be comma-separated or repeated (1)\n --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)\n --dependencies Shortcut for --include dependencies,unlisted,binaries,unresolved\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --files Shortcut for --include files\n --fix Fix issues\n --fix-type Fix only issues of type, can be comma-separated or repeated (2)\n --format Format modified files after --fix using the local formatter\n --allow-remove-files Allow Knip to remove files (with --fix)\n --include-libs Include type definitions from external dependencies (default: false)\n --include-entry-exports Include entry files when reporting unused exports\n --isolate-workspaces Isolate workspaces into separate programs\n -n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)\n --preprocessor Preprocess the results before providing it to the reporter(s), can be repeated\n --preprocessor-options Pass extra options to the preprocessor (as JSON string, see --reporter-options example)\n --reporter Select reporter: symbols, compact, codeowners, json, codeclimate, markdown, disclosure, can be repeated (default: symbols)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --tags Include or exclude tagged exports\n --no-config-hints Suppress configuration hints\n --treat-config-hints-as-errors Exit with non-zero code (1) if there are any configuration hints\n --no-exit-code Always exit with code zero (0)\n --max-issues Maximum number of issues before non-zero exit code (default: 0)\n -d, --debug Show debug output\n --trace Show trace output\n --trace-export [name] Show trace output for named export(s)\n --trace-file [file] Show trace output for exports in file\n --performance Measure count and running time of key functions and display stats table\n --memory Measure memory usage and display data table\n --memory-realtime Log memory usage in realtime\n -h, --help Print this help text\n -V, --version Print version\n\n(1) Issue types: files, dependencies, unlisted, unresolved, exports, nsExports, classMembers, types, nsTypes, enumMembers, duplicates\n(2) Fixable issue types: dependencies, exports, types\n\nExamples:\n\n$ knip\n$ knip --production\n$ knip --workspace packages/client --include files,dependencies\n$ knip -c ./config/knip.json --reporter compact\n$ knip --reporter codeowners --reporter-options '{\"path\":\".github/CODEOWNERS\"}'\n$ knip --tags=-lintignore\n\nWebsite: https://knip.dev";
2
2
  declare const _default: {
3
3
  cache?: boolean | undefined;
4
4
  'cache-location'?: string | undefined;
@@ -13,6 +13,7 @@ declare const _default: {
13
13
  files?: boolean | undefined;
14
14
  fix?: boolean | undefined;
15
15
  'fix-type'?: string[] | undefined;
16
+ format?: boolean | undefined;
16
17
  'allow-remove-files'?: boolean | undefined;
17
18
  help?: boolean | undefined;
18
19
  'ignore-internal'?: boolean | undefined;
@@ -21,6 +21,7 @@ Options:
21
21
  --files Shortcut for --include files
22
22
  --fix Fix issues
23
23
  --fix-type Fix only issues of type, can be comma-separated or repeated (2)
24
+ --format Format modified files after --fix using the local formatter
24
25
  --allow-remove-files Allow Knip to remove files (with --fix)
25
26
  --include-libs Include type definitions from external dependencies (default: false)
26
27
  --include-entry-exports Include entry files when reporting unused exports
@@ -75,6 +76,7 @@ try {
75
76
  files: { type: 'boolean' },
76
77
  fix: { type: 'boolean' },
77
78
  'fix-type': { type: 'string', multiple: true },
79
+ format: { type: 'boolean' },
78
80
  'allow-remove-files': { type: 'boolean' },
79
81
  help: { type: 'boolean', short: 'h' },
80
82
  'ignore-internal': { type: 'boolean' },
@@ -3,13 +3,12 @@ type Options = {
3
3
  gitignore: boolean;
4
4
  cwd: string;
5
5
  };
6
- type GlobOptions = {
7
- readonly gitignore: boolean;
8
- readonly cwd: string;
9
- readonly dir: string;
6
+ interface GlobOptions extends FastGlobOptions {
7
+ gitignore: boolean;
8
+ cwd: string;
9
+ dir: string;
10
10
  label?: string;
11
- } & FastGlobOptionsWithoutCwd;
12
- type FastGlobOptionsWithoutCwd = Pick<FastGlobOptions, 'onlyDirectories' | 'ignore' | 'absolute' | 'dot'>;
11
+ }
13
12
  export declare const findAndParseGitignores: (cwd: string) => Promise<{
14
13
  gitignoreFiles: string[];
15
14
  ignores: Set<string>;
@@ -48,59 +48,58 @@ export const findAndParseGitignores = async (cwd) => {
48
48
  const dir = dirname(toPosix(filePath));
49
49
  const base = relative(cwd, dir);
50
50
  const ancestor = base.startsWith('..') ? `${relative(dir, cwd)}/` : undefined;
51
- const dirIgnores = new Set(base === '' ? init : []);
52
- const dirUnignores = new Set();
51
+ const ignoresForDir = new Set(base === '' ? init : []);
52
+ const unignoresForDir = new Set();
53
53
  const patterns = readFileSync(filePath, 'utf8');
54
54
  for (const rule of parseAndConvertGitignorePatterns(patterns, ancestor)) {
55
- const [pattern1, pattern2] = rule.patterns;
55
+ const [pattern, extraPattern] = rule.patterns;
56
56
  if (rule.negated) {
57
57
  if (base === '' || base.startsWith('..')) {
58
- if (!unignores.includes(pattern2)) {
58
+ if (!unignores.includes(extraPattern)) {
59
59
  unignores.push(...rule.patterns);
60
- dirUnignores.add(pattern1);
61
- dirUnignores.add(pattern2);
60
+ unignoresForDir.add(pattern);
61
+ unignoresForDir.add(extraPattern);
62
62
  }
63
63
  }
64
64
  else {
65
- if (!unignores.includes(pattern2.startsWith('**/') ? pattern2 : `**/${pattern2}`)) {
66
- const unignore = join(base, pattern1);
67
- const extraUnignore = join(base, pattern2);
65
+ if (!unignores.includes(extraPattern.startsWith('**/') ? extraPattern : `**/${extraPattern}`)) {
66
+ const unignore = join(base, pattern);
67
+ const extraUnignore = join(base, extraPattern);
68
68
  unignores.push(unignore, extraUnignore);
69
- dirUnignores.add(unignore);
70
- dirUnignores.add(extraUnignore);
69
+ unignoresForDir.add(unignore);
70
+ unignoresForDir.add(extraUnignore);
71
71
  }
72
72
  }
73
73
  }
74
74
  else {
75
75
  if (base === '' || base.startsWith('..')) {
76
- ignores.add(pattern1);
77
- ignores.add(pattern2);
78
- dirIgnores.add(pattern1);
79
- dirIgnores.add(pattern2);
76
+ ignores.add(pattern);
77
+ ignores.add(extraPattern);
78
+ ignoresForDir.add(pattern);
79
+ ignoresForDir.add(extraPattern);
80
80
  }
81
- else {
82
- if (!(pattern1.startsWith('**/') && ignores.has(pattern1))) {
83
- const ignore = join(base, pattern1);
84
- const extraIgnore = join(base, pattern2);
85
- ignores.add(ignore);
86
- ignores.add(extraIgnore);
87
- dirIgnores.add(ignore);
88
- dirIgnores.add(extraIgnore);
89
- }
81
+ else if (!unignores.includes(extraPattern.startsWith('**/') ? extraPattern : `**/${extraPattern}`)) {
82
+ const ignore = join(base, pattern);
83
+ const extraIgnore = join(base, extraPattern);
84
+ ignores.add(ignore);
85
+ ignores.add(extraIgnore);
86
+ ignoresForDir.add(ignore);
87
+ ignoresForDir.add(extraIgnore);
90
88
  }
91
89
  }
92
90
  }
93
91
  const cacheDir = ancestor ? cwd : dir;
94
92
  const cacheForDir = cachedGitIgnores.get(cacheDir);
95
93
  if (cacheForDir) {
96
- for (const pattern of dirIgnores)
94
+ for (const pattern of ignoresForDir)
97
95
  cacheForDir.ignores.add(pattern);
98
- cacheForDir.unignores = Array.from(new Set([...cacheForDir.unignores, ...dirUnignores]));
96
+ for (const pattern of unignoresForDir)
97
+ cacheForDir.unignores.add(pattern);
99
98
  }
100
99
  else {
101
- cachedGitIgnores.set(cacheDir, { ignores: dirIgnores, unignores: Array.from(dirUnignores) });
100
+ cachedGitIgnores.set(cacheDir, { ignores: ignoresForDir, unignores: unignoresForDir });
102
101
  }
103
- for (const pattern of dirIgnores)
102
+ for (const pattern of ignoresForDir)
104
103
  matchers.add(_picomatch(pattern, pmOptions));
105
104
  };
106
105
  findAncestorGitignoreFiles(cwd).forEach(addFile);
@@ -152,11 +151,11 @@ export async function glob(patterns, options) {
152
151
  cachedGlobIgnores.set(options.dir, compact(_ignore));
153
152
  const { dir, label, ...fgOptions } = { ...options, ignore };
154
153
  const paths = await fg.glob(patterns, fgOptions);
155
- const name = relative(options.cwd, dir);
156
- debugLogObject(name || ROOT_WORKSPACE_NAME, label ? `Finding ${label}` : 'Finding paths', () => ({
154
+ const name = relative(options.cwd, dir) || ROOT_WORKSPACE_NAME;
155
+ debugLogObject(name, label ? `Finding ${label}` : 'Finding paths', () => ({
157
156
  patterns,
158
157
  ...fgOptions,
159
- ignore: hasCache ? `// identical to ${name}` : ignore,
158
+ ignore: hasCache ? `// using cache from ${name}` : ignore,
160
159
  paths,
161
160
  }));
162
161
  return paths;
@@ -1,5 +1,5 @@
1
1
  import type { PluginName } from '../types/PluginNames.js';
2
- type InputType = 'binary' | 'entry' | 'project' | 'config' | 'dependency' | 'deferResolve' | 'deferResolveEntry';
2
+ type InputType = 'binary' | 'entry' | 'project' | 'config' | 'dependency' | 'deferResolve' | 'deferResolveEntry' | 'alias';
3
3
  export interface Input {
4
4
  type: InputType;
5
5
  specifier: string;
@@ -15,6 +15,10 @@ export interface ConfigInput extends Input {
15
15
  containingFilePath?: string;
16
16
  pluginName: PluginName;
17
17
  }
18
+ interface AliasInput extends Input {
19
+ type: 'alias';
20
+ prefixes: string[];
21
+ }
18
22
  type Options = {
19
23
  optional?: boolean;
20
24
  dir?: string;
@@ -41,5 +45,7 @@ export declare const toDeferResolveProductionEntry: (specifier: string, options?
41
45
  export declare const isDeferResolveProductionEntry: (input: Input) => boolean;
42
46
  export declare const toDeferResolveEntry: (specifier: string, options?: Options) => Input;
43
47
  export declare const isDeferResolveEntry: (input: Input) => boolean;
48
+ export declare const toAlias: (specifier: string, prefixes: string[], options?: Options) => AliasInput;
49
+ export declare const isAlias: (input: Input) => input is AliasInput;
44
50
  export declare const toDebugString: (input: Input) => string;
45
51
  export {};
@@ -50,4 +50,11 @@ export const toDeferResolveEntry = (specifier, options = {}) => ({
50
50
  ...options,
51
51
  });
52
52
  export const isDeferResolveEntry = (input) => input.type === 'deferResolveEntry';
53
+ export const toAlias = (specifier, prefixes, options = {}) => ({
54
+ type: 'alias',
55
+ specifier,
56
+ prefixes,
57
+ ...options,
58
+ });
59
+ export const isAlias = (input) => input.type === 'alias';
53
60
  export const toDebugString = (input) => `${input.type}:${isAbsolute(input.specifier) ? toRelative(input.specifier) : input.specifier}${input.containingFilePath ? ` (${toRelative(input.containingFilePath)})` : ''}`;
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "5.53.0";
1
+ export declare const version = "5.54.1";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '5.53.0';
1
+ export const version = '5.54.1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "5.53.0",
3
+ "version": "5.54.1",
4
4
  "description": "Find and fix unused dependencies, exports and files in your TypeScript and JavaScript projects",
5
5
  "homepage": "https://knip.dev",
6
6
  "repository": {
@@ -42,8 +42,9 @@
42
42
  "format": "biome format --write .",
43
43
  "test": "bun test test/*.test.ts test/**/*.test.ts",
44
44
  "test:watch": "bun test test/*.test.ts test/**/*.test.ts --reporter=junit --reporter-outfile=junit.xml || bun test --watch $(grep -o 'name=\"[^\"]*\".*failures=\"[^0]' junit.xml | grep -v 'name=\"bun test\"' | grep -o 'name=\"[^\"]*\"' | cut -d'\"' -f2)",
45
- "test:node": "glob -c \"npx -y tsx --test --import ./transform-test.js\" \"test/**/*.test.ts\"",
46
45
  "test:smoke": "bun test test/*.test.ts test/{plugins,util}/*.test.ts",
46
+ "test:node": "tsx --test --import ./transform-test.js test/**/*.test.ts test/*.test.ts",
47
+ "test:node:smoke": "tsx --test --import ./transform-test.js {test/*.test.ts,test/plugins/*.test.ts,test/util/*.test.ts}",
47
48
  "watch": "npm link && tsc --watch",
48
49
  "prebuild": "npm run generate-plugin-defs && node rmdir.js dist",
49
50
  "build": "tsc",
@@ -63,6 +64,7 @@
63
64
  "@nodelib/fs.walk": "^1.2.3",
64
65
  "enhanced-resolve": "^5.18.1",
65
66
  "fast-glob": "^3.3.3",
67
+ "formatly": "^0.2.3",
66
68
  "jiti": "^2.4.2",
67
69
  "js-yaml": "^4.1.0",
68
70
  "minimist": "^1.2.8",
@@ -87,8 +89,8 @@
87
89
  "@types/webpack": "^5.28.5",
88
90
  "@wdio/types": "^9.5.0",
89
91
  "codeclimate-types": "^0.3.1",
90
- "glob": "^10.4.2",
91
92
  "release-it": "^19.0.1",
93
+ "tsx": "^4.19.4",
92
94
  "type-fest": "^4.31.0",
93
95
  "typescript": "^5.5.2"
94
96
  },