knip 2.10.1 → 2.10.3

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.
package/README.md CHANGED
@@ -38,6 +38,11 @@ with OpenAI_</sup>
38
38
 
39
39
  Knip supports LTS versions of Node.js, and currently requires at least Node.js v16.17 or v18.6.
40
40
 
41
+ ## Experimental: knowledge base
42
+
43
+ You might want to ask your questions in the [Knip knowledge base][8] (powered by OpenAI and [7-docs][9]). This is an
44
+ experimental knowledge base, answers may be incorrect.
45
+
41
46
  ## Configuration
42
47
 
43
48
  Knip has good defaults and you can run it without any configuration. Here's the default:
@@ -194,7 +199,7 @@ The report contains the following types of issues:
194
199
 
195
200
  When an issue type has zero issues, it is not shown.
196
201
 
197
- Getting too many reported issues and false positives? Read more about [handling issues][8].
202
+ Getting too many reported issues and false positives? Read more about [handling issues][10].
198
203
 
199
204
  _(1)_ The variable or type is not referenced directly and has become a member of a namespace. Knip can't find a
200
205
  reference to it, so you can _probably_ remove it.
@@ -222,7 +227,7 @@ Example:
222
227
  }
223
228
  ```
224
229
 
225
- See [reading the report][9] for the list of issue types.
230
+ See [reading the report][11] for the list of issue types.
226
231
 
227
232
  The rules are modeled after the ESLint `rules` configuration, and could be extended in the future. For instance, to
228
233
  apply filters or configurations only to a specific issue type.
@@ -243,7 +248,7 @@ Use `--exclude` to ignore reports you're not interested in:
243
248
 
244
249
  Use `--dependencies` or `--exports` as shortcuts to combine groups of related types.
245
250
 
246
- See [reading the report][9] for the list of issue types.
251
+ See [reading the report][11] for the list of issue types.
247
252
 
248
253
  ### When to use rules or filters
249
254
 
@@ -285,7 +290,7 @@ As always, make sure to back up files or use Git before deleting files or making
285
290
 
286
291
  🔁 Repeat the process to reveal new unused files and exports. Sometimes it's so liberating to remove things!
287
292
 
288
- Getting too many reported issues and false positives? Read more about [handling issues][8].
293
+ Getting too many reported issues and false positives? Read more about [handling issues][10].
289
294
 
290
295
  ## Workspaces
291
296
 
@@ -315,7 +320,7 @@ Here's an example `knip.json` configuration with some custom `entry` and `projec
315
320
  ```
316
321
 
317
322
  It might be useful to run Knip first with no or little configuration to see where it needs custom `entry` and/or
318
- `project` files. Each workspace has the same [default configuration][10].
323
+ `project` files. Each workspace has the same [default configuration][12].
319
324
 
320
325
  The root workspace is named `"."` under `workspaces` (like in the example).
321
326
 
@@ -434,7 +439,7 @@ has them at `e2e-tests/*.spec.ts`. Here's how to configure this:
434
439
  ### Multi-project repositories
435
440
 
436
441
  Some repositories have a single `package.json`, but consist of multiple projects with configuration files across the
437
- repository (such as the [Nx "intregrated repo" style][11]). Let's assume some of these projects are apps and have their
442
+ repository (such as the [Nx "intregrated repo" style][13]). Let's assume some of these projects are apps and have their
438
443
  own Cypress configuration and test files. In that case, we could configure the Cypress plugin like this:
439
444
 
440
445
  ```json
@@ -451,7 +456,7 @@ In case a plugin causes issues, it can be disabled by using `false` as its value
451
456
 
452
457
  ### Create a new plugin
453
458
 
454
- Getting false positives because a plugin is missing? Want to help out? Please read more at [writing a plugin][12]. This
459
+ Getting false positives because a plugin is missing? Want to help out? Please read more at [writing a plugin][14]. This
455
460
  guide also contains more details if you want to learn more about plugins and why they are useful.
456
461
 
457
462
  ## Compilers
@@ -474,7 +479,7 @@ export default {
474
479
  };
475
480
  ```
476
481
 
477
- Read [Compilers][13] for more details and examples.
482
+ Read [Compilers][15] for more details and examples.
478
483
 
479
484
  ## Production Mode
480
485
 
@@ -551,7 +556,7 @@ When the provided built-in reporters are not sufficient, a custom reporter can b
551
556
  Pass `--reporter ./my-reporter` from the command line. The data can then be used to write issues to `stdout`, a JSON or
552
557
  CSV file, or sent to a service.
553
558
 
554
- Find more details and ideas in [custom reporters][14].
559
+ Find more details and ideas in [custom reporters][16].
555
560
 
556
561
  ## Public exports
557
562
 
@@ -575,14 +580,14 @@ Knip does not report public exports and types as unused.
575
580
 
576
581
  ## Handling Issues
577
582
 
578
- How to handle a long list of reported issues? Seeing too many false positives? Read more about [handling issues][15]
583
+ How to handle a long list of reported issues? Seeing too many false positives? Read more about [handling issues][17]
579
584
  describing potential causes for false positives, and how to handle them.
580
585
 
581
586
  ## Comparison
582
587
 
583
588
  This table is an ongoing comparison. Based on their docs (please report any mistakes):
584
589
 
585
- | Feature | **knip** | [depcheck][16] | [unimported][17] | [ts-unused-exports][18] | [ts-prune][19] |
590
+ | Feature | **knip** | [depcheck][18] | [unimported][19] | [ts-unused-exports][20] | [ts-prune][21] |
586
591
  | :---------------------- | :------: | :------------: | :--------------: | :---------------------: | :------------: |
587
592
  | Unused files | ✅ | - | ✅ | - | - |
588
593
  | Unused dependencies | ✅ | ✅ | ✅ | - | - |
@@ -618,7 +623,7 @@ The following commands are similar:
618
623
  unimported
619
624
  knip --production --dependencies --include files
620
625
 
621
- Also see [production mode][20].
626
+ Also see [production mode][22].
622
627
 
623
628
  ### ts-unused-exports
624
629
 
@@ -640,16 +645,17 @@ The following commands are similar:
640
645
 
641
646
  Many thanks to some of the early adopters of Knip:
642
647
 
643
- - [Block Protocol][21]
644
- - [Cursor][22]
645
- - [DeepmergeTS][23]
646
- - [eslint-plugin-functional][24]
647
- - [freeCodeCamp.org][25]
648
- - [is-immutable-type][26]
649
- - [release-it][27]
650
- - [Template TypeScript Node Package][28]
648
+ - [Abracabra][23]
649
+ - [Block Protocol][24]
650
+ - [Cursor][25]
651
+ - [DeepmergeTS][26]
652
+ - [eslint-plugin-functional][27]
653
+ - [freeCodeCamp.org][28]
654
+ - [is-immutable-type][29]
655
+ - [release-it][30]
656
+ - [Template TypeScript Node Package][31]
651
657
 
652
- ## 🐣 Super Secret Easter Egg Boost 🚀
658
+ ## Potential boost with `--no-gitignore`
653
659
 
654
660
  Running Knip on large workspaces with many packages may feel a bit sluggish. Knip looks up `.gitignore` files and uses
655
661
  them to filter out matching entry and project files. This increases correctness. However, you might want to disable that
@@ -667,7 +673,7 @@ And to measure the difference of this flag in seconds:
667
673
  SECONDS=0; knip > /dev/null; t1=$SECONDS; SECONDS=0; knip --no-gitignore > /dev/null; t2=$SECONDS; echo "Difference: $((t1 - t2)) seconds"
668
674
  ```
669
675
 
670
- ⏲️ Analysis on a large project went from 33 down to 9 seconds (that's >70% faster). Happy Easter! 🐣
676
+ ⏲️ Analysis on a large project went from 33 down to 9 seconds (that's >70% faster).
671
677
 
672
678
  ## Knip
673
679
 
@@ -685,7 +691,7 @@ each file, and traversing all of this, why not collect the various issues in one
685
691
 
686
692
  Special thanks to the wonderful people who have contributed to this project:
687
693
 
688
- [![Contributors][30]][29]
694
+ [![Contributors][33]][32]
689
695
 
690
696
  [1]: #workspaces
691
697
  [2]: #plugins
@@ -694,29 +700,32 @@ Special thanks to the wonderful people who have contributed to this project:
694
700
  [5]: #custom-reporters
695
701
  [6]: https://labs.openai.com/s/xZQACaLepaKya0PRUPtIN5dC
696
702
  [7]: ./assets/cow-with-orange-scissors-van-gogh-style.webp
697
- [8]: #handling-issues
698
- [9]: #reading-the-report
699
- [10]: #configuration
700
- [11]: https://nx.dev/concepts/integrated-vs-package-based
701
- [12]: ./docs/writing-a-plugin.md
702
- [13]: ./docs/compilers.md
703
- [14]: ./docs/custom-reporters.md
704
- [15]: ./docs/handling-issues.md
705
- [16]: https://github.com/depcheck/depcheck
706
- [17]: https://github.com/smeijer/unimported
707
- [18]: https://github.com/pzavolinsky/ts-unused-exports
708
- [19]: https://github.com/nadeesha/ts-prune
709
- [20]: #production-mode
710
- [21]: https://github.com/blockprotocol/blockprotocol
711
- [22]: https://github.com/getcursor/cursor
712
- [23]: https://github.com/RebeccaStevens/deepmerge-ts
713
- [24]: https://github.com/eslint-functional/eslint-plugin-functional
714
- [25]: https://github.com/freeCodeCamp/freeCodeCamp
715
- [26]: https://github.com/RebeccaStevens/is-immutable-type
716
- [27]: https://github.com/release-it/release-it
717
- [28]: https://github.com/JoshuaKGoldberg/template-typescript-node-package
718
- [29]: https://github.com/webpro/knip/graphs/contributors
719
- [30]: https://contrib.rocks/image?repo=webpro/knip
703
+ [8]: https://knip.deno.dev
704
+ [9]: https://github.com/7-docs/7-docs
705
+ [10]: #handling-issues
706
+ [11]: #reading-the-report
707
+ [12]: #configuration
708
+ [13]: https://nx.dev/concepts/integrated-vs-package-based
709
+ [14]: ./docs/writing-a-plugin.md
710
+ [15]: ./docs/compilers.md
711
+ [16]: ./docs/custom-reporters.md
712
+ [17]: ./docs/handling-issues.md
713
+ [18]: https://github.com/depcheck/depcheck
714
+ [19]: https://github.com/smeijer/unimported
715
+ [20]: https://github.com/pzavolinsky/ts-unused-exports
716
+ [21]: https://github.com/nadeesha/ts-prune
717
+ [22]: #production-mode
718
+ [23]: https://github.com/nicoespeon/abracadabra
719
+ [24]: https://github.com/blockprotocol/blockprotocol
720
+ [25]: https://github.com/getcursor/cursor
721
+ [26]: https://github.com/RebeccaStevens/deepmerge-ts
722
+ [27]: https://github.com/eslint-functional/eslint-plugin-functional
723
+ [28]: https://github.com/freeCodeCamp/freeCodeCamp
724
+ [29]: https://github.com/RebeccaStevens/is-immutable-type
725
+ [30]: https://github.com/release-it/release-it
726
+ [31]: https://github.com/JoshuaKGoldberg/template-typescript-node-package
727
+ [32]: https://github.com/webpro/knip/graphs/contributors
728
+ [33]: https://contrib.rocks/image?repo=webpro/knip
720
729
  [plugin-ava]: ./src/plugins/ava
721
730
  [plugin-babel]: ./src/plugins/babel
722
731
  [plugin-capacitor]: ./src/plugins/capacitor
@@ -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
  };
@@ -2,6 +2,7 @@ import parseArgs from 'minimist';
2
2
  import { toBinary } from '../util.js';
3
3
  const commands = [
4
4
  'add',
5
+ 'dedupe',
5
6
  'dlx',
6
7
  'run',
7
8
  'i',
@@ -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.3";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '2.10.1';
1
+ export const version = '2.10.3';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "2.10.1",
3
+ "version": "2.10.3",
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": "glob -c \"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 })\"",
@@ -41,7 +41,7 @@
41
41
  "schema.json"
42
42
  ],
43
43
  "dependencies": {
44
- "@npmcli/map-workspaces": "^3.0.2",
44
+ "@npmcli/map-workspaces": "^3.0.4",
45
45
  "@snyk/github-codeowners": "^1.1.0",
46
46
  "bash-parser": "^0.5.0",
47
47
  "chalk": "^5.2.0",
@@ -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": "18.15.13",
70
+ "@types/node": "18.16.3",
71
71
  "@types/npmcli__map-workspaces": "3.0.1",
72
72
  "@types/webpack": "5.28.1",
73
- "@typescript-eslint/eslint-plugin": "5.59.0",
74
- "@typescript-eslint/parser": "5.59.0",
73
+ "@typescript-eslint/eslint-plugin": "5.59.1",
74
+ "@typescript-eslint/parser": "5.59.1",
75
75
  "c8": "7.13.0",
76
76
  "eslint": "8.39.0",
77
77
  "eslint-import-resolver-typescript": "3.5.5",
78
78
  "eslint-plugin-import": "2.27.5",
79
79
  "eslint-plugin-n": "15.7.0",
80
- "globstar": "1.0.0",
81
- "prettier": "2.8.7",
80
+ "glob": "10.2.2",
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",
85
- "tsx": "3.12.6",
86
- "type-fest": "3.8.0"
85
+ "tsx": "3.12.7",
86
+ "type-fest": "3.9.0"
87
87
  },
88
88
  "engines": {
89
89
  "node": ">=16.17.0 <17 || >=18.6.0"