knip 2.15.5 → 2.16.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.
@@ -1,14 +1,12 @@
1
1
  import parse from '@ericcornelissen/bash-parser';
2
- import parseArgs from 'minimist';
3
2
  import { debugLogObject } from '../util/debug.js';
4
3
  import * as FallbackResolver from './resolvers/fallback.js';
5
4
  import * as KnownResolvers from './resolvers/index.js';
6
- import { stripBinaryPath, toBinary } from './util.js';
7
- const spawningBinaries = ['cross-env', 'dotenv'];
5
+ import { stripBinaryPath } from './util.js';
8
6
  export const getBinariesFromScript = (script, { cwd, manifest, knownGlobalsOnly = false }) => {
9
7
  if (!script)
10
8
  return [];
11
- const fromArgs = (args) => getBinariesFromScript(args.join(' '), { cwd, manifest });
9
+ const fromArgs = (args) => getBinariesFromScript(args.filter(arg => arg !== '--').join(' '), { cwd, manifest });
12
10
  const getBinariesFromNodes = (nodes) => nodes.flatMap(node => {
13
11
  switch (node.type) {
14
12
  case 'Command': {
@@ -31,25 +29,16 @@ export const getBinariesFromScript = (script, { cwd, manifest, knownGlobalsOnly
31
29
  }
32
30
  if (knownGlobalsOnly)
33
31
  return [];
34
- if (spawningBinaries.includes(binary)) {
35
- const parsedArgs = parseArgs(args);
36
- const [spawnedBinary] = parsedArgs._;
37
- if (spawnedBinary) {
38
- const restArgs = args.slice(args.indexOf(spawnedBinary));
39
- return [toBinary(binary), ...fromArgs(restArgs)];
40
- }
41
- else {
42
- return [];
43
- }
44
- }
45
32
  return FallbackResolver.resolve(binary, args, { cwd, manifest, fromArgs });
46
33
  }
47
34
  case 'LogicalExpression':
48
35
  return getBinariesFromNodes([node.left, node.right]);
49
36
  case 'If':
50
- return getBinariesFromNodes([...node.clause.commands, ...node.then.commands]);
37
+ return getBinariesFromNodes([...node.clause.commands, ...node.then.commands, ...(node.else?.commands ?? [])]);
51
38
  case 'For':
52
39
  return getBinariesFromNodes(node.do.commands);
40
+ case 'CompoundList':
41
+ return getBinariesFromNodes(node.commands);
53
42
  default:
54
43
  return [];
55
44
  }
@@ -0,0 +1,2 @@
1
+ import type { Resolver } from '../types.js';
2
+ export declare const resolve: Resolver;
@@ -0,0 +1,9 @@
1
+ import parseArgs from 'minimist';
2
+ import { toBinary } from '../util.js';
3
+ export const resolve = (binary, args, { fromArgs }) => {
4
+ const parsed = parseArgs(args, {
5
+ boolean: ['all', 'check-coverage', 'clean', 'exclude-after-remap', 'per-file', 'skip-full'],
6
+ });
7
+ parsed._ = parsed._.filter(a => a !== 'check-coverage');
8
+ return [toBinary(binary), ...fromArgs(parsed._)];
9
+ };
@@ -0,0 +1,2 @@
1
+ import type { Resolver } from '../types.js';
2
+ export declare const resolve: Resolver;
@@ -0,0 +1,6 @@
1
+ import parseArgs from 'minimist';
2
+ import { toBinary } from '../util.js';
3
+ export const resolve = (binary, args, { fromArgs }) => {
4
+ const parsed = parseArgs(args);
5
+ return [toBinary(binary), ...fromArgs(parsed._)];
6
+ };
@@ -13,10 +13,11 @@ const argFilters = {
13
13
  tsx: parsed => parsed._.filter(p => p !== 'watch'),
14
14
  default: withoutPositional,
15
15
  };
16
- export const resolve = (binary, args, { cwd }) => {
16
+ const spawningBinaries = ['cross-env'];
17
+ export const resolve = (binary, args, { cwd, fromArgs }) => {
17
18
  const parsed = parseArgs(args, { string: ['r'], alias: { require: ['r', 'loader'] }, boolean: ['quiet', 'verbose'] });
18
- const argFilter = argFilters[binary] ?? argFilters.default;
19
- const filteredArgs = compact(argFilter(parsed));
20
- const bin = binary.startsWith('.') ? tryResolveFilePath(cwd, binary) : [toBinary(binary)];
21
- return [...bin, ...tryResolveSpecifiers(cwd, filteredArgs)];
19
+ const bin = binary.startsWith('.') ? tryResolveFilePath(cwd, binary) : toBinary(binary);
20
+ const filteredArgs = binary in argFilters ? argFilters[binary](parsed) : argFilters.default(parsed);
21
+ const shiftedArgs = spawningBinaries.includes(binary) ? fromArgs(args) : [];
22
+ return compact([bin, ...tryResolveSpecifiers(cwd, filteredArgs), ...shiftedArgs]);
22
23
  };
@@ -1,3 +1,5 @@
1
+ export * as c8 from './c8.js';
2
+ export * as dotenv from './dotenv.js';
1
3
  export * as node from './node.js';
2
4
  export * as npx from './npx.js';
3
5
  export * as pnpm from './pnpm.js';
@@ -1,3 +1,5 @@
1
+ export * as c8 from './c8.js';
2
+ export * as dotenv from './dotenv.js';
1
3
  export * as node from './node.js';
2
4
  export * as npx from './npx.js';
3
5
  export * as pnpm from './pnpm.js';
@@ -1,6 +1,7 @@
1
1
  import parseArgs from 'minimist';
2
+ import { compact } from '../../util/array.js';
2
3
  import { tryResolveFilePath, tryResolveSpecifiers } from '../util.js';
3
4
  export const resolve = (binary, args, { cwd }) => {
4
5
  const parsed = parseArgs(args, { string: ['r'], alias: { require: ['r', 'loader', 'experimental-loader'] } });
5
- return [...tryResolveFilePath(cwd, parsed._[0]), ...tryResolveSpecifiers(cwd, [parsed.require].flat())];
6
+ return compact([tryResolveFilePath(cwd, parsed._[0]), ...tryResolveSpecifiers(cwd, [parsed.require].flat())]);
6
7
  };
@@ -1,10 +1,24 @@
1
1
  import parseArgs from 'minimist';
2
- import { fromBinary } from '../util.js';
3
- export const resolve = (binary, args, { fromArgs }) => {
4
- const parsed = parseArgs(args, { '--': true, stopEarly: true, boolean: ['yes', 'no'], alias: { yes: 'y', no: 'n' } });
2
+ import { isInternal } from '../../util/path.js';
3
+ import { fromBinary, toBinary } from '../util.js';
4
+ export const resolve = (binary, args, { fromArgs, manifest }) => {
5
+ const parsed = parseArgs(args, {
6
+ '--': true,
7
+ stopEarly: true,
8
+ boolean: ['yes', 'no'],
9
+ alias: { yes: 'y', no: 'no-install' },
10
+ });
5
11
  const leftParsed = fromArgs(parsed._);
6
- const left = parsed.yes ? leftParsed.slice(1) : leftParsed;
7
- const packageName = left[0] ? [fromBinary(left[0])] : [];
8
- const right = parsed['--'] ? fromArgs(parsed['--']) : [];
9
- return [...packageName, ...left.slice(1), ...right];
12
+ const leftHandCommand = parsed.yes ? leftParsed.slice(1) : leftParsed;
13
+ const rightHandCommand = parsed['--'] ? fromArgs(parsed['--']) : [];
14
+ const binaryOrPackageName = fromBinary(leftHandCommand[0] ?? rightHandCommand[0]);
15
+ const dependencies = manifest
16
+ ? [...Object.keys(manifest.dependencies ?? {}), ...Object.keys(manifest.devDependencies ?? {})]
17
+ : [];
18
+ const dependency = !binaryOrPackageName.startsWith('@') &&
19
+ !isInternal(binaryOrPackageName) &&
20
+ !dependencies.includes(binaryOrPackageName)
21
+ ? toBinary(binaryOrPackageName)
22
+ : binaryOrPackageName;
23
+ return [dependency, ...leftHandCommand.slice(1), ...rightHandCommand];
10
24
  };
@@ -1,4 +1,5 @@
1
1
  import parseArgs from 'minimist';
2
+ import { compact } from '../../util/array.js';
2
3
  import { toBinary, tryResolveSpecifiers } from '../util.js';
3
4
  export const resolve = (binary, args, { cwd, fromArgs }) => {
4
5
  const safeArgs = args.filter(arg => arg !== '--watch');
@@ -6,5 +7,5 @@ export const resolve = (binary, args, { cwd, fromArgs }) => {
6
7
  const watchers = parsed.watch ? fromArgs(Object.values(parsed.watch)) : [];
7
8
  const plugins = parsed.plugin ? tryResolveSpecifiers(cwd, [parsed.plugin].flat()) : [];
8
9
  const configPlugins = parsed.configPlugin ? tryResolveSpecifiers(cwd, [parsed.configPlugin].flat()) : [];
9
- return [toBinary(binary), ...watchers, ...plugins, ...configPlugins];
10
+ return compact([toBinary(binary), ...watchers, ...plugins, ...configPlugins]);
10
11
  };
@@ -1,5 +1,5 @@
1
- export declare const tryResolveFilePath: (cwd: string, specifier: string, acceptModuleSpecifier?: boolean) => string[];
2
- export declare const tryResolveSpecifiers: (cwd: string, specifiers: string[]) => string[];
1
+ export declare const tryResolveFilePath: (cwd: string, specifier: string, acceptModuleSpecifier?: boolean) => string | undefined;
2
+ export declare const tryResolveSpecifiers: (cwd: string, specifiers: string[]) => (string | undefined)[];
3
3
  export declare const toBinary: (specifier: string) => string;
4
4
  export declare const fromBinary: (specifier: string) => string;
5
5
  export declare const isBinary: (specifier: string) => boolean;
@@ -7,20 +7,21 @@ export const tryResolveFilePath = (cwd, specifier, acceptModuleSpecifier) => {
7
7
  if (!isInNodeModules(filePath)) {
8
8
  const resolvedFilePath = _tryResolve(filePath, cwd);
9
9
  if (resolvedFilePath) {
10
- return [resolvedFilePath];
10
+ return resolvedFilePath;
11
11
  }
12
12
  else if (acceptModuleSpecifier) {
13
- const packageName = getPackageNameFromModuleSpecifier(specifier);
14
- return packageName ? [packageName] : [];
13
+ return getPackageNameFromModuleSpecifier(specifier);
15
14
  }
16
15
  }
16
+ else if (specifier.includes('node_modules/.bin')) {
17
+ return toBinary(stripBinaryPath(specifier));
18
+ }
17
19
  else {
18
- return [getPackageNameFromFilePath(specifier)];
20
+ return getPackageNameFromFilePath(specifier);
19
21
  }
20
22
  }
21
- return [];
22
23
  };
23
- export const tryResolveSpecifiers = (cwd, specifiers) => specifiers.flatMap(specifier => tryResolveFilePath(cwd, specifier, true));
24
+ export const tryResolveSpecifiers = (cwd, specifiers) => specifiers.map(specifier => tryResolveFilePath(cwd, specifier, true));
24
25
  export const toBinary = (specifier) => specifier.replace(/^(bin:)?/, 'bin:');
25
26
  export const fromBinary = (specifier) => specifier.replace(/^(bin:)?/, '');
26
27
  export const isBinary = (specifier) => specifier.startsWith('bin:');
package/dist/constants.js CHANGED
@@ -8,26 +8,27 @@ export const TEST_FILE_PATTERNS = [
8
8
  export const IGNORED_GLOBAL_BINARIES = [
9
9
  'bash',
10
10
  'bun',
11
- 'deno',
12
- 'git',
13
- 'node',
14
- 'npm',
15
- 'npx',
16
- 'pnpm',
17
- 'pnpx',
18
- 'true',
19
- 'yarn',
20
11
  'cat',
21
12
  'cd',
22
13
  'cp',
14
+ 'deno',
23
15
  'echo',
16
+ 'exec',
24
17
  'exit',
18
+ 'git',
25
19
  'grep',
26
20
  'mkdir',
27
21
  'mv',
22
+ 'node',
23
+ 'npm',
24
+ 'npx',
25
+ 'pnpm',
26
+ 'pnpx',
28
27
  'rm',
29
28
  'sh',
30
29
  'sudo',
30
+ 'true',
31
+ 'yarn',
31
32
  ];
32
33
  export const IGNORED_DEPENDENCIES = ['knip', 'typescript'];
33
34
  export const IGNORED_FILE_EXTENSIONS = [
@@ -0,0 +1 @@
1
+ export declare const getGitHooksPath: () => string;
@@ -0,0 +1,9 @@
1
+ import { execSync } from 'child_process';
2
+ export const getGitHooksPath = () => {
3
+ try {
4
+ return execSync('git config --get core.hooksPath', { encoding: 'utf8' }).trim();
5
+ }
6
+ catch (error) {
7
+ return '.husky';
8
+ }
9
+ };
@@ -2,14 +2,16 @@ import { readFileSync } from 'fs';
2
2
  import { _getDependenciesFromScripts } from '../../binaries/index.js';
3
3
  import { timerify } from '../../util/Performance.js';
4
4
  import { hasDependency } from '../../util/plugin.js';
5
+ import { getGitHooksPath } from './helpers.js';
5
6
  export const NAME = 'husky';
6
7
  export const ENABLERS = ['husky'];
7
8
  export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
9
+ const gitHooksPath = getGitHooksPath();
8
10
  export const CONFIG_FILE_PATTERNS = [
9
- '.husky/prepare-commit-msg',
10
- '.husky/commit-msg',
11
- '.husky/pre-{applypatch,commit,merge-commit,push,rebase,receive}',
12
- '.husky/post-{checkout,commit,merge,rewrite}',
11
+ `${gitHooksPath}/prepare-commit-msg`,
12
+ `${gitHooksPath}/commit-msg`,
13
+ `${gitHooksPath}/pre-{applypatch,commit,merge-commit,push,rebase,receive}`,
14
+ `${gitHooksPath}/post-{checkout,commit,merge,rewrite}`,
13
15
  ];
14
16
  const findHuskyDependencies = async (configFilePath, { cwd, manifest }) => {
15
17
  const script = readFileSync(configFilePath);
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "2.15.5";
1
+ export declare const version = "2.16.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '2.15.5';
1
+ export const version = '2.16.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "2.15.5",
3
+ "version": "2.16.0",
4
4
  "description": "Find unused files, dependencies and exports in your TypeScript and JavaScript projects",
5
5
  "homepage": "https://github.com/webpro/knip",
6
6
  "repository": "github:webpro/knip",
@@ -67,23 +67,23 @@
67
67
  "@types/js-yaml": "4.0.5",
68
68
  "@types/micromatch": "4.0.2",
69
69
  "@types/minimist": "1.2.2",
70
- "@types/node": "20.4.1",
70
+ "@types/node": "20.4.2",
71
71
  "@types/npmcli__map-workspaces": "3.0.1",
72
72
  "@types/webpack": "5.28.1",
73
73
  "@typescript-eslint/eslint-plugin": "6.0.0",
74
74
  "@typescript-eslint/parser": "6.0.0",
75
75
  "c8": "8.0.0",
76
- "eslint": "8.44.0",
76
+ "eslint": "8.45.0",
77
77
  "eslint-import-resolver-typescript": "3.5.5",
78
78
  "eslint-plugin-import": "2.27.5",
79
79
  "eslint-plugin-n": "16.0.1",
80
80
  "glob": "10.3.3",
81
81
  "prettier": "3.0.0",
82
- "release-it": "16.1.0",
82
+ "release-it": "16.1.2",
83
83
  "remark-cli": "11.0.0",
84
84
  "remark-preset-webpro": "0.0.3",
85
85
  "tsx": "3.12.7",
86
- "type-fest": "3.13.0"
86
+ "type-fest": "4.0.0"
87
87
  },
88
88
  "engines": {
89
89
  "node": ">=16.17.0 <17 || >=18.6.0"