knip 5.63.1 → 5.64.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.
Files changed (76) hide show
  1. package/dist/ConfigurationChief.d.ts +12 -0
  2. package/dist/DependencyDeputy.js +3 -2
  3. package/dist/IssueFixer.js +3 -1
  4. package/dist/binaries/bash-parser.d.ts +1 -0
  5. package/dist/binaries/bash-parser.js +3 -0
  6. package/dist/binaries/fallback.js +3 -2
  7. package/dist/binaries/package-manager/bun.js +1 -0
  8. package/dist/binaries/plugins.js +3 -1
  9. package/dist/compilers/index.d.ts +20 -0
  10. package/dist/constants.js +2 -0
  11. package/dist/graph/analyze.js +7 -4
  12. package/dist/graph/build.js +7 -7
  13. package/dist/plugins/angular/index.js +2 -3
  14. package/dist/plugins/bumpp/index.d.ts +8 -0
  15. package/dist/plugins/bumpp/index.js +11 -0
  16. package/dist/plugins/eslint/index.d.ts +7 -0
  17. package/dist/plugins/eslint/index.js +12 -0
  18. package/dist/plugins/glob/index.d.ts +0 -1
  19. package/dist/plugins/glob/index.js +0 -1
  20. package/dist/plugins/index.d.ts +19 -7
  21. package/dist/plugins/index.js +4 -0
  22. package/dist/plugins/karma/helpers.js +1 -1
  23. package/dist/plugins/node-modules-inspector/index.d.ts +0 -1
  24. package/dist/plugins/node-modules-inspector/index.js +0 -1
  25. package/dist/plugins/nuxt/index.js +7 -1
  26. package/dist/plugins/nuxt/types.d.ts +1 -1
  27. package/dist/plugins/oxlint/index.d.ts +0 -1
  28. package/dist/plugins/oxlint/index.js +0 -1
  29. package/dist/plugins/playwright/index.d.ts +0 -1
  30. package/dist/plugins/playwright/index.js +0 -1
  31. package/dist/plugins/playwright-test/index.d.ts +0 -1
  32. package/dist/plugins/playwright-test/index.js +0 -1
  33. package/dist/plugins/pnpm/index.d.ts +1 -0
  34. package/dist/plugins/pnpm/index.js +5 -1
  35. package/dist/plugins/prisma/index.d.ts +0 -1
  36. package/dist/plugins/prisma/index.js +0 -1
  37. package/dist/plugins/rslib/index.js +1 -1
  38. package/dist/plugins/rstest/index.d.ts +10 -0
  39. package/dist/plugins/rstest/index.js +29 -0
  40. package/dist/plugins/rstest/types.d.ts +6 -0
  41. package/dist/plugins/rstest/types.js +1 -0
  42. package/dist/plugins/ts-node/index.d.ts +0 -1
  43. package/dist/plugins/ts-node/index.js +0 -1
  44. package/dist/reporters/githubActions.d.ts +3 -0
  45. package/dist/reporters/githubActions.js +94 -0
  46. package/dist/reporters/index.d.ts +1 -0
  47. package/dist/reporters/index.js +2 -0
  48. package/dist/reporters/json.js +1 -1
  49. package/dist/reporters/util/configuration-hints.d.ts +13 -1
  50. package/dist/reporters/util/configuration-hints.js +1 -0
  51. package/dist/schema/configuration.d.ts +112 -0
  52. package/dist/schema/plugins.d.ts +46 -0
  53. package/dist/schema/plugins.js +2 -0
  54. package/dist/types/PluginNames.d.ts +2 -2
  55. package/dist/types/PluginNames.js +2 -0
  56. package/dist/types/args.d.ts +2 -0
  57. package/dist/types/exports.d.ts +1 -1
  58. package/dist/types/imports.d.ts +1 -1
  59. package/dist/types/module-graph.d.ts +5 -4
  60. package/dist/typescript/SourceFile.d.ts +2 -2
  61. package/dist/typescript/ast-helpers.d.ts +4 -0
  62. package/dist/typescript/ast-helpers.js +29 -0
  63. package/dist/typescript/find-internal-references.js +10 -1
  64. package/dist/typescript/get-imports-and-exports.js +27 -17
  65. package/dist/typescript/visitors/dynamic-imports/importCall.js +6 -1
  66. package/dist/util/cli-arguments.d.ts +3 -2
  67. package/dist/util/cli-arguments.js +2 -2
  68. package/dist/util/create-options.d.ts +22 -3
  69. package/dist/util/create-options.js +1 -1
  70. package/dist/util/load-config.d.ts +2 -1
  71. package/dist/util/load-config.js +4 -4
  72. package/dist/util/modules.js +18 -7
  73. package/dist/version.d.ts +1 -1
  74. package/dist/version.js +1 -1
  75. package/package.json +3 -3
  76. package/schema.json +8 -0
@@ -1,7 +1,7 @@
1
1
  import type ts from 'typescript';
2
2
  import type { SymbolType } from './issues.js';
3
3
  type Identifier = string;
4
- type ExportPosTuple = [number, number, number];
4
+ export type ExportPosTuple = [number, number, number];
5
5
  export type Fix = ExportPosTuple | undefined;
6
6
  export type Fixes = Array<ExportPosTuple>;
7
7
  export type ExportNode = {
@@ -4,7 +4,7 @@ export interface ImportNode {
4
4
  identifier: string | undefined;
5
5
  alias?: string | undefined;
6
6
  namespace?: string | undefined;
7
- pos: number | undefined;
7
+ pos: number;
8
8
  symbol?: ts.Symbol;
9
9
  isTypeOnly?: boolean;
10
10
  isReExport?: boolean;
@@ -19,7 +19,7 @@ export type ImportDetails = {
19
19
  reExportedNs: IdToFileMap;
20
20
  };
21
21
  export type ImportMap = Map<FilePath, ImportDetails>;
22
- export type UnresolvedImport = {
22
+ export type Import = {
23
23
  specifier: string;
24
24
  pos?: number;
25
25
  line?: number;
@@ -50,13 +50,14 @@ export type ExportMember = {
50
50
  jsDocTags: Tags;
51
51
  };
52
52
  export type ExportMap = Map<Identifier, Export>;
53
+ export type Specifiers = Set<[Import, FilePath]>;
53
54
  export type FileNode = {
54
55
  imports: {
55
56
  internal: ImportMap;
56
- external: Set<string>;
57
- unresolved: Set<UnresolvedImport>;
57
+ external: Set<Import>;
58
+ unresolved: Set<Import>;
58
59
  resolved: Set<FilePath>;
59
- specifiers: Set<[string, FilePath]>;
60
+ specifiers: Specifiers;
60
61
  };
61
62
  exports: ExportMap;
62
63
  duplicates: Iterable<Array<IssueSymbol>>;
@@ -14,8 +14,8 @@ type PragmaMap = {
14
14
  pos?: number;
15
15
  };
16
16
  types?: {
17
- value?: string;
18
- pos?: number;
17
+ value: string;
18
+ pos: number;
19
19
  };
20
20
  };
21
21
  range?: {
@@ -49,3 +49,7 @@ export declare const isModuleExportsAccess: (node: ts.PropertyAccessExpression)
49
49
  export declare const getImportMap: (sourceFile: ts.SourceFile) => Map<string, string>;
50
50
  export declare const getDefaultImportName: (importMap: ReturnType<typeof getImportMap>, specifier: string) => string | undefined;
51
51
  export declare const getPropertyValues: (node: ts.ObjectLiteralExpression, propertyName: string) => Set<string>;
52
+ export declare const getAccessedIdentifiers: (identifier: string, scope: ts.Node) => {
53
+ identifier: string;
54
+ pos: number;
55
+ }[];
@@ -265,3 +265,32 @@ export const getPropertyValues = (node, propertyName) => {
265
265
  }
266
266
  return values;
267
267
  };
268
+ export const getAccessedIdentifiers = (identifier, scope) => {
269
+ const identifiers = [];
270
+ function visit(node) {
271
+ if (ts.isPropertyAccessExpression(node) && node.expression.getText() === identifier) {
272
+ identifiers.push({ identifier: String(node.name.escapedText), pos: node.name.pos });
273
+ }
274
+ else if (ts.isElementAccessExpression(node) &&
275
+ node.expression.getText() === identifier &&
276
+ ts.isStringLiteral(node.argumentExpression)) {
277
+ identifiers.push({
278
+ identifier: stripQuotes(node.argumentExpression.text),
279
+ pos: node.argumentExpression.pos,
280
+ });
281
+ }
282
+ else if (ts.isVariableDeclaration(node) &&
283
+ node.initializer?.getText() === identifier &&
284
+ ts.isObjectBindingPattern(node.name)) {
285
+ for (const element of node.name.elements) {
286
+ if (ts.isBindingElement(element)) {
287
+ const identifier = (element.propertyName ?? element.name).getText();
288
+ identifiers.push({ identifier, pos: element.pos });
289
+ }
290
+ }
291
+ }
292
+ ts.forEachChild(node, visit);
293
+ }
294
+ visit(scope);
295
+ return identifiers;
296
+ };
@@ -38,12 +38,21 @@ export const findInternalReferences = (item, sourceFile, typeChecker, referenced
38
38
  const declaration = symbol.declarations?.[0];
39
39
  if (declaration) {
40
40
  if (findInFlow(declaration.name?.flowNode, item.symbol)) {
41
- return [++refCount, isSymbolInExport];
41
+ refCount++;
42
+ return [refCount, isSymbolInExport];
42
43
  }
43
44
  if (ts.isImportSpecifier(declaration) && symbols.has(symbol)) {
44
45
  return [++refCount, isSymbolInExport];
45
46
  }
46
47
  }
48
+ if (symbol && symbol.flags & ts.SymbolFlags.Property) {
49
+ const type = typeChecker.getTypeOfSymbol(symbol);
50
+ if (type?.symbol && item.symbol === type.symbol) {
51
+ refCount++;
52
+ if (isBindingElement)
53
+ return [refCount, isSymbolInExport];
54
+ }
55
+ }
47
56
  symbols.add(symbol);
48
57
  }
49
58
  }
@@ -78,7 +78,7 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
78
78
  const addInternalImport = (options) => {
79
79
  const { identifier, symbol, filePath, namespace, alias, specifier, isReExport } = options;
80
80
  const isStar = identifier === IMPORT_STAR;
81
- specifiers.add([specifier, filePath]);
81
+ specifiers.add([{ specifier, pos: options.pos, line: options.line, col: options.col }, filePath]);
82
82
  const file = internal.get(filePath);
83
83
  const imports = file ?? createImports();
84
84
  if (!file)
@@ -112,10 +112,9 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
112
112
  }
113
113
  };
114
114
  const addImport = (opts, node) => {
115
- const { specifier, isTypeOnly, pos, identifier = ANONYMOUS, isReExport = false } = opts;
116
- if (isBuiltin(specifier))
115
+ if (isBuiltin(opts.specifier))
117
116
  return;
118
- const module = resolveModule(specifier);
117
+ const module = resolveModule(opts.specifier);
119
118
  if (module) {
120
119
  const filePath = module.resolvedFileName;
121
120
  if (filePath) {
@@ -124,33 +123,44 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
124
123
  return;
125
124
  }
126
125
  if (!module.isExternalLibraryImport || !isInNodeModules(filePath)) {
127
- addInternalImport({ ...opts, identifier, filePath, isReExport });
126
+ const { line, character } = node.getSourceFile().getLineAndCharacterOfPosition(opts.pos);
127
+ addInternalImport({
128
+ ...opts,
129
+ identifier: opts.identifier ?? ANONYMOUS,
130
+ filePath,
131
+ isReExport: opts.isReExport ?? false,
132
+ line: line + 1,
133
+ col: character + 1,
134
+ });
128
135
  }
129
136
  if (module.isExternalLibraryImport) {
130
- if (options.skipTypeOnly && isTypeOnly)
137
+ if (options.skipTypeOnly && opts.isTypeOnly)
131
138
  return;
132
- const sanitizedSpecifier = sanitizeSpecifier(isInNodeModules(specifier) || isInNodeModules(filePath) ? getPackageNameFromFilePath(specifier) : specifier);
139
+ const isInNM = isInNodeModules(opts.specifier);
140
+ const sanitizedSpecifier = sanitizeSpecifier(isInNM || isInNodeModules(filePath) ? getPackageNameFromFilePath(opts.specifier) : opts.specifier);
133
141
  if (!isStartsLikePackageName(sanitizedSpecifier)) {
134
142
  return;
135
143
  }
136
- external.add(sanitizedSpecifier);
144
+ if (isInNM) {
145
+ external.add({ specifier: sanitizedSpecifier });
146
+ }
147
+ else {
148
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(opts.pos);
149
+ external.add({ specifier: sanitizedSpecifier, pos: opts.pos, line: line + 1, col: character + 2 });
150
+ }
137
151
  }
138
152
  }
139
153
  }
140
154
  else {
141
- if (options.skipTypeOnly && isTypeOnly)
155
+ if (options.skipTypeOnly && opts.isTypeOnly)
142
156
  return;
143
157
  if (shouldIgnore(getJSDocTags(node), options.tags))
144
158
  return;
145
- if (specifier.startsWith(PROTOCOL_VIRTUAL))
159
+ if (opts.specifier.startsWith(PROTOCOL_VIRTUAL))
146
160
  return;
147
- if (typeof pos === 'number') {
148
- const { line, character } = sourceFile.getLineAndCharacterOfPosition(pos);
149
- unresolved.add({ specifier, pos, line: line + 1, col: character + 1 });
150
- }
151
- else {
152
- unresolved.add({ specifier });
153
- }
161
+ const pos = 'moduleSpecifier' in node ? node.moduleSpecifier.pos : node.pos;
162
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(pos);
163
+ unresolved.add({ specifier: opts.specifier, pos, line: line + 1, col: character + 2 });
154
164
  }
155
165
  };
156
166
  const addExport = ({ node, symbol, identifier, type, pos, members = [], fix }) => {
@@ -1,6 +1,6 @@
1
1
  import ts from 'typescript';
2
2
  import { ANONYMOUS } from '../../../constants.js';
3
- import { findAncestor, findDescendants, isAccessExpression, isImportCall, isTopLevel, stripQuotes, } from '../../ast-helpers.js';
3
+ import { findAncestor, findDescendants, getAccessedIdentifiers, isAccessExpression, isImportCall, isTopLevel, stripQuotes, } from '../../ast-helpers.js';
4
4
  import { importVisitor as visit } from '../index.js';
5
5
  const getSymbol = (node, isTopLevel) => (isTopLevel ? node.symbol : undefined);
6
6
  export default visit(() => true, node => {
@@ -64,6 +64,11 @@ export default visit(() => true, node => {
64
64
  if (ts.isIdentifier(variableDeclaration.name)) {
65
65
  const alias = String(variableDeclaration.name.escapedText);
66
66
  const symbol = getSymbol(variableDeclaration, isTLA);
67
+ const scope = findAncestor(variableDeclaration, ts.isFunctionBody) || node.getSourceFile();
68
+ const accessed = getAccessedIdentifiers(alias, scope);
69
+ if (accessed.length > 0) {
70
+ return accessed.map(acc => ({ identifier: acc.identifier, alias, symbol, specifier, pos: acc.pos }));
71
+ }
67
72
  return { identifier: 'default', alias, symbol, specifier, pos: node.arguments[0].pos };
68
73
  }
69
74
  const bindings = findDescendants(variableDeclaration, ts.isBindingElement);
@@ -1,5 +1,6 @@
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 --performance-fn [name] Measure only function [name]\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
- export default function (): {
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, github-actions, 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 --performance-fn [name] Measure only function [name]\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
+ export type ParsedCLIArgs = ReturnType<typeof parseCLIArgs>;
3
+ export default function parseCLIArgs(): {
3
4
  cache?: boolean | undefined;
4
5
  'cache-location'?: string | undefined;
5
6
  config?: string | undefined;
@@ -29,7 +29,7 @@ Options:
29
29
  -n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)
30
30
  --preprocessor Preprocess the results before providing it to the reporter(s), can be repeated
31
31
  --preprocessor-options Pass extra options to the preprocessor (as JSON string, see --reporter-options example)
32
- --reporter Select reporter: symbols, compact, codeowners, json, codeclimate, markdown, disclosure, can be repeated (default: symbols)
32
+ --reporter Select reporter: symbols, compact, codeowners, json, codeclimate, markdown, disclosure, github-actions, can be repeated (default: symbols)
33
33
  --reporter-options Pass extra options to the reporter (as JSON string, see example)
34
34
  --tags Include or exclude tagged exports
35
35
  --no-config-hints Suppress configuration hints
@@ -60,7 +60,7 @@ $ knip --reporter codeowners --reporter-options '{"path":".github/CODEOWNERS"}'
60
60
  $ knip --tags=-lintignore
61
61
 
62
62
  Website: https://knip.dev`;
63
- export default function () {
63
+ export default function parseCLIArgs() {
64
64
  return parseArgs({
65
65
  options: {
66
66
  cache: { type: 'boolean' },
@@ -1,8 +1,7 @@
1
1
  import type { Options } from '../types/options.js';
2
- import type parseArgs from './cli-arguments.js';
3
- type ParsedArgs = ReturnType<typeof parseArgs>;
2
+ import type { ParsedCLIArgs } from './cli-arguments.js';
4
3
  interface CreateOptions extends Partial<Options> {
5
- parsedCLIArgs?: ParsedArgs;
4
+ parsedCLIArgs?: ParsedCLIArgs;
6
5
  }
7
6
  export declare const createOptions: (options: CreateOptions) => Promise<{
8
7
  cacheLocation: string;
@@ -71,6 +70,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
71
70
  entry?: string | string[] | undefined;
72
71
  project?: string | string[] | undefined;
73
72
  } | undefined;
73
+ bumpp?: string | boolean | string[] | {
74
+ config?: string | string[] | undefined;
75
+ entry?: string | string[] | undefined;
76
+ project?: string | string[] | undefined;
77
+ } | undefined;
74
78
  bun?: string | boolean | string[] | {
75
79
  config?: string | string[] | undefined;
76
80
  entry?: string | string[] | undefined;
@@ -431,6 +435,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
431
435
  entry?: string | string[] | undefined;
432
436
  project?: string | string[] | undefined;
433
437
  } | undefined;
438
+ rstest?: string | boolean | string[] | {
439
+ config?: string | string[] | undefined;
440
+ entry?: string | string[] | undefined;
441
+ project?: string | string[] | undefined;
442
+ } | undefined;
434
443
  'semantic-release'?: string | boolean | string[] | {
435
444
  config?: string | string[] | undefined;
436
445
  entry?: string | string[] | undefined;
@@ -652,6 +661,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
652
661
  entry?: string | string[] | undefined;
653
662
  project?: string | string[] | undefined;
654
663
  } | undefined;
664
+ bumpp?: string | boolean | string[] | {
665
+ config?: string | string[] | undefined;
666
+ entry?: string | string[] | undefined;
667
+ project?: string | string[] | undefined;
668
+ } | undefined;
655
669
  bun?: string | boolean | string[] | {
656
670
  config?: string | string[] | undefined;
657
671
  entry?: string | string[] | undefined;
@@ -1012,6 +1026,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
1012
1026
  entry?: string | string[] | undefined;
1013
1027
  project?: string | string[] | undefined;
1014
1028
  } | undefined;
1029
+ rstest?: string | boolean | string[] | {
1030
+ config?: string | string[] | undefined;
1031
+ entry?: string | string[] | undefined;
1032
+ project?: string | string[] | undefined;
1033
+ } | undefined;
1015
1034
  'semantic-release'?: string | boolean | string[] | {
1016
1035
  config?: string | string[] | undefined;
1017
1036
  entry?: string | string[] | undefined;
@@ -30,7 +30,7 @@ export const createOptions = async (options) => {
30
30
  if (parsedCLIArgs.config && !configFilePath && !manifest.knip) {
31
31
  throw new ConfigurationError(`Unable to find ${parsedCLIArgs.config} or package.json#knip`);
32
32
  }
33
- const loadedConfig = Object.assign({}, manifest.knip, configFilePath ? await loadResolvedConfigFile(configFilePath) : {});
33
+ const loadedConfig = Object.assign({}, manifest.knip, configFilePath ? await loadResolvedConfigFile(configFilePath, parsedCLIArgs) : {});
34
34
  const parsedConfig = knipConfigurationSchema.parse(partitionCompilers(loadedConfig));
35
35
  if (!configFilePath && manifest.knip)
36
36
  configFilePath = manifestPath;
@@ -1 +1,2 @@
1
- export declare function loadResolvedConfigFile(configPath: string): Promise<any>;
1
+ import type { ParsedCLIArgs } from './cli-arguments.js';
2
+ export declare function loadResolvedConfigFile(configPath: string, options: ParsedCLIArgs): Promise<any>;
@@ -1,10 +1,10 @@
1
1
  import { debugLogObject } from './debug.js';
2
2
  import { ConfigurationError } from './errors.js';
3
3
  import { _load } from './loader.js';
4
- const unwrapFunction = async (maybeFunction) => {
4
+ const unwrapFunction = async (maybeFunction, options) => {
5
5
  if (typeof maybeFunction === 'function') {
6
6
  try {
7
- return await maybeFunction();
7
+ return await maybeFunction(options);
8
8
  }
9
9
  catch (error) {
10
10
  debugLogObject('*', 'Error executing function:', error);
@@ -13,10 +13,10 @@ const unwrapFunction = async (maybeFunction) => {
13
13
  }
14
14
  return maybeFunction;
15
15
  };
16
- export async function loadResolvedConfigFile(configPath) {
16
+ export async function loadResolvedConfigFile(configPath, options) {
17
17
  const loadedValue = await _load(configPath);
18
18
  try {
19
- return await unwrapFunction(loadedValue);
19
+ return await unwrapFunction(loadedValue, options);
20
20
  }
21
21
  catch (_error) {
22
22
  throw new ConfigurationError(`Error running the function from ${configPath}`);
@@ -38,13 +38,24 @@ export const getPackageFromDefinitelyTyped = (typedDependency) => {
38
38
  }
39
39
  return typedDependency;
40
40
  };
41
- const matchDirectives = /^([?!|-]+)?([^!?:]+).*/;
42
41
  export const sanitizeSpecifier = (specifier) => {
43
- if (isBuiltin(specifier))
42
+ if (isBuiltin(specifier) || isAbsolute(specifier) || specifier.startsWith(PROTOCOL_VIRTUAL))
44
43
  return specifier;
45
- if (isAbsolute(specifier))
46
- return specifier;
47
- if (specifier.startsWith(PROTOCOL_VIRTUAL))
48
- return specifier;
49
- return specifier.replace(matchDirectives, '$2');
44
+ let s = specifier;
45
+ let end = s.length;
46
+ let i = 0;
47
+ while (i < s.length && (s[i] === '!' || s[i] === '-'))
48
+ i++;
49
+ s = s.substring(i);
50
+ for (let j = 0; j < s.length; j++) {
51
+ const char = s[j];
52
+ if (char === '!' || char === '?' || (char === '#' && j > 0)) {
53
+ end = j;
54
+ break;
55
+ }
56
+ }
57
+ s = s.substring(0, end);
58
+ if (s.includes(':') && !s.includes('/'))
59
+ s = s.split(':')[0];
60
+ return s;
50
61
  };
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "5.63.1";
1
+ export declare const version = "5.64.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '5.63.1';
1
+ export const version = '5.64.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "5.63.1",
3
+ "version": "5.64.0",
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": {
@@ -63,7 +63,7 @@
63
63
  "jiti": "^2.5.1",
64
64
  "js-yaml": "^4.1.0",
65
65
  "minimist": "^1.2.8",
66
- "oxc-resolver": "^11.6.2",
66
+ "oxc-resolver": "^11.8.2",
67
67
  "picocolors": "^1.1.1",
68
68
  "picomatch": "^4.0.1",
69
69
  "smol-toml": "^1.4.1",
@@ -86,7 +86,7 @@
86
86
  "@wdio/types": "^9.16.2",
87
87
  "codeclimate-types": "^0.3.1",
88
88
  "glob": "^11.0.2",
89
- "release-it": "^19.0.4",
89
+ "release-it": "^19.0.5",
90
90
  "tsx": "^4.20.3",
91
91
  "typescript": "^5.5.2"
92
92
  },
package/schema.json CHANGED
@@ -319,6 +319,10 @@
319
319
  "title": "biome plugin configuration (https://knip.dev/reference/plugins/biome)",
320
320
  "$ref": "#/definitions/plugin"
321
321
  },
322
+ "bumpp": {
323
+ "title": "bumpp plugin configuration (https://knip.dev/reference/plugins/bumpp)",
324
+ "$ref": "#/definitions/plugin"
325
+ },
322
326
  "bun": {
323
327
  "title": "bun plugin configuration (https://knip.dev/reference/plugins/bun)",
324
328
  "$ref": "#/definitions/plugin"
@@ -607,6 +611,10 @@
607
611
  "title": "rspack plugin configuration (https://knip.dev/reference/plugins/rspack)",
608
612
  "$ref": "#/definitions/plugin"
609
613
  },
614
+ "rstest": {
615
+ "title": "rstest plugin configuration (https://knip.dev/reference/plugins/rstest)",
616
+ "$ref": "#/definitions/plugin"
617
+ },
610
618
  "semantic-release": {
611
619
  "title": "semantic-release plugin configuration (https://knip.dev/reference/plugins/semantic-release)",
612
620
  "$ref": "#/definitions/plugin"