knip 2.10.1 → 2.10.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.
@@ -1,5 +1,5 @@
1
1
  import { isBuiltin } from 'node:module';
2
- import { IGNORE_DEFINITELY_TYPED, IGNORED_DEPENDENCIES, IGNORED_GLOBAL_BINARIES } from './constants.js';
2
+ import { IGNORE_DEFINITELY_TYPED, IGNORED_DEPENDENCIES, IGNORED_GLOBAL_BINARIES, ROOT_WORKSPACE_NAME, } from './constants.js';
3
3
  import { isDefinitelyTyped, getDefinitelyTypedFor, getPackageFromDefinitelyTyped } from './util/modules.js';
4
4
  export class DependencyDeputy {
5
5
  isStrict;
@@ -191,27 +191,34 @@ export class DependencyDeputy {
191
191
  const referencedDependencies = this.referencedDependencies.get(workspaceName);
192
192
  const referencedBinaries = this.referencedBinaries.get(workspaceName);
193
193
  const installedBinaries = this.getInstalledBinaries(workspaceName);
194
+ referencedDependencies?.forEach(pkg => pkg in rootIgnoreDependencies && rootIgnoreDependencies[pkg]++);
194
195
  referencedBinaries?.forEach(binaryName => binaryName in rootIgnoreBinaries && rootIgnoreBinaries[binaryName]++);
195
- const allDeps = [...this.getProductionDependencies(workspaceName), ...this.getDevDependencies(workspaceName)];
196
- const isReferencedDep = (name) => referencedDependencies?.has(name) || (allDeps.includes(name) && !referencedDependencies?.has(name));
197
- const isReferencedBin = (name) => !installedBinaries?.has(name) && referencedBinaries?.has(name);
196
+ const dependencies = this.isStrict
197
+ ? this.getProductionDependencies(workspaceName)
198
+ : [...this.getProductionDependencies(workspaceName), ...this.getDevDependencies(workspaceName)];
199
+ const isReferencedDep = (name) => referencedDependencies?.has(name) && dependencies.includes(name);
200
+ const isReferencedBin = (name) => referencedBinaries?.has(name) && installedBinaries?.has(name);
198
201
  ignoreDependencies
199
202
  .filter(packageName => IGNORED_DEPENDENCIES.includes(packageName) ||
200
- (workspaceName !== '.' && this.ignoreDependencies.includes(packageName)) ||
201
- !isReferencedDep(packageName))
203
+ (workspaceName !== ROOT_WORKSPACE_NAME && this.ignoreDependencies.includes(packageName)) ||
204
+ isReferencedDep(packageName))
202
205
  .forEach(identifier => configurationHints.add({ workspaceName, identifier, type: 'ignoreDependencies' }));
203
206
  ignoreBinaries
204
207
  .filter(binaryName => IGNORED_GLOBAL_BINARIES.includes(binaryName) ||
205
- (workspaceName !== '.' && this.ignoreBinaries.includes(binaryName)) ||
206
- !isReferencedBin(binaryName))
208
+ (workspaceName !== ROOT_WORKSPACE_NAME && this.ignoreBinaries.includes(binaryName)) ||
209
+ isReferencedBin(binaryName))
207
210
  .forEach(identifier => configurationHints.add({ workspaceName, identifier, type: 'ignoreBinaries' }));
208
211
  }
212
+ const installedBinaries = this.getInstalledBinaries(ROOT_WORKSPACE_NAME);
213
+ const dependencies = this.isStrict
214
+ ? this.getProductionDependencies(ROOT_WORKSPACE_NAME)
215
+ : [...this.getProductionDependencies(ROOT_WORKSPACE_NAME), ...this.getDevDependencies(ROOT_WORKSPACE_NAME)];
209
216
  Object.keys(rootIgnoreBinaries)
210
- .filter(key => rootIgnoreBinaries[key] === 0)
211
- .forEach(identifier => configurationHints.add({ workspaceName: '.', identifier, type: 'ignoreBinaries' }));
217
+ .filter(key => IGNORED_GLOBAL_BINARIES.includes(key) || (rootIgnoreBinaries[key] !== 0 && installedBinaries?.has(key)))
218
+ .forEach(identifier => configurationHints.add({ workspaceName: ROOT_WORKSPACE_NAME, identifier, type: 'ignoreBinaries' }));
212
219
  Object.keys(rootIgnoreDependencies)
213
- .filter(key => rootIgnoreDependencies[key] === 0)
214
- .forEach(identifier => configurationHints.add({ workspaceName: '.', identifier, type: 'ignoreDependencies' }));
220
+ .filter(key => IGNORED_DEPENDENCIES.includes(key) || (rootIgnoreDependencies[key] !== 0 && dependencies.includes(key)))
221
+ .forEach(identifier => configurationHints.add({ workspaceName: ROOT_WORKSPACE_NAME, identifier, type: 'ignoreDependencies' }));
215
222
  return { configurationHints };
216
223
  }
217
224
  }
@@ -1,6 +1,6 @@
1
1
  import parseArgs from 'minimist';
2
2
  import { compact } from '../../util/array.js';
3
- import { toBinary, tryResolveFilePath, tryResolveFilePaths } from '../util.js';
3
+ import { toBinary, tryResolveFilePath, tryResolveSpecifiers } from '../util.js';
4
4
  const withPositional = parsed => [parsed._[0], parsed.require].flat();
5
5
  const withoutPositional = parsed => [parsed.require].flat();
6
6
  const argFilters = {
@@ -17,6 +17,6 @@ export const resolve = (binary, args, { cwd }) => {
17
17
  const parsed = parseArgs(args, { string: ['r'], alias: { require: ['r', 'loader'] }, boolean: ['quiet', 'verbose'] });
18
18
  const argFilter = argFilters[binary] ?? argFilters.default;
19
19
  const filteredArgs = compact(argFilter(parsed));
20
- const bin = binary.startsWith('.') ? tryResolveFilePath(cwd, binary, binary) : [toBinary(binary)];
21
- return [...bin, ...tryResolveFilePaths(cwd, filteredArgs)];
20
+ const bin = binary.startsWith('.') ? tryResolveFilePath(cwd, binary) : [toBinary(binary)];
21
+ return [...bin, ...tryResolveSpecifiers(cwd, filteredArgs)];
22
22
  };
@@ -1,6 +1,6 @@
1
1
  import parseArgs from 'minimist';
2
- import { tryResolveFilePath, tryResolveFilePaths } from '../util.js';
2
+ import { tryResolveFilePath, tryResolveSpecifiers } from '../util.js';
3
3
  export const resolve = (binary, args, { cwd }) => {
4
4
  const parsed = parseArgs(args, { string: ['r'], alias: { require: ['r', 'loader', 'experimental-loader'] } });
5
- return [...tryResolveFilePath(cwd, parsed._[0]), ...tryResolveFilePaths(cwd, [parsed.require].flat())];
5
+ return [...tryResolveFilePath(cwd, parsed._[0]), ...tryResolveSpecifiers(cwd, [parsed.require].flat())];
6
6
  };
@@ -1,10 +1,10 @@
1
1
  import parseArgs from 'minimist';
2
- import { toBinary, tryResolveFilePaths } from '../util.js';
2
+ import { toBinary, tryResolveSpecifiers } from '../util.js';
3
3
  export const resolve = (binary, args, { cwd, fromArgs }) => {
4
4
  const safeArgs = args.filter(arg => arg !== '--watch');
5
5
  const parsed = parseArgs(safeArgs, { alias: { plugin: 'p' } });
6
6
  const watchers = parsed.watch ? fromArgs(Object.values(parsed.watch)) : [];
7
- const plugins = parsed.plugin ? tryResolveFilePaths(cwd, [parsed.plugin].flat()) : [];
8
- const configPlugins = parsed.configPlugin ? tryResolveFilePaths(cwd, [parsed.configPlugin].flat()) : [];
7
+ const plugins = parsed.plugin ? tryResolveSpecifiers(cwd, [parsed.plugin].flat()) : [];
8
+ const configPlugins = parsed.configPlugin ? tryResolveSpecifiers(cwd, [parsed.configPlugin].flat()) : [];
9
9
  return [toBinary(binary), ...watchers, ...plugins, ...configPlugins];
10
10
  };
@@ -1,5 +1,5 @@
1
- export declare const tryResolveFilePath: (cwd: string, specifier: string, fallback?: string) => string[];
2
- export declare const tryResolveFilePaths: (cwd: string, specifiers: string[]) => string[];
1
+ export declare const tryResolveFilePath: (cwd: string, specifier: string, acceptModuleSpecifier?: boolean) => string[];
2
+ export declare const tryResolveSpecifiers: (cwd: string, specifiers: string[]) => string[];
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;
@@ -1,18 +1,23 @@
1
+ import { getPackageNameFromFilePath, getPackageNameFromModuleSpecifier } from '../util/modules.js';
1
2
  import { isInNodeModules, join } from '../util/path.js';
2
3
  import { _tryResolve } from '../util/require.js';
3
- export const tryResolveFilePath = (cwd, specifier, fallback) => {
4
+ export const tryResolveFilePath = (cwd, specifier, acceptModuleSpecifier) => {
4
5
  if (specifier) {
5
6
  const filePath = join(cwd, specifier);
6
7
  if (!isInNodeModules(filePath)) {
7
8
  const resolvedFilePath = _tryResolve(filePath, cwd);
8
9
  if (resolvedFilePath)
9
10
  return [resolvedFilePath];
11
+ else if (acceptModuleSpecifier)
12
+ return [getPackageNameFromModuleSpecifier(specifier)];
13
+ }
14
+ else {
15
+ return [getPackageNameFromFilePath(specifier)];
10
16
  }
11
- return fallback ? [stripNodeModulesFromPath(fallback)] : [];
12
17
  }
13
18
  return [];
14
19
  };
15
- export const tryResolveFilePaths = (cwd, specifiers) => specifiers.flatMap(specifier => tryResolveFilePath(cwd, specifier, specifier));
20
+ export const tryResolveSpecifiers = (cwd, specifiers) => specifiers.flatMap(specifier => tryResolveFilePath(cwd, specifier, true));
16
21
  export const toBinary = (specifier) => specifier.replace(/^(bin:)?/, 'bin:');
17
22
  export const fromBinary = (specifier) => specifier.replace(/^(bin:)?/, '');
18
23
  export const isBinary = (specifier) => specifier.startsWith('bin:');
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import micromatch from 'micromatch';
1
2
  import { _getDependenciesFromScripts } from './binaries/index.js';
2
3
  import { fromBinary, isBinary } from './binaries/util.js';
3
4
  import { ConfigurationChief } from './ConfigurationChief.js';
@@ -42,7 +43,10 @@ export const main = async (unresolvedConfiguration) => {
42
43
  const absSpecifier = toAbsolute(specifier, dirname(containingFilePath));
43
44
  const filePath = _tryResolve(absSpecifier, containingFilePath);
44
45
  if (filePath) {
45
- principal.addEntryPath(filePath);
46
+ const ignorePatterns = workspace.config.ignore.map(pattern => join(dirname(containingFilePath), pattern));
47
+ const isIgnored = micromatch.isMatch(filePath, ignorePatterns);
48
+ if (!isIgnored)
49
+ principal.addEntryPath(filePath);
46
50
  }
47
51
  else {
48
52
  collector.addIssue({ type: 'unresolved', filePath: containingFilePath, symbol: specifier });
@@ -277,7 +281,7 @@ export const main = async (unresolvedConfiguration) => {
277
281
  }
278
282
  continue;
279
283
  }
280
- if (importedModule.isReExport || importedModule.isStar) {
284
+ if (importedModule.isStar) {
281
285
  const isReExportedByEntryFile = isExportedInEntryFile(importedModule);
282
286
  if (!isReExportedByEntryFile && !principal.hasExternalReferences(filePath, exportedItem)) {
283
287
  if (['enum', 'type', 'interface'].includes(exportedItem.type)) {
@@ -292,8 +296,13 @@ export const main = async (unresolvedConfiguration) => {
292
296
  if (['enum', 'type', 'interface'].includes(exportedItem.type)) {
293
297
  collector.addIssue({ type: 'types', filePath, symbol, symbolType: exportedItem.type });
294
298
  }
295
- else if (!importedModule.isDynamic || !principal.hasExternalReferences(filePath, exportedItem)) {
296
- collector.addIssue({ type: 'exports', filePath, symbol });
299
+ else {
300
+ if (importedModule.isReExport && !principal.hasExternalReferences(filePath, exportedItem)) {
301
+ collector.addIssue({ type: 'exports', filePath, symbol });
302
+ }
303
+ else if (!importedModule.isDynamic || !principal.hasExternalReferences(filePath, exportedItem)) {
304
+ collector.addIssue({ type: 'exports', filePath, symbol });
305
+ }
297
306
  }
298
307
  }
299
308
  }
@@ -15,6 +15,8 @@ const findVitestDependencies = async (configFilePath) => {
15
15
  const environments = cfg.environment ? [getEnvPackageName(cfg.environment)] : [];
16
16
  const reporters = getExternalReporters(cfg.reporters);
17
17
  const coverage = cfg.coverage?.provider ? [`@vitest/coverage-${cfg.coverage.provider}`] : [];
18
- return compact([...environments, ...reporters, ...coverage]);
18
+ const setupFiles = cfg.setupFiles ? [cfg.setupFiles].flat() : [];
19
+ const globalSetup = cfg.globalSetup ? [cfg.globalSetup].flat() : [];
20
+ return compact([...environments, ...reporters, ...coverage, ...setupFiles, ...globalSetup]);
19
21
  };
20
22
  export const findDependencies = timerify(findVitestDependencies);
@@ -1,9 +1,11 @@
1
1
  export type VitestConfig = {
2
2
  test: {
3
- environment?: string;
4
- reporters?: string[];
5
3
  coverage?: {
6
4
  provider: string;
7
5
  };
6
+ environment?: string;
7
+ globalSetup?: string | string[];
8
+ reporters?: string[];
9
+ setupFiles?: string | string[];
8
10
  };
9
11
  };
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "2.10.1";
1
+ export declare const version = "2.10.2";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '2.10.1';
1
+ export const version = '2.10.2';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "2.10.1",
3
+ "version": "2.10.2",
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",
@@ -19,10 +19,10 @@
19
19
  "scripts": {
20
20
  "knip": "node ./dist/cli.js",
21
21
  "knip:production": "node ./dist/cli.js --production --strict",
22
- "lint": "eslint src tests",
23
- "lint:fix": "eslint src tests --fix",
22
+ "lint": "eslint scripts src tests",
23
+ "lint:fix": "eslint scripts src tests --fix",
24
24
  "format": "prettier scripts src tests schema.json --with-node-modules --write --config .prettierrc",
25
- "test": "globstar -- node --loader tsx --test \"tests/**/*.test.ts\"",
25
+ "test": "globstar -- node --no-warnings --loader tsx --test \"tests/**/*.test.ts\"",
26
26
  "coverage": "c8 npm test",
27
27
  "watch": "tsc --watch",
28
28
  "prebuild": "node -e \"require('fs').rmSync('dist', { force: true, recursive: true })\"",
@@ -67,7 +67,7 @@
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": "18.15.13",
70
+ "@types/node": "18.16.0",
71
71
  "@types/npmcli__map-workspaces": "3.0.1",
72
72
  "@types/webpack": "5.28.1",
73
73
  "@typescript-eslint/eslint-plugin": "5.59.0",
@@ -78,7 +78,7 @@
78
78
  "eslint-plugin-import": "2.27.5",
79
79
  "eslint-plugin-n": "15.7.0",
80
80
  "globstar": "1.0.0",
81
- "prettier": "2.8.7",
81
+ "prettier": "2.8.8",
82
82
  "release-it": "15.10.1",
83
83
  "remark-cli": "11.0.0",
84
84
  "remark-preset-webpro": "0.0.2",