knip 5.34.1 → 5.34.2

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.
@@ -52,9 +52,10 @@ export class IssueCollector {
52
52
  return;
53
53
  const key = relative(this.cwd, issue.filePath);
54
54
  issue.severity = this.rules[issue.type];
55
- this.issues[issue.type][key] = this.issues[issue.type][key] ?? {};
56
- if (!this.issues[issue.type][key][issue.symbol]) {
57
- this.issues[issue.type][key][issue.symbol] = issue;
55
+ const issues = this.issues[issue.type];
56
+ issues[key] = issues[key] ?? {};
57
+ if (!issues[key][issue.symbol]) {
58
+ issues[key][issue.symbol] = issue;
58
59
  this.counters[issue.type]++;
59
60
  }
60
61
  return issue;
@@ -2,10 +2,11 @@ import parse, {} from '../../vendor/bash-parser/index.js';
2
2
  import { pluginArgsMap } from '../plugins.js';
3
3
  import { debugLogObject } from '../util/debug.js';
4
4
  import { toBinary, toDeferResolve } from '../util/input.js';
5
+ import { extractBinary } from '../util/modules.js';
5
6
  import { resolve as fallbackResolve } from './fallback.js';
6
7
  import PackageManagerResolvers from './package-manager/index.js';
7
8
  import { resolve as resolverFromPlugins } from './plugins.js';
8
- import { parseNodeArgs, trimBinary } from './util.js';
9
+ import { parseNodeArgs } from './util.js';
9
10
  const spawningBinaries = ['cross-env', 'retry-cli'];
10
11
  const isExpansion = (node) => 'expansion' in node;
11
12
  const isAssignment = (node) => 'type' in node && node.type === 'AssignmentWord';
@@ -22,7 +23,7 @@ export const getDependenciesFromScript = (script, options) => {
22
23
  switch (node.type) {
23
24
  case 'Command': {
24
25
  const text = node.name?.text;
25
- const binary = text ? trimBinary(text) : text;
26
+ const binary = text ? extractBinary(text) : text;
26
27
  const commandExpansions = node.prefix
27
28
  ?.filter(isExpansion)
28
29
  .map(prefix => prefix.expansion)
@@ -1,7 +1,8 @@
1
1
  import parseArgs from 'minimist';
2
2
  import { toBinary, toDependency } from '../../util/input.js';
3
+ import { stripVersionFromSpecifier } from '../../util/modules.js';
3
4
  import { isInternal } from '../../util/path.js';
4
- import { argsFrom, stripVersionFromSpecifier } from '../util.js';
5
+ import { argsFrom } from '../util.js';
5
6
  export const resolve = (_binary, args, options) => {
6
7
  const { fromArgs } = options;
7
8
  const parsed = parseArgs(args, {
@@ -1,5 +1,3 @@
1
1
  import parseArgs from 'minimist';
2
- export declare const stripVersionFromSpecifier: (specifier: string) => string;
3
- export declare const trimBinary: (command: string) => string;
4
2
  export declare const argsFrom: (args: string[], from: string) => string[];
5
3
  export declare const parseNodeArgs: (args: string[]) => parseArgs.ParsedArgs;
@@ -1,9 +1,4 @@
1
1
  import parseArgs from 'minimist';
2
- export const stripVersionFromSpecifier = (specifier) => specifier.replace(/(\S+)@.*/, '$1');
3
- const stripNodeModulesFromPath = (command) => command.replace(/^(\.\/)?node_modules\//, '');
4
- export const trimBinary = (command) => stripVersionFromSpecifier(stripNodeModulesFromPath(command)
5
- .replace(/^(\.bin\/)/, '')
6
- .replace(/\$\(npm bin\)\/(\w+)/, '$1'));
7
2
  export const argsFrom = (args, from) => args.slice(args.indexOf(from));
8
3
  export const parseNodeArgs = (args) => parseArgs(args, {
9
4
  string: ['r'],
package/dist/index.js CHANGED
@@ -10,9 +10,9 @@ import { _getInputsFromScripts } from './binaries/index.js';
10
10
  import { getCompilerExtensions, getIncludedCompilers } from './compilers/index.js';
11
11
  import { debugLog, debugLogArray, debugLogObject } from './util/debug.js';
12
12
  import { getOrCreateFileNode, updateImportMap } from './util/dependency-graph.js';
13
+ import { getReferencedInputsHandler } from './util/get-referenced-inputs.js';
13
14
  import { getGitIgnoredHandler } from './util/glob-core.js';
14
15
  import { _glob, negate } from './util/glob.js';
15
- import { getReferencedInputsHandler } from './util/handle-referenced-inputs.js';
16
16
  import { getHasStrictlyNsReferences, getType } from './util/has-strictly-ns-references.js';
17
17
  import { isConfigPattern, isEntry, isProductionEntry, toProductionEntry } from './util/input.js';
18
18
  import { getIsIdentifierReferencedHandler } from './util/is-identifier-referenced.js';
@@ -461,7 +461,13 @@ export const main = async (unresolvedConfiguration) => {
461
461
  const packageName = getPackageNameFromModuleSpecifier(specifier);
462
462
  const isHandled = packageName && deputy.maybeAddReferencedExternalDependency(ws, packageName);
463
463
  if (!isHandled)
464
- collector.addIssue({ type: 'unlisted', filePath, workspace: ws.name, symbol: specifier });
464
+ collector.addIssue({
465
+ type: 'unlisted',
466
+ filePath,
467
+ workspace: ws.name,
468
+ symbol: packageName ?? specifier,
469
+ specifier,
470
+ });
465
471
  }
466
472
  }
467
473
  if (file.imports?.unresolved) {
@@ -12,15 +12,18 @@ const resolveConfig = async (localConfig, options) => {
12
12
  const extend = localConfig.extends
13
13
  ? [localConfig.extends].flat().map(specifier => toConfig('typescript', specifier, options.configFilePath))
14
14
  : [];
15
+ const references = localConfig.references
16
+ ?.filter(reference => reference.path.endsWith('.json'))
17
+ .map(reference => toConfig('typescript', reference.path, options.configFilePath)) ?? [];
15
18
  if (!(compilerOptions && localConfig))
16
- return extend;
19
+ return compact([...extend, ...references]);
17
20
  const jsx = (compilerOptions?.jsxImportSource ? [compilerOptions.jsxImportSource] : []).map(toProductionDependency);
18
21
  const types = compilerOptions.types ?? [];
19
22
  const plugins = Array.isArray(compilerOptions?.plugins)
20
23
  ? compilerOptions.plugins.map(plugin => (typeof plugin === 'object' && 'name' in plugin ? plugin.name : ''))
21
24
  : [];
22
25
  const importHelpers = compilerOptions?.importHelpers ? ['tslib'] : [];
23
- return compact([...extend, ...[...types, ...plugins, ...importHelpers].map(toDeferResolve), ...jsx]);
26
+ return compact([...extend, ...references, ...[...types, ...plugins, ...importHelpers].map(toDeferResolve), ...jsx]);
24
27
  };
25
28
  const args = {
26
29
  binaries: ['tsc'],
@@ -3,13 +3,23 @@ import picocolors from 'picocolors';
3
3
  import { ROOT_WORKSPACE_NAME } from '../constants.js';
4
4
  import { relative, toRelative } from '../util/path.js';
5
5
  import { getTitle, identity, logTitle } from './util.js';
6
+ const dim = picocolors.gray;
7
+ const bright = picocolors.whiteBright;
6
8
  const TRUNCATE_WIDTH = 40;
7
9
  const truncate = (text) => (text.length > TRUNCATE_WIDTH ? `${text.slice(0, TRUNCATE_WIDTH - 3)}...` : text);
10
+ const hl = (issue) => {
11
+ if (issue.specifier && issue.specifier !== issue.symbol && issue.specifier.includes(issue.symbol)) {
12
+ const parts = issue.specifier.split(issue.symbol);
13
+ const rest = parts.slice(1).join('');
14
+ return [dim(parts[0]), bright(issue.symbol), dim(rest)].join('');
15
+ }
16
+ return issue.symbol;
17
+ };
8
18
  const logIssueRecord = (issues) => {
9
19
  const table = new EasyTable();
10
20
  for (const issue of issues) {
11
- const print = issue.isFixed || issue.severity === 'warn' ? picocolors.gray : identity;
12
- table.cell('symbol', print(issue.symbols ? truncate(issue.symbols.map(s => s.symbol).join(', ')) : issue.symbol));
21
+ const print = issue.isFixed || issue.severity === 'warn' ? dim : identity;
22
+ table.cell('symbol', print(issue.symbols ? truncate(issue.symbols.map(s => s.symbol).join(', ')) : hl(issue)));
13
23
  issue.parentSymbol && table.cell('parentSymbol', print(issue.parentSymbol));
14
24
  issue.symbolType && table.cell('symbolType', print(issue.symbolType));
15
25
  const pos = issue.line === undefined ? '' : `:${issue.line}${issue.col === undefined ? '' : `:${issue.col}`}`;
@@ -35,9 +45,9 @@ export default ({ report, issues, tagHints, configurationHints, noConfigHints, i
35
45
  for (const issue of issuesForType) {
36
46
  const relPath = toRelative(issue.filePath);
37
47
  if (issue.isFixed)
38
- console.log(picocolors.gray(`${relPath} (removed)`));
48
+ console.log(dim(`${relPath} (removed)`));
39
49
  else if (issue.severity === 'warn')
40
- console.log(picocolors.gray(relPath));
50
+ console.log(dim(relPath));
41
51
  else
42
52
  console.log(relPath);
43
53
  }
@@ -61,7 +71,7 @@ export default ({ report, issues, tagHints, configurationHints, noConfigHints, i
61
71
  const { type, workspaceName, identifier } = hint;
62
72
  const message = `Unused item in ${type}`;
63
73
  const workspace = workspaceName && workspaceName !== ROOT_WORKSPACE_NAME ? ` (workspace: ${workspaceName})` : '';
64
- console.warn(picocolors.gray(`${message}${workspace}:`), identifier);
74
+ console.warn(dim(`${message}${workspace}:`), identifier);
65
75
  }
66
76
  }
67
77
  if (tagHints.size > 0) {
@@ -69,7 +79,7 @@ export default ({ report, issues, tagHints, configurationHints, noConfigHints, i
69
79
  for (const hint of tagHints) {
70
80
  const { filePath, identifier, tagName } = hint;
71
81
  const message = `Unused tag in ${toRelative(filePath)}:`;
72
- console.warn(picocolors.gray(message), `${identifier} → ${tagName}`);
82
+ console.warn(dim(message), `${identifier} → ${tagName}`);
73
83
  }
74
84
  }
75
85
  }
@@ -21,6 +21,7 @@ export type Issue = {
21
21
  symbols?: IssueSymbol[];
22
22
  symbolType?: SymbolType;
23
23
  parentSymbol?: string;
24
+ specifier?: string;
24
25
  severity?: IssueSeverity;
25
26
  pos?: number;
26
27
  line?: number;
@@ -1,7 +1,6 @@
1
- import { trimBinary } from '../binaries/util.js';
2
1
  import { IGNORED_RUNTIME_DEPENDENCIES } from '../constants.js';
3
2
  import { debugLog } from './debug.js';
4
- import { toBinary, toDebugString } from './input.js';
3
+ import { toDebugString } from './input.js';
5
4
  import { fromBinary, isBinary, isConfigPattern, isDeferResolveEntry, isDependency } from './input.js';
6
5
  import { getPackageNameFromSpecifier } from './modules.js';
7
6
  import { dirname, isAbsolute, isInternal, join } from './path.js';
@@ -10,9 +9,6 @@ export const getReferencedInputsHandler = (collector, deputy, chief, isGitIgnore
10
9
  const { specifier, containingFilePath } = input;
11
10
  if (!containingFilePath || IGNORED_RUNTIME_DEPENDENCIES.has(specifier))
12
11
  return;
13
- if (isDeferResolveEntry(input) && specifier.includes('node_modules/.bin')) {
14
- Object.assign(input, toBinary(trimBinary(input.specifier)));
15
- }
16
12
  if (isBinary(input)) {
17
13
  const binaryName = fromBinary(input);
18
14
  const ws = (input.dir && chief.findWorkspaceByFilePath(`${input.dir}/`)) || workspace;
@@ -24,6 +20,7 @@ export const getReferencedInputsHandler = (collector, deputy, chief, isGitIgnore
24
20
  filePath: containingFilePath,
25
21
  workspace: workspace.name,
26
22
  symbol: binaryName,
23
+ specifier,
27
24
  });
28
25
  return;
29
26
  }
@@ -40,7 +37,8 @@ export const getReferencedInputsHandler = (collector, deputy, chief, isGitIgnore
40
37
  type: 'unlisted',
41
38
  filePath: containingFilePath,
42
39
  workspace: specifierWorkspace.name,
43
- symbol: specifier,
40
+ symbol: packageName ?? specifier,
41
+ specifier,
44
42
  });
45
43
  }
46
44
  return;
@@ -68,6 +66,7 @@ export const getReferencedInputsHandler = (collector, deputy, chief, isGitIgnore
68
66
  filePath: containingFilePath,
69
67
  workspace: workspace.name,
70
68
  symbol: packageName ?? specifier,
69
+ specifier,
71
70
  });
72
71
  }
73
72
  else if (!isGitIgnored(filePath)) {
@@ -2,6 +2,8 @@ export declare const getPackageNameFromModuleSpecifier: (moduleSpecifier: string
2
2
  export declare const getPackageNameFromFilePath: (value: string) => string;
3
3
  export declare const getPackageNameFromSpecifier: (specifier: string) => string | undefined;
4
4
  export declare const isStartsLikePackageName: (specifier: string) => boolean;
5
+ export declare const stripVersionFromSpecifier: (specifier: string) => string;
6
+ export declare const extractBinary: (command: string) => string;
5
7
  export declare const isDefinitelyTyped: (packageName: string) => boolean;
6
8
  export declare const getDefinitelyTypedFor: (packageName: string) => string;
7
9
  export declare const getPackageFromDefinitelyTyped: (typedDependency: string) => string;
@@ -9,6 +9,8 @@ export const getPackageNameFromModuleSpecifier = (moduleSpecifier) => {
9
9
  };
10
10
  const lastPackageNameMatch = /(?<=node_modules\/)(@[^/]+\/[^/]+|[^/]+)/g;
11
11
  export const getPackageNameFromFilePath = (value) => {
12
+ if (value.includes('node_modules/.bin/'))
13
+ return extractBinary(value);
12
14
  const match = toPosix(value).match(lastPackageNameMatch);
13
15
  if (match)
14
16
  return match[match.length - 1];
@@ -16,6 +18,11 @@ export const getPackageNameFromFilePath = (value) => {
16
18
  };
17
19
  export const getPackageNameFromSpecifier = (specifier) => isInNodeModules(specifier) ? getPackageNameFromFilePath(specifier) : getPackageNameFromModuleSpecifier(specifier);
18
20
  export const isStartsLikePackageName = (specifier) => /^(@[a-z0-9._]|[a-z0-9])/.test(specifier);
21
+ export const stripVersionFromSpecifier = (specifier) => specifier.replace(/(\S+)@.*/, '$1');
22
+ const stripNodeModulesFromPath = (command) => command.replace(/^(\.\/)?node_modules\//, '');
23
+ export const extractBinary = (command) => stripVersionFromSpecifier(stripNodeModulesFromPath(command)
24
+ .replace(/^(\.bin\/)/, '')
25
+ .replace(/\$\(npm bin\)\/(\w+)/, '$1'));
19
26
  export const isDefinitelyTyped = (packageName) => packageName.startsWith(`${DT_SCOPE}/`);
20
27
  export const getDefinitelyTypedFor = (packageName) => {
21
28
  if (isDefinitelyTyped(packageName))
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "5.34.1";
1
+ export declare const version = "5.34.2";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '5.34.1';
1
+ export const version = '5.34.2';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "5.34.1",
3
+ "version": "5.34.2",
4
4
  "description": "Find unused files, dependencies and exports in your TypeScript and JavaScript projects",
5
5
  "homepage": "https://knip.dev",
6
6
  "repository": {