knip 2.0.0-alpha.6 → 2.0.0-alpha.8

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 (75) hide show
  1. package/README.md +30 -28
  2. package/dist/binaries/bash-parser.d.ts +6 -0
  3. package/dist/binaries/bash-parser.js +57 -0
  4. package/dist/binaries/index.d.ts +2 -0
  5. package/dist/binaries/index.js +22 -0
  6. package/dist/binaries/resolvers/fallback.d.ts +2 -0
  7. package/dist/binaries/resolvers/fallback.js +14 -0
  8. package/dist/binaries/resolvers/index.d.ts +4 -0
  9. package/dist/binaries/resolvers/index.js +4 -0
  10. package/dist/binaries/resolvers/node.d.ts +3 -0
  11. package/dist/binaries/resolvers/node.js +20 -0
  12. package/dist/binaries/resolvers/npx.d.ts +2 -0
  13. package/dist/binaries/resolvers/npx.js +5 -0
  14. package/dist/binaries/resolvers/pnpm.d.ts +2 -0
  15. package/dist/binaries/resolvers/pnpm.js +45 -0
  16. package/dist/binaries/resolvers/yarn.d.ts +2 -0
  17. package/dist/binaries/resolvers/yarn.js +46 -0
  18. package/dist/binaries/types.d.ts +18 -0
  19. package/dist/binaries/types.js +1 -0
  20. package/dist/configuration-chief.js +2 -2
  21. package/dist/dependency-deputy.js +9 -2
  22. package/dist/index.js +1 -0
  23. package/dist/manifest/index.d.ts +2 -1
  24. package/dist/manifest/index.js +10 -6
  25. package/dist/plugins/ava/index.d.ts +6 -0
  26. package/dist/plugins/ava/index.js +22 -0
  27. package/dist/plugins/ava/types.d.ts +4 -0
  28. package/dist/plugins/ava/types.js +1 -0
  29. package/dist/plugins/commitlint/index.js +10 -3
  30. package/dist/plugins/cspell/index.d.ts +6 -0
  31. package/dist/plugins/cspell/index.js +18 -0
  32. package/dist/plugins/cspell/types.d.ts +3 -0
  33. package/dist/plugins/cspell/types.js +1 -0
  34. package/dist/plugins/github-actions/index.js +1 -1
  35. package/dist/plugins/husky/index.js +1 -1
  36. package/dist/plugins/index.d.ts +4 -0
  37. package/dist/plugins/index.js +4 -0
  38. package/dist/plugins/lefthook/index.js +1 -1
  39. package/dist/plugins/lint-staged/index.js +1 -1
  40. package/dist/plugins/nx/index.js +1 -1
  41. package/dist/plugins/release-it/index.js +1 -1
  42. package/dist/plugins/semantic-release/index.d.ts +6 -0
  43. package/dist/plugins/semantic-release/index.js +18 -0
  44. package/dist/plugins/semantic-release/types.d.ts +3 -0
  45. package/dist/plugins/semantic-release/types.js +1 -0
  46. package/dist/plugins/svelte/index.d.ts +7 -0
  47. package/dist/plugins/svelte/index.js +9 -0
  48. package/dist/source-lab.d.ts +21 -0
  49. package/dist/source-lab.js +135 -0
  50. package/dist/util/array.d.ts +1 -0
  51. package/dist/util/array.js +7 -0
  52. package/dist/util/find-import-specifiers.d.ts +5 -0
  53. package/dist/util/find-import-specifiers.js +48 -0
  54. package/dist/util/fs.d.ts +4 -0
  55. package/dist/util/fs.js +17 -2
  56. package/dist/util/loader.js +7 -5
  57. package/dist/util/log.d.ts +1 -0
  58. package/dist/util/log.js +1 -0
  59. package/dist/util/members.d.ts +3 -0
  60. package/dist/util/members.js +25 -0
  61. package/dist/util/path.js +1 -1
  62. package/dist/util/project.d.ts +13 -0
  63. package/dist/util/project.js +48 -0
  64. package/dist/util/resolve-included-issue-types.d.ts +2 -2
  65. package/dist/util/resolve-included-issue-types.js +2 -2
  66. package/dist/util/type.d.ts +2 -0
  67. package/dist/util/type.js +9 -0
  68. package/dist/version.d.ts +1 -1
  69. package/dist/version.js +1 -1
  70. package/dist/workspace-worker.d.ts +4 -2
  71. package/dist/workspace-worker.js +4 -1
  72. package/package.json +7 -7
  73. package/schema.json +16 -0
  74. package/dist/progress-updater.d.ts +0 -12
  75. package/dist/progress-updater.js +0 -34
package/README.md CHANGED
@@ -40,7 +40,7 @@ for the full story.
40
40
  ## Issues
41
41
 
42
42
  Are you seeing false positives? Please report them by [opening an issue in this repo][9]. Bonus points for linking to a
43
- public repository using Knip, or even opening a pull request with a directory and example files in `test/fixtures`.
43
+ public repository using Knip, or even opening a pull request with a directory and example files in `tests/fixtures`.
44
44
  Correctness and bug fixes have priority over performance and new features.
45
45
 
46
46
  Also see the [FAQ][10].
@@ -309,10 +309,11 @@ Knip contains a growing list of plugins:
309
309
  - [Sentry][37]
310
310
  - [Storybook][38]
311
311
  - [Stryker][39]
312
- - [TypeDoc][40]
313
- - [TypeScript][41]
314
- - [Vitest][42]
315
- - [Webpack][43]
312
+ - [Svelte][40]
313
+ - [TypeDoc][41]
314
+ - [TypeScript][42]
315
+ - [Vitest][43]
316
+ - [Webpack][44]
316
317
 
317
318
  Plugins are automatically activated. Each plugin is automatically enabled based on simple heuristics. Most of them check
318
319
  whether one or one of a few (dev) dependencies are listed in `package.json`. Once enabled, they add a set of
@@ -320,7 +321,7 @@ configuration and/or entry files for Knip to analyze. These defaults can be over
320
321
 
321
322
  Most plugins use one or both of the following file types:
322
323
 
323
- - `config` - custom dependency resolvers are applied to the [config files][44]
324
+ - `config` - custom dependency resolvers are applied to the [config files][45]
324
325
  - `entry` - files to include with the analysis of the rest of the source code
325
326
 
326
327
  See each plugin's documentation for its default values.
@@ -351,7 +352,7 @@ For plugins related to test files, it's good to know that the following glob pat
351
352
  - `**/__tests__/**/*.{js,jsx,ts,tsx,mjs,cjs}`
352
353
  - `**/test/**/*.{js,jsx,ts,tsx,mjs,cjs}`
353
354
 
354
- Files matching these patterns are excluded in [production mode][45].
355
+ Files matching these patterns are excluded in [production mode][46].
355
356
 
356
357
  ### Disable a plugin
357
358
 
@@ -411,10 +412,10 @@ Here's what's included in production mode analysis:
411
412
 
412
413
  Additionally, the `--strict` flag can be used to:
413
414
 
414
- - Consider only `dependencies` (not `devDependencies`) when finding unused or unlisted dependencies.
415
- - Consider only non-type imports (i.e. ignore `import type {}`).
416
- - Assume each workspace is self-contained: they have their own `dependencies` (and not rely on packages of ancestor
417
- workspaces).
415
+ - Consider `dependencies` (not `devDependencies`) when finding unused or unlisted dependencies.
416
+ - Include `peerDependencies` when finding unused or unlisted dependencies.
417
+ - Ignore type-only imports (`import type {}`).
418
+ - Verify each workspace is self-contained: have their own `dependencies` (and not use packages of ancestor workspaces).
418
419
 
419
420
  ### Plugins
420
421
 
@@ -478,7 +479,7 @@ type ReporterOptions = {
478
479
 
479
480
  The data can then be used to write issues to `stdout`, a JSON or CSV file, or sent to a service.
480
481
 
481
- Find more details and ideas in [custom reporters][46].
482
+ Find more details and ideas in [custom reporters][47].
482
483
 
483
484
  ## Public exports
484
485
 
@@ -535,7 +536,7 @@ When unused dependencies are related to dependencies having a Knip [plugin][1],
535
536
  for that dependency are at custom locations. The default values are at the plugin's documentation, and can be overridden
536
537
  to match the custom location(s).
537
538
 
538
- When the dependencies don't have a Knip plugin yet, please file an issue or [create a new plugin][47].
539
+ When the dependencies don't have a Knip plugin yet, please file an issue or [create a new plugin][48].
539
540
 
540
541
  #### Too many unused exports
541
542
 
@@ -543,7 +544,7 @@ When the project is a library and the exports are meant to be used by consumers
543
544
 
544
545
  1. By default, unused exports of `entry` files are not reported. You could re-export from an existing entry file, or
545
546
  add the containing file to the `entry` array in the configuration.
546
- 2. The exported values or types can be marked [using the JSDoc `@public` tag][48]
547
+ 2. The exported values or types can be marked [using the JSDoc `@public` tag][49]
547
548
 
548
549
  ### How to start using Knip in CI while having too many issues to sort out?
549
550
 
@@ -563,7 +564,7 @@ All of this is hiding problems, so please make sure to plan for fixing them and/
563
564
 
564
565
  This table is an ongoing comparison. Based on their docs (please report any mistakes):
565
566
 
566
- | Feature | **knip** | [depcheck][49] | [unimported][50] | [ts-unused-exports][51] | [ts-prune][52] |
567
+ | Feature | **knip** | [depcheck][50] | [unimported][51] | [ts-unused-exports][52] | [ts-prune][53] |
567
568
  | :-------------------------------- | :------: | :------------: | :--------------: | :---------------------: | :------------: |
568
569
  | Unused files | ✅ | - | ✅ | - | - |
569
570
  | Unused dependencies | ✅ | ✅ | ✅ | - | - |
@@ -661,16 +662,17 @@ for the job. I'm motivated to make knip perfectly suited for the job of cutting
661
662
  [37]: ./src/plugins/sentry
662
663
  [38]: ./src/plugins/storybook
663
664
  [39]: ./src/plugins/stryker
664
- [40]: ./src/plugins/typedoc
665
- [41]: ./src/plugins/typescript
666
- [42]: ./src/plugins/vitest
667
- [43]: ./src/plugins/webpack
668
- [44]: #config
669
- [45]: #production-mode
670
- [46]: ./docs/custom-reporters.md
671
- [47]: #create-a-new-plugin
672
- [48]: #public-exports
673
- [49]: https://github.com/depcheck/depcheck
674
- [50]: https://github.com/smeijer/unimported
675
- [51]: https://github.com/pzavolinsky/ts-unused-exports
676
- [52]: https://github.com/nadeesha/ts-prune
665
+ [40]: ./src/plugins/svelte
666
+ [41]: ./src/plugins/typedoc
667
+ [42]: ./src/plugins/typescript
668
+ [43]: ./src/plugins/vitest
669
+ [44]: ./src/plugins/webpack
670
+ [45]: #config
671
+ [46]: #production-mode
672
+ [47]: ./docs/custom-reporters.md
673
+ [48]: #create-a-new-plugin
674
+ [49]: #public-exports
675
+ [50]: https://github.com/depcheck/depcheck
676
+ [51]: https://github.com/smeijer/unimported
677
+ [52]: https://github.com/pzavolinsky/ts-unused-exports
678
+ [53]: https://github.com/nadeesha/ts-prune
@@ -0,0 +1,6 @@
1
+ import type { PackageJson } from 'type-fest';
2
+ export declare const getBinariesFromScript: (script: string, { cwd, manifest, knownGlobalsOnly }: {
3
+ cwd: string;
4
+ manifest: PackageJson;
5
+ knownGlobalsOnly?: boolean | undefined;
6
+ }) => string[];
@@ -0,0 +1,57 @@
1
+ import parse from 'bash-parser';
2
+ import parseArgs from 'minimist';
3
+ import * as FallbackResolver from './resolvers/fallback.js';
4
+ import * as KnownResolvers from './resolvers/index.js';
5
+ const spawningBinaries = ['cross-env', 'dotenv'];
6
+ export const getBinariesFromScript = (script, { cwd, manifest, knownGlobalsOnly = false }) => {
7
+ if (!script)
8
+ return [];
9
+ const fromArgs = (args) => getBinariesFromScript(args.join(' '), { cwd, manifest });
10
+ const getBinariesFromNodes = (nodes) => nodes.flatMap(node => {
11
+ switch (node.type) {
12
+ case 'Command': {
13
+ const binary = node.name?.text;
14
+ const commandExpansions = node.prefix?.flatMap(prefix => prefix.expansion?.filter(expansion => expansion.type === 'CommandExpansion') ?? []) ?? [];
15
+ if (commandExpansions.length > 0) {
16
+ return commandExpansions.flatMap(expansion => getBinariesFromNodes(expansion.commandAST.commands)) ?? [];
17
+ }
18
+ if (!binary || binary === '.' || binary === 'source')
19
+ return [];
20
+ if (binary.startsWith('-') || binary.startsWith('"') || binary.startsWith('..'))
21
+ return [];
22
+ if (['bun', 'deno'].includes(binary))
23
+ return [];
24
+ const args = node.suffix?.map(arg => arg.text) ?? [];
25
+ if (['!', 'test'].includes(binary))
26
+ return fromArgs(args);
27
+ if (binary in KnownResolvers) {
28
+ return KnownResolvers[binary].resolve(binary, args, { cwd, manifest, fromArgs });
29
+ }
30
+ if (knownGlobalsOnly)
31
+ return [];
32
+ if (spawningBinaries.includes(binary)) {
33
+ const parsedArgs = parseArgs(args);
34
+ const [spawnedBinary] = parsedArgs._;
35
+ if (spawnedBinary) {
36
+ const restArgs = args.slice(args.indexOf(spawnedBinary));
37
+ return [binary, ...fromArgs(restArgs)];
38
+ }
39
+ else {
40
+ return [];
41
+ }
42
+ }
43
+ return FallbackResolver.resolve(binary, args, { cwd, manifest, fromArgs });
44
+ }
45
+ case 'LogicalExpression':
46
+ return getBinariesFromNodes([node.left, node.right]);
47
+ case 'If':
48
+ return getBinariesFromNodes([...node.clause.commands, ...node.then.commands]);
49
+ case 'For':
50
+ return getBinariesFromNodes(node.do.commands);
51
+ default:
52
+ return [];
53
+ }
54
+ });
55
+ const parsed = parse(script);
56
+ return parsed?.commands ? getBinariesFromNodes(parsed.commands) : [];
57
+ };
@@ -0,0 +1,2 @@
1
+ import type { GetReferencesFromScripts } from './types.js';
2
+ export declare const _getReferencesFromScripts: GetReferencesFromScripts;
@@ -0,0 +1,22 @@
1
+ import { IGNORED_GLOBAL_BINARIES } from '../constants.js';
2
+ import { compact } from '../util/array.js';
3
+ import { partition } from '../util/array.js';
4
+ import { getPackageNameFromModuleSpecifier, stripBinary } from '../util/modules.js';
5
+ import { isInternal } from '../util/path.js';
6
+ import { timerify } from '../util/performance.js';
7
+ import { getBinariesFromScript } from './bash-parser.js';
8
+ const defaultCwd = process.cwd();
9
+ const getReferencesFromScripts = (npmScripts, options = {}) => {
10
+ const { cwd = defaultCwd, manifest = {}, ignore = [], knownGlobalsOnly = false } = options;
11
+ const scripts = [npmScripts].flat();
12
+ const results = scripts.flatMap(script => getBinariesFromScript(script, { cwd, manifest, knownGlobalsOnly }));
13
+ const [entryFiles, binaries] = partition(compact(results), isInternal);
14
+ return {
15
+ entryFiles,
16
+ binaries: binaries
17
+ .map(stripBinary)
18
+ .map(getPackageNameFromModuleSpecifier)
19
+ .filter(binaryName => !IGNORED_GLOBAL_BINARIES.includes(binaryName) && !ignore.includes(binaryName)),
20
+ };
21
+ };
22
+ export const _getReferencesFromScripts = timerify(getReferencesFromScripts);
@@ -0,0 +1,2 @@
1
+ import type { Resolver } from '../types.js';
2
+ export declare const resolve: Resolver;
@@ -0,0 +1,14 @@
1
+ import parseArgs from 'minimist';
2
+ import { tryResolveFilePaths } from './node.js';
3
+ const argResolvers = {
4
+ 'babel-node': parsed => [parsed._[0], parsed.require].flat(),
5
+ 'ts-node': parsed => [parsed._[0], parsed.require].flat(),
6
+ tsx: parsed => parsed._.filter(p => p !== 'watch'),
7
+ default: parsed => [parsed.require].flat(),
8
+ };
9
+ export const resolve = (binary, args, { cwd }) => {
10
+ const parsed = parseArgs(args, { string: ['r'], alias: { require: ['r', 'loader'] } });
11
+ const resolver = argResolvers[binary] ?? argResolvers.default;
12
+ const resolve = resolver(parsed);
13
+ return [binary, ...tryResolveFilePaths(cwd, resolve)];
14
+ };
@@ -0,0 +1,4 @@
1
+ export * as node from './node.js';
2
+ export * as npx from './npx.js';
3
+ export * as pnpm from './pnpm.js';
4
+ export * as yarn from './yarn.js';
@@ -0,0 +1,4 @@
1
+ export * as node from './node.js';
2
+ export * as npx from './npx.js';
3
+ export * as pnpm from './pnpm.js';
4
+ export * as yarn from './yarn.js';
@@ -0,0 +1,3 @@
1
+ import type { Resolver } from '../types.js';
2
+ export declare const tryResolveFilePaths: (cwd: string, specifiers: string[]) => string[];
3
+ export declare const resolve: Resolver;
@@ -0,0 +1,20 @@
1
+ import parseArgs from 'minimist';
2
+ import { isInNodeModules, join } from '../../util/path.js';
3
+ import { tryResolve } from '../../util/require.js';
4
+ const tryResolveFilePath = (cwd, specifier, fallback) => {
5
+ if (specifier) {
6
+ const filePath = join(cwd, specifier);
7
+ if (!isInNodeModules(filePath)) {
8
+ const resolvedFilePath = tryResolve(filePath);
9
+ if (resolvedFilePath)
10
+ return [resolvedFilePath];
11
+ }
12
+ return fallback ? [fallback] : [];
13
+ }
14
+ return [];
15
+ };
16
+ export const tryResolveFilePaths = (cwd, specifiers) => specifiers.flatMap(specifier => tryResolveFilePath(cwd, specifier, specifier));
17
+ export const resolve = (binary, args, { cwd }) => {
18
+ const parsed = parseArgs(args, { string: ['r'], alias: { require: ['r', 'loader', 'experimental-loader'] } });
19
+ return [...tryResolveFilePath(cwd, parsed._[0]), ...tryResolveFilePaths(cwd, [parsed.require].flat())];
20
+ };
@@ -0,0 +1,2 @@
1
+ import type { Resolver } from '../types.js';
2
+ export declare const resolve: Resolver;
@@ -0,0 +1,5 @@
1
+ import parseArgs from 'minimist';
2
+ export const resolve = (binary, args, { fromArgs }) => {
3
+ const parsed = parseArgs(args, { '--': true, stopEarly: true, boolean: ['yes', 'no'], alias: { yes: 'y', no: 'n' } });
4
+ return [...(parsed.yes ? [] : fromArgs(parsed._)), ...(parsed['--'] ? fromArgs(parsed['--']) : [])];
5
+ };
@@ -0,0 +1,2 @@
1
+ import type { Resolver } from '../types.js';
2
+ export declare const resolve: Resolver;
@@ -0,0 +1,45 @@
1
+ import parseArgs from 'minimist';
2
+ const commands = [
3
+ 'add',
4
+ 'dlx',
5
+ 'run',
6
+ 'i',
7
+ 'install',
8
+ 'up',
9
+ 'update',
10
+ 'upgrade',
11
+ 'remove',
12
+ 'rm',
13
+ 'uninstall',
14
+ 'un',
15
+ 'link',
16
+ 'ln',
17
+ 'unlink',
18
+ 'import',
19
+ 'rebuild',
20
+ 'rb',
21
+ 'prune',
22
+ 'fetch',
23
+ 'install-test',
24
+ 'it',
25
+ 'patch',
26
+ 'patch-commit',
27
+ 'audit',
28
+ 'list',
29
+ 'ls',
30
+ 'outdated',
31
+ 'why',
32
+ 'test',
33
+ 't',
34
+ 'tst',
35
+ ];
36
+ export const resolve = (binary, args, { manifest }) => {
37
+ const scripts = manifest.scripts ? Object.keys(manifest.scripts) : [];
38
+ const parsed = parseArgs(args, {});
39
+ const [command, result] = parsed._;
40
+ if (scripts.includes(command) || commands.includes(command))
41
+ return [];
42
+ if (command === 'exec')
43
+ return [result];
44
+ return command ? [command] : [];
45
+ };
@@ -0,0 +1,2 @@
1
+ import type { Resolver } from '../types.js';
2
+ export declare const resolve: Resolver;
@@ -0,0 +1,46 @@
1
+ import parseArgs from 'minimist';
2
+ const commands = [
3
+ 'add',
4
+ 'bin',
5
+ 'cache',
6
+ 'config',
7
+ 'constraints',
8
+ 'dedupe',
9
+ 'dlx',
10
+ 'explain',
11
+ 'info',
12
+ 'init',
13
+ 'install',
14
+ 'link',
15
+ 'pack',
16
+ 'patch',
17
+ 'patch-commit',
18
+ 'plugin',
19
+ 'rebuild',
20
+ 'remove',
21
+ 'search',
22
+ 'set',
23
+ 'stage',
24
+ 'unlink',
25
+ 'unplug',
26
+ 'up',
27
+ 'upgrade-interactive',
28
+ 'version',
29
+ 'why',
30
+ 'workspace',
31
+ 'workspaces',
32
+ ];
33
+ export const resolve = (binary, args, { manifest, fromArgs }) => {
34
+ const scripts = manifest.scripts ? Object.keys(manifest.scripts) : [];
35
+ const parsed = parseArgs(args, {});
36
+ const [command, result] = parsed._;
37
+ if (scripts.includes(command) || commands.includes(command))
38
+ return [];
39
+ if (command === 'run' && scripts.includes(result))
40
+ return [];
41
+ if (command === 'run' || command === 'exec')
42
+ return [result];
43
+ if (command === 'node')
44
+ return fromArgs(parsed._);
45
+ return command ? [command] : [];
46
+ };
@@ -0,0 +1,18 @@
1
+ import type { PackageJson } from 'type-fest';
2
+ type Options = {
3
+ cwd?: string;
4
+ manifest?: PackageJson;
5
+ ignore?: string[];
6
+ knownGlobalsOnly?: boolean;
7
+ };
8
+ export type GetReferencesFromScripts = (npmScripts: string | string[], options?: Options) => {
9
+ entryFiles: string[];
10
+ binaries: string[];
11
+ };
12
+ type FromArgs = (args: string[]) => string[];
13
+ export type Resolver = (binary: string, args: string[], options: {
14
+ cwd: string;
15
+ manifest: PackageJson;
16
+ fromArgs: FromArgs;
17
+ }) => string[];
18
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -120,8 +120,8 @@ export class ConfigurationChief {
120
120
  project,
121
121
  paths,
122
122
  ignore: arrayify(workspaceConfig.ignore),
123
- ignoreBinaries: [...ignoreBinaries, ...arrayify(workspaceConfig.ignoreBinaries)],
124
- ignoreDependencies: [...ignoreDependencies, ...arrayify(workspaceConfig.ignoreDependencies)],
123
+ ignoreBinaries: compact([...ignoreBinaries, ...arrayify(workspaceConfig.ignoreBinaries)]),
124
+ ignoreDependencies: compact([...ignoreDependencies, ...arrayify(workspaceConfig.ignoreDependencies)]),
125
125
  };
126
126
  for (const [name, pluginConfig] of Object.entries(workspaceConfig)) {
127
127
  const pluginName = toCamelCase(name);
@@ -36,7 +36,12 @@ export class DependencyDeputy {
36
36
  return this._manifests.get(workspaceName);
37
37
  }
38
38
  getProductionDependencies(workspaceName) {
39
- return this._manifests.get(workspaceName)?.dependencies ?? [];
39
+ const manifest = this._manifests.get(workspaceName);
40
+ if (!manifest)
41
+ return [];
42
+ if (this.isStrict)
43
+ return [...manifest.dependencies, ...manifest.peerDependencies];
44
+ return manifest.dependencies;
40
45
  }
41
46
  getDevDependencies(workspaceName) {
42
47
  return this._manifests.get(workspaceName)?.devDependencies ?? [];
@@ -87,7 +92,9 @@ export class DependencyDeputy {
87
92
  }
88
93
  isInDependencies(workspaceName, packageName) {
89
94
  const manifest = this._manifests.get(workspaceName);
90
- const dependencies = manifest ? (this.isStrict ? manifest.dependencies : manifest.allDependencies) : [];
95
+ if (!manifest)
96
+ return false;
97
+ const dependencies = this.isStrict ? this.getProductionDependencies(workspaceName) : manifest.allDependencies;
91
98
  return dependencies.includes(packageName);
92
99
  }
93
100
  settleDependencyIssues() {
package/dist/index.js CHANGED
@@ -48,6 +48,7 @@ export const main = async (unresolvedConfiguration) => {
48
48
  config,
49
49
  manifest,
50
50
  isProduction,
51
+ isStrict,
51
52
  rootIgnore: chief.config.ignore,
52
53
  negatedWorkspacePatterns: chief.getNegatedWorkspacePatterns(name),
53
54
  enabledPluginsInAncestors: ancestors.flatMap(ancestor => enabledPluginsStore.get(ancestor) ?? []),
@@ -5,10 +5,11 @@ type Options = {
5
5
  config: WorkspaceConfiguration;
6
6
  manifest: PackageJson;
7
7
  isProduction: boolean;
8
+ isStrict: boolean;
8
9
  dir: string;
9
10
  cwd: string;
10
11
  };
11
- export declare const findDependencies: ({ config, manifest, isProduction, dir, cwd }: Options) => Promise<{
12
+ export declare const findDependencies: ({ config, manifest, isProduction, isStrict, dir, cwd }: Options) => Promise<{
12
13
  dependencies: string[];
13
14
  peerDependencies: PeerDependencies;
14
15
  installedBinaries: InstalledBinaries;
@@ -1,13 +1,13 @@
1
- import { _getReferencesFromScripts } from '../util/binaries/index.js';
1
+ import { _getReferencesFromScripts } from '../binaries/index.js';
2
2
  import { timerify } from '../util/performance.js';
3
3
  import { getPackageManifest } from './helpers.js';
4
- const findManifestDependencies = async ({ config, manifest, isProduction, dir, cwd }) => {
4
+ const findManifestDependencies = async ({ config, manifest, isProduction, isStrict, dir, cwd }) => {
5
5
  const { ignoreBinaries } = config;
6
6
  const scriptFilter = isProduction ? ['start', 'postinstall'] : [];
7
7
  const referencedDependencies = new Set();
8
8
  const peerDependencies = new Map();
9
9
  const scripts = Object.entries(manifest.scripts ?? {}).reduce((scripts, [scriptName, script]) => {
10
- if (script && (scriptFilter.length === 0 || (scriptFilter.length > 0 && scriptFilter.includes(scriptName)))) {
10
+ if (script && (scriptFilter.length === 0 || scriptFilter.includes(scriptName))) {
11
11
  return [...scripts, script];
12
12
  }
13
13
  return scripts;
@@ -18,7 +18,11 @@ const findManifestDependencies = async ({ config, manifest, isProduction, dir, c
18
18
  ignore: ignoreBinaries,
19
19
  });
20
20
  const installedBinaries = new Map();
21
- const packageNames = [...Object.keys(manifest.dependencies ?? {}), ...Object.keys(manifest.devDependencies ?? {})];
21
+ const packageNames = [
22
+ ...Object.keys(manifest.dependencies ?? {}),
23
+ ...(isStrict ? Object.keys(manifest.peerDependencies ?? {}) : []),
24
+ ...(isProduction ? [] : Object.keys(manifest.devDependencies ?? {})),
25
+ ];
22
26
  for (const packageName of packageNames) {
23
27
  const manifest = await getPackageManifest({ dir, packageName, cwd });
24
28
  if (manifest) {
@@ -45,8 +49,8 @@ const findManifestDependencies = async ({ config, manifest, isProduction, dir, c
45
49
  for (const binaryName of referencedBinaries) {
46
50
  if (installedBinaries.has(binaryName)) {
47
51
  const packageNames = Array.from(installedBinaries.get(binaryName) ?? []);
48
- const packageName = packageNames.length === 1 ? packageNames[0] : undefined;
49
- referencedDependencies.add(packageName ?? binaryName);
52
+ const packageName = packageNames.length === 1 ? packageNames[0] : binaryName;
53
+ referencedDependencies.add(packageName);
50
54
  }
51
55
  else {
52
56
  referencedDependencies.add(binaryName);
@@ -0,0 +1,6 @@
1
+ import type { IsPluginEnabledCallback, GenericPluginCallback } from '../../types/plugins.js';
2
+ export declare const NAME = "Ava";
3
+ export declare const ENABLERS: string[];
4
+ export declare const isEnabled: IsPluginEnabledCallback;
5
+ export declare const CONFIG_FILE_PATTERNS: string[];
6
+ export declare const findDependencies: GenericPluginCallback;
@@ -0,0 +1,22 @@
1
+ import { _getReferencesFromScripts } from '../../binaries/index.js';
2
+ import { _load } from '../../util/loader.js';
3
+ import { timerify } from '../../util/performance.js';
4
+ import { hasDependency } from '../../util/plugin.js';
5
+ export const NAME = 'Ava';
6
+ export const ENABLERS = ['ava'];
7
+ export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
8
+ export const CONFIG_FILE_PATTERNS = ['ava.config.{js,cjs,mjs}', 'package.json'];
9
+ const findPluginDependencies = async (configFilePath, { cwd, manifest, workspaceConfig }) => {
10
+ const config = configFilePath.endsWith('package.json') ? manifest.ava : await _load(configFilePath);
11
+ const requireArgs = (config?.require ?? []).map(require => `--require ${require}`);
12
+ const otherArgs = config?.nodeArguments ?? [];
13
+ const cmd = `node ${otherArgs.join(' ') + ' '}${requireArgs.join(' ')}`;
14
+ const { binaries } = _getReferencesFromScripts([cmd], {
15
+ cwd,
16
+ manifest,
17
+ ignore: workspaceConfig.ignoreBinaries,
18
+ knownGlobalsOnly: true,
19
+ });
20
+ return binaries;
21
+ };
22
+ export const findDependencies = timerify(findPluginDependencies);
@@ -0,0 +1,4 @@
1
+ export type PluginConfig = {
2
+ require?: string[];
3
+ nodeArguments?: string[];
4
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -4,9 +4,16 @@ import { hasDependency } from '../../util/plugin.js';
4
4
  export const NAME = 'commitlint';
5
5
  export const ENABLERS = ['@commitlint/cli'];
6
6
  export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
7
- export const CONFIG_FILE_PATTERNS = ['commitlint.config.{js,ts}'];
8
- const findCommitLintDependencies = async (configFilePath) => {
9
- const config = await _load(configFilePath);
7
+ export const CONFIG_FILE_PATTERNS = [
8
+ '.commitlintrc',
9
+ '.commitlintrc.{json,yaml,yml,js,cjs,ts,cts}',
10
+ 'commitlint.config.{js,cjs,ts,cts}',
11
+ 'package.json',
12
+ ];
13
+ const findCommitLintDependencies = async (configFilePath, { manifest }) => {
14
+ const config = configFilePath.endsWith('package.json')
15
+ ? manifest.commitlint
16
+ : await _load(configFilePath);
10
17
  return config?.extends ? [config.extends].flat() : [];
11
18
  };
12
19
  export const findDependencies = timerify(findCommitLintDependencies);
@@ -0,0 +1,6 @@
1
+ import type { IsPluginEnabledCallback, GenericPluginCallback } from '../../types/plugins.js';
2
+ export declare const NAME = "cspell";
3
+ export declare const ENABLERS: string[];
4
+ export declare const isEnabled: IsPluginEnabledCallback;
5
+ export declare const CONFIG_FILE_PATTERNS: string[];
6
+ export declare const findDependencies: GenericPluginCallback;
@@ -0,0 +1,18 @@
1
+ import { _load } from '../../util/loader.js';
2
+ import { timerify } from '../../util/performance.js';
3
+ import { hasDependency } from '../../util/plugin.js';
4
+ export const NAME = 'cspell';
5
+ export const ENABLERS = ['cspell'];
6
+ export const isEnabled = ({ dependencies }) => hasDependency(dependencies, ENABLERS);
7
+ export const CONFIG_FILE_PATTERNS = [
8
+ 'cspell.config.{js,cjs,json,yaml,yml}',
9
+ 'cspell.{json,yaml,yml}',
10
+ '.c{s,S}pell.json',
11
+ 'cSpell.json',
12
+ ];
13
+ const findPluginDependencies = async (configFilePath) => {
14
+ const config = await _load(configFilePath);
15
+ const imports = config?.import ?? [];
16
+ return imports;
17
+ };
18
+ export const findDependencies = timerify(findPluginDependencies);
@@ -0,0 +1,3 @@
1
+ export type PluginConfig = {
2
+ import?: string[];
3
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
- import { _getReferencesFromScripts } from '../../util/binaries/index.js';
1
+ import { _getReferencesFromScripts } from '../../binaries/index.js';
2
2
  import { _firstGlob } from '../../util/glob.js';
3
3
  import { _load } from '../../util/loader.js';
4
4
  import { getValuesByKeyDeep } from '../../util/object.js';
@@ -1,5 +1,5 @@
1
1
  import { readFileSync } from 'fs';
2
- import { _getReferencesFromScripts } from '../../util/binaries/index.js';
2
+ import { _getReferencesFromScripts } from '../../binaries/index.js';
3
3
  import { timerify } from '../../util/performance.js';
4
4
  import { hasDependency } from '../../util/plugin.js';
5
5
  export const NAME = 'husky';