knip 2.1.3 → 2.2.1

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 (116) hide show
  1. package/README.md +10 -8
  2. package/dist/{configuration-chief.js → ConfigurationChief.js} +39 -38
  3. package/dist/{dependency-deputy.d.ts → DependencyDeputy.d.ts} +4 -2
  4. package/dist/{dependency-deputy.js → DependencyDeputy.js} +29 -10
  5. package/dist/{principal-factory.d.ts → PrincipalFactory.d.ts} +1 -1
  6. package/dist/{principal-factory.js → PrincipalFactory.js} +1 -1
  7. package/dist/{project-principal.d.ts → ProjectPrincipal.d.ts} +7 -4
  8. package/dist/{project-principal.js → ProjectPrincipal.js} +6 -4
  9. package/dist/{workspace-worker.d.ts → WorkspaceWorker.d.ts} +1 -1
  10. package/dist/{workspace-worker.js → WorkspaceWorker.js} +0 -2
  11. package/dist/binaries/index.d.ts +2 -2
  12. package/dist/binaries/index.js +12 -16
  13. package/dist/binaries/resolvers/fallback.js +8 -4
  14. package/dist/binaries/resolvers/npx.js +3 -1
  15. package/dist/binaries/types.d.ts +1 -5
  16. package/dist/cli.js +1 -1
  17. package/dist/index.js +57 -47
  18. package/dist/manifest/index.d.ts +1 -3
  19. package/dist/manifest/index.js +11 -25
  20. package/dist/plugins/_template/index.js +1 -1
  21. package/dist/plugins/ava/index.js +4 -6
  22. package/dist/plugins/babel/index.js +1 -1
  23. package/dist/plugins/capacitor/index.js +1 -1
  24. package/dist/plugins/changesets/index.js +1 -1
  25. package/dist/plugins/commitizen/index.js +1 -1
  26. package/dist/plugins/commitlint/index.js +1 -1
  27. package/dist/plugins/cspell/index.js +1 -1
  28. package/dist/plugins/eslint/index.js +1 -1
  29. package/dist/plugins/gatsby/index.js +1 -1
  30. package/dist/plugins/github-actions/index.js +4 -6
  31. package/dist/plugins/husky/index.js +4 -6
  32. package/dist/plugins/jest/index.js +1 -1
  33. package/dist/plugins/lefthook/index.js +4 -6
  34. package/dist/plugins/lint-staged/index.js +7 -7
  35. package/dist/plugins/markdownlint/index.js +1 -1
  36. package/dist/plugins/mocha/index.js +1 -1
  37. package/dist/plugins/npm-package-json-lint/index.js +1 -1
  38. package/dist/plugins/nx/index.js +4 -4
  39. package/dist/plugins/nyc/index.js +1 -1
  40. package/dist/plugins/postcss/index.js +1 -1
  41. package/dist/plugins/prettier/index.js +1 -1
  42. package/dist/plugins/release-it/index.js +4 -4
  43. package/dist/plugins/remark/index.js +1 -1
  44. package/dist/plugins/semantic-release/index.js +1 -1
  45. package/dist/plugins/storybook/index.js +1 -1
  46. package/dist/plugins/stryker/index.js +1 -1
  47. package/dist/plugins/typedoc/index.js +1 -1
  48. package/dist/plugins/typescript/index.js +1 -1
  49. package/dist/plugins/vitest/index.js +1 -1
  50. package/dist/plugins/webpack/index.js +1 -1
  51. package/dist/types/config.d.ts +1 -1
  52. package/dist/types/{ast.d.ts → exports.d.ts} +0 -10
  53. package/dist/types/imports.d.ts +14 -0
  54. package/dist/types/imports.js +1 -0
  55. package/dist/types/plugins.d.ts +1 -2
  56. package/dist/types/workspace.d.ts +1 -0
  57. package/dist/typescript/SourceFile.d.ts +1 -0
  58. package/dist/typescript/getImportsAndExports.d.ts +29 -0
  59. package/dist/typescript/getImportsAndExports.js +158 -0
  60. package/dist/typescript/visitors/exports/exportAssignment.d.ts +3 -0
  61. package/dist/typescript/visitors/exports/exportAssignment.js +8 -0
  62. package/dist/typescript/visitors/exports/exportDeclaration.d.ts +3 -0
  63. package/dist/typescript/visitors/exports/exportDeclaration.js +13 -0
  64. package/dist/typescript/visitors/exports/exportKeyword.d.ts +3 -0
  65. package/dist/typescript/visitors/exports/exportKeyword.js +77 -0
  66. package/dist/typescript/visitors/exports/index.d.ts +3 -0
  67. package/dist/typescript/visitors/exports/index.js +6 -0
  68. package/dist/typescript/visitors/exports/moduleExportsAccessExpression.d.ts +3 -0
  69. package/dist/typescript/visitors/exports/moduleExportsAccessExpression.js +31 -0
  70. package/dist/typescript/visitors/helpers.d.ts +3 -0
  71. package/dist/typescript/visitors/helpers.js +3 -0
  72. package/dist/typescript/visitors/imports/importCall.d.ts +3 -0
  73. package/dist/typescript/visitors/imports/importCall.js +35 -0
  74. package/dist/typescript/visitors/imports/importDeclaration.d.ts +3 -0
  75. package/dist/typescript/visitors/imports/importDeclaration.js +32 -0
  76. package/dist/typescript/visitors/imports/importEqualsDeclaration.d.ts +3 -0
  77. package/dist/typescript/visitors/imports/importEqualsDeclaration.js +11 -0
  78. package/dist/typescript/visitors/imports/index.d.ts +3 -0
  79. package/dist/typescript/visitors/imports/index.js +17 -0
  80. package/dist/typescript/visitors/imports/jsDocType.d.ts +3 -0
  81. package/dist/typescript/visitors/imports/jsDocType.js +11 -0
  82. package/dist/typescript/visitors/imports/reExportDeclaration.d.ts +3 -0
  83. package/dist/typescript/visitors/imports/reExportDeclaration.js +21 -0
  84. package/dist/typescript/visitors/imports/requireCall.d.ts +3 -0
  85. package/dist/typescript/visitors/imports/requireCall.js +46 -0
  86. package/dist/typescript/visitors/imports/requireResolveCall.d.ts +3 -0
  87. package/dist/typescript/visitors/imports/requireResolveCall.js +14 -0
  88. package/dist/typescript/visitors/index.d.ts +10 -0
  89. package/dist/typescript/visitors/index.js +15 -0
  90. package/dist/typescript/visitors/scripts/index.d.ts +3 -0
  91. package/dist/typescript/visitors/scripts/index.js +3 -0
  92. package/dist/typescript/visitors/scripts/zx.d.ts +3 -0
  93. package/dist/typescript/visitors/scripts/zx.js +8 -0
  94. package/dist/util/array.d.ts +0 -1
  95. package/dist/util/array.js +0 -7
  96. package/dist/util/compilers.d.ts +5 -4
  97. package/dist/util/compilers.js +1 -3
  98. package/dist/util/glob.js +1 -1
  99. package/dist/util/loader.js +1 -1
  100. package/dist/util/plugin.js +1 -1
  101. package/dist/util/require.js +1 -1
  102. package/dist/version.d.ts +1 -1
  103. package/dist/version.js +1 -1
  104. package/package.json +1 -1
  105. package/dist/typescript/ast-walker.d.ts +0 -16
  106. package/dist/typescript/ast-walker.js +0 -364
  107. package/dist/{configuration-chief.d.ts → ConfigurationChief.d.ts} +0 -0
  108. package/dist/{configuration-validator.d.ts → ConfigurationValidator.d.ts} +6 -6
  109. /package/dist/{configuration-validator.js → ConfigurationValidator.js} +0 -0
  110. /package/dist/{console-streamer.d.ts → ConsoleStreamer.d.ts} +0 -0
  111. /package/dist/{console-streamer.js → ConsoleStreamer.js} +0 -0
  112. /package/dist/{issue-collector.d.ts → IssueCollector.d.ts} +0 -0
  113. /package/dist/{issue-collector.js → IssueCollector.js} +0 -0
  114. /package/dist/types/{ast.js → exports.js} +0 -0
  115. /package/dist/util/{performance.d.ts → Performance.d.ts} +0 -0
  116. /package/dist/util/{performance.js → Performance.js} +0 -0
package/README.md CHANGED
@@ -20,7 +20,7 @@ The dots don't connect themselves. This is where Knip comes in:
20
20
  - [x] Built-in support for [workspaces (monorepos)][1]
21
21
  - [x] Growing list of [built-in plugins][2]
22
22
  - [x] Use [compilers][3] to include other file types (e.g. `.mdx`, `.vue`, `.svelte`)
23
- - [x] Checks npm scripts for used and unlisted dependencies
23
+ - [x] Finds binaries and dependencies in npm scripts, and a lot more locations
24
24
  - [x] Finds unused members of classes and enums
25
25
  - [x] Finds duplicate exports
26
26
  - [x] Supports any combination of JavaScript and TypeScript
@@ -237,9 +237,9 @@ As always, make sure to backup files or use Git before deleting files or making
237
237
 
238
238
  Workspaces and monorepos are handled out-of-the-box by Knip. Every workspace is part of the analysis.
239
239
 
240
- Here's an example configuration with some custom `entry` and `project` patterns:
240
+ Here's an example `knip.json` configuration with some custom `entry` and `project` patterns:
241
241
 
242
- ```jsonc
242
+ ```json
243
243
  {
244
244
  "workspaces": {
245
245
  ".": {
@@ -280,6 +280,9 @@ Here's some example output when running Knip in a workspace:
280
280
 
281
281
  Use `--debug` to get more verbose output.
282
282
 
283
+ Use `ignoreBinaries` and `ignoreDependencies` at the root of `knip.json` for global effect, or inside any workspace
284
+ config for local effect.
285
+
283
286
  ## Plugins
284
287
 
285
288
  Plugins tell Knip where to look for configuration and entry files, and if necessary have a custom dependency finder.
@@ -439,10 +442,9 @@ use the `--production` flag. Here's an example:
439
442
  Here's what's included in production mode analysis:
440
443
 
441
444
  - Only `entry` and `project` patterns suffixed with `!`.
442
- - Only `entry` patterns from plugins exported as `PRODUCTION_ENTRY_FILE_PATTERNS` (such as Next.js and Gatsby).
443
- - Only the `postinstall` and `start` script (e.g. not the `test` or other npm scripts in `package.json`).
444
- - Only `exports`, `nsExports` and `classMembers` are included in the report (`types`, `nsTypes`, `enumMembers` are
445
- ignored).
445
+ - Only production `entry` file patterns exported for plugins (such as Next.js and Gatsby).
446
+ - Only the `start` and `postinstall` scripts (e.g. not the `test` or other npm scripts in `package.json`).
447
+ - Only unused `exports`, `nsExports` and `classMembers` are reported (not `types`, `nsTypes`, `enumMembers`).
446
448
 
447
449
  ### Strict
448
450
 
@@ -587,7 +589,7 @@ This table is an ongoing comparison. Based on their docs (please report any mist
587
589
  | Custom reporters | ✅ | - | - | - | - |
588
590
  | JavaScript support | ✅ | ✅ | ✅ | - | - |
589
591
  | Configure entry files | ✅ | ❌ | ✅ | ❌ | ❌ |
590
- | [Support workspaces][1] | ✅ | ❌ | ❌ | - | - |
592
+ | [Workspaces][1] | ✅ | ❌ | ❌ | - | - |
591
593
  | ESLint plugin available | - | - | - | ✅ | - |
592
594
 
593
595
  ✅ = Supported, ❌ = Not supported, - = Out of scope
@@ -1,6 +1,6 @@
1
1
  import mapWorkspaces from '@npmcli/map-workspaces';
2
2
  import micromatch from 'micromatch';
3
- import { ConfigurationValidator } from './configuration-validator.js';
3
+ import { ConfigurationValidator } from './ConfigurationValidator.js';
4
4
  import { ROOT_WORKSPACE_NAME, DEFAULT_EXTENSIONS, KNIP_CONFIG_LOCATIONS } from './constants.js';
5
5
  import * as plugins from './plugins/index.js';
6
6
  import { arrayify, compact } from './util/array.js';
@@ -88,7 +88,7 @@ export class ConfigurationChief {
88
88
  return [this.config.syncCompilers, this.config.asyncCompilers];
89
89
  }
90
90
  normalize(rawLocalConfig) {
91
- const workspaces = rawLocalConfig.workspaces ?? {
91
+ const initialWorkspaces = rawLocalConfig.workspaces ?? {
92
92
  [ROOT_WORKSPACE_NAME]: {
93
93
  ...rawLocalConfig,
94
94
  },
@@ -102,6 +102,42 @@ export class ConfigurationChief {
102
102
  const { syncCompilers, asyncCompilers } = rawLocalConfig;
103
103
  const extensions = [...Object.keys(syncCompilers ?? {}), ...Object.keys(asyncCompilers ?? {})];
104
104
  const defaultWorkspaceConfig = getDefaultWorkspaceConfig(extensions);
105
+ const workspaces = Object.entries(initialWorkspaces)
106
+ .filter(([workspaceName]) => !ignoreWorkspaces.includes(workspaceName))
107
+ .reduce((workspaces, workspace) => {
108
+ const [workspaceName, workspaceConfig] = workspace;
109
+ const entry = workspaceConfig.entry ? arrayify(workspaceConfig.entry) : defaultWorkspaceConfig.entry;
110
+ const project = workspaceConfig.project ? arrayify(workspaceConfig.project) : defaultWorkspaceConfig.project;
111
+ const paths = workspaceConfig.paths ?? defaultWorkspaceConfig.paths;
112
+ workspaces[workspaceName] = {
113
+ entry,
114
+ project,
115
+ paths,
116
+ ignore: arrayify(workspaceConfig.ignore),
117
+ ignoreBinaries: compact([...ignoreBinaries, ...arrayify(workspaceConfig.ignoreBinaries)]),
118
+ ignoreDependencies: compact([...ignoreDependencies, ...arrayify(workspaceConfig.ignoreDependencies)]),
119
+ };
120
+ for (const [name, pluginConfig] of Object.entries(workspaceConfig)) {
121
+ const pluginName = toCamelCase(name);
122
+ if (PLUGIN_NAMES.includes(pluginName)) {
123
+ if (pluginConfig === false) {
124
+ workspaces[workspaceName][pluginName] = false;
125
+ }
126
+ else {
127
+ const isObject = typeof pluginConfig !== 'string' && !Array.isArray(pluginConfig);
128
+ const config = isObject ? arrayify(pluginConfig.config) : pluginConfig ? arrayify(pluginConfig) : null;
129
+ const entry = isObject && 'entry' in pluginConfig ? arrayify(pluginConfig.entry) : null;
130
+ const project = isObject && 'project' in pluginConfig ? arrayify(pluginConfig.project) : entry;
131
+ workspaces[workspaceName][pluginName] = {
132
+ config,
133
+ entry,
134
+ project,
135
+ };
136
+ }
137
+ }
138
+ }
139
+ return workspaces;
140
+ }, {});
105
141
  return {
106
142
  include,
107
143
  exclude,
@@ -109,42 +145,7 @@ export class ConfigurationChief {
109
145
  ignoreWorkspaces,
110
146
  syncCompilers: new Map(Object.entries(syncCompilers ?? {})),
111
147
  asyncCompilers: new Map(Object.entries(asyncCompilers ?? {})),
112
- workspaces: Object.entries(workspaces)
113
- .filter(([workspaceName]) => !ignoreWorkspaces.includes(workspaceName))
114
- .reduce((workspaces, workspace) => {
115
- const [workspaceName, workspaceConfig] = workspace;
116
- const entry = workspaceConfig.entry ? arrayify(workspaceConfig.entry) : defaultWorkspaceConfig.entry;
117
- const project = workspaceConfig.project ? arrayify(workspaceConfig.project) : defaultWorkspaceConfig.project;
118
- const paths = workspaceConfig.paths ?? defaultWorkspaceConfig.paths;
119
- workspaces[workspaceName] = {
120
- entry,
121
- project,
122
- paths,
123
- ignore: arrayify(workspaceConfig.ignore),
124
- ignoreBinaries: compact([...ignoreBinaries, ...arrayify(workspaceConfig.ignoreBinaries)]),
125
- ignoreDependencies: compact([...ignoreDependencies, ...arrayify(workspaceConfig.ignoreDependencies)]),
126
- };
127
- for (const [name, pluginConfig] of Object.entries(workspaceConfig)) {
128
- const pluginName = toCamelCase(name);
129
- if (PLUGIN_NAMES.includes(pluginName)) {
130
- if (pluginConfig === false) {
131
- workspaces[workspaceName][pluginName] = false;
132
- }
133
- else {
134
- const isObject = typeof pluginConfig !== 'string' && !Array.isArray(pluginConfig);
135
- const config = isObject ? arrayify(pluginConfig.config) : pluginConfig ? arrayify(pluginConfig) : null;
136
- const entry = isObject && 'entry' in pluginConfig ? arrayify(pluginConfig.entry) : null;
137
- const project = isObject && 'project' in pluginConfig ? arrayify(pluginConfig.project) : entry;
138
- workspaces[workspaceName][pluginName] = {
139
- config,
140
- entry,
141
- project,
142
- };
143
- }
144
- }
145
- }
146
- return workspaces;
147
- }, {}),
148
+ workspaces,
148
149
  };
149
150
  }
150
151
  async setWorkspaces() {
@@ -1,4 +1,4 @@
1
- import { Workspace } from './configuration-chief.js';
1
+ import { Workspace } from './ConfigurationChief.js';
2
2
  import type { Issue } from './types/issues.js';
3
3
  import type { WorkspaceManifests } from './types/workspace.js';
4
4
  import type { PeerDependencies, InstalledBinaries } from './types/workspace.js';
@@ -13,12 +13,13 @@ export declare class DependencyDeputy {
13
13
  peerDependencies: Map<string, PeerDependencies>;
14
14
  installedBinaries: Map<string, InstalledBinaries>;
15
15
  constructor({ isStrict }: Options);
16
- addWorkspace({ name, dir, manifestPath, manifest, ignoreDependencies, }: {
16
+ addWorkspace({ name, dir, manifestPath, manifest, ignoreDependencies, ignoreBinaries, }: {
17
17
  name: string;
18
18
  dir: string;
19
19
  manifestPath: string;
20
20
  manifest: PackageJson;
21
21
  ignoreDependencies: string[];
22
+ ignoreBinaries: string[];
22
23
  }): void;
23
24
  getWorkspaceManifest(workspaceName: string): {
24
25
  workspaceDir: string;
@@ -30,6 +31,7 @@ export declare class DependencyDeputy {
30
31
  devDependencies: string[];
31
32
  allDependencies: string[];
32
33
  ignoreDependencies: string[];
34
+ ignoreBinaries: string[];
33
35
  } | undefined;
34
36
  getProductionDependencies(workspaceName: string): string[];
35
37
  getDevDependencies(workspaceName: string): string[];
@@ -1,5 +1,5 @@
1
1
  import { isBuiltin } from 'node:module';
2
- import { IGNORE_DEFINITELY_TYPED, IGNORED_DEPENDENCIES } from './constants.js';
2
+ import { IGNORE_DEFINITELY_TYPED, IGNORED_DEPENDENCIES, IGNORED_GLOBAL_BINARIES } from './constants.js';
3
3
  import { isDefinitelyTyped, getDefinitelyTypedFor, getPackageFromDefinitelyTyped } from './util/modules.js';
4
4
  export class DependencyDeputy {
5
5
  isStrict;
@@ -13,7 +13,7 @@ export class DependencyDeputy {
13
13
  this.peerDependencies = new Map();
14
14
  this.installedBinaries = new Map();
15
15
  }
16
- addWorkspace({ name, dir, manifestPath, manifest, ignoreDependencies, }) {
16
+ addWorkspace({ name, dir, manifestPath, manifest, ignoreDependencies, ignoreBinaries, }) {
17
17
  const scripts = Object.values(manifest.scripts ?? {});
18
18
  const dependencies = Object.keys(manifest.dependencies ?? {});
19
19
  const peerDependencies = Object.keys(manifest.peerDependencies ?? {});
@@ -24,6 +24,7 @@ export class DependencyDeputy {
24
24
  workspaceDir: dir,
25
25
  manifestPath,
26
26
  ignoreDependencies,
27
+ ignoreBinaries,
27
28
  scripts,
28
29
  dependencies,
29
30
  peerDependencies,
@@ -80,6 +81,10 @@ export class DependencyDeputy {
80
81
  closestWorkspaceNameForTypes && this.addReferencedDependency(closestWorkspaceNameForTypes, typesPackageName);
81
82
  return true;
82
83
  }
84
+ if (IGNORED_GLOBAL_BINARIES.includes(packageName))
85
+ return true;
86
+ if (this.getWorkspaceManifest(workspace.name)?.ignoreBinaries.includes(packageName))
87
+ return true;
83
88
  for (const name of workspaceNames) {
84
89
  const binaries = this.getInstalledBinaries(name);
85
90
  if (binaries?.has(packageName)) {
@@ -102,9 +107,21 @@ export class DependencyDeputy {
102
107
  settleDependencyIssues() {
103
108
  const dependencyIssues = [];
104
109
  const devDependencyIssues = [];
105
- for (const [workspaceName, { manifestPath, ignoreDependencies }] of this._manifests.entries()) {
110
+ for (const [workspaceName, { manifestPath, ignoreDependencies, ignoreBinaries }] of this._manifests.entries()) {
106
111
  const referencedDependencies = this.referencedDependencies.get(workspaceName);
107
- const isUnreferencedDependency = (dependency) => {
112
+ const installedBinaries = this.getInstalledBinaries(workspaceName);
113
+ const ignoreBins = [...IGNORED_GLOBAL_BINARIES, ...ignoreBinaries];
114
+ const ignoreDeps = [...IGNORED_DEPENDENCIES, ...ignoreDependencies];
115
+ const isNotIgnoredDependency = (packageName) => !ignoreDeps.includes(packageName);
116
+ const isNotIgnoredBinary = (packageName) => {
117
+ if (installedBinaries?.has(packageName)) {
118
+ const binaryNames = installedBinaries.get(packageName);
119
+ if (binaryNames && ignoreBins.some(ignoredBinary => binaryNames.has(ignoredBinary)))
120
+ return false;
121
+ }
122
+ return true;
123
+ };
124
+ const isNotReferencedDependency = (dependency) => {
108
125
  if (referencedDependencies?.has(dependency))
109
126
  return false;
110
127
  const [scope, typedDependency] = dependency.split('/');
@@ -114,23 +131,25 @@ export class DependencyDeputy {
114
131
  return false;
115
132
  const peerDependencies = this.getPeerDependencies(workspaceName, typedPackageName);
116
133
  if (peerDependencies.length) {
117
- return !peerDependencies.find(peerDependency => !isUnreferencedDependency(peerDependency));
134
+ return !peerDependencies.find(peerDependency => !isNotReferencedDependency(peerDependency));
118
135
  }
119
136
  return !referencedDependencies?.has(typedPackageName);
120
137
  }
121
138
  if (!referencedDependencies?.has(dependency)) {
122
139
  const peerDependencies = this.getPeerDependencies(workspaceName, dependency);
123
- return !peerDependencies.find(peerDependency => !isUnreferencedDependency(peerDependency));
140
+ return !peerDependencies.find(peerDependency => !isNotReferencedDependency(peerDependency));
124
141
  }
125
142
  return false;
126
143
  };
127
144
  this.getProductionDependencies(workspaceName)
128
- .filter(symbol => !IGNORED_DEPENDENCIES.includes(symbol) && !ignoreDependencies.includes(symbol))
129
- .filter(isUnreferencedDependency)
145
+ .filter(isNotIgnoredDependency)
146
+ .filter(isNotIgnoredBinary)
147
+ .filter(isNotReferencedDependency)
130
148
  .forEach(symbol => dependencyIssues.push({ type: 'dependencies', filePath: manifestPath, symbol }));
131
149
  this.getDevDependencies(workspaceName)
132
- .filter(symbol => !IGNORED_DEPENDENCIES.includes(symbol) && !ignoreDependencies.includes(symbol))
133
- .filter(isUnreferencedDependency)
150
+ .filter(isNotIgnoredDependency)
151
+ .filter(isNotIgnoredBinary)
152
+ .filter(isNotReferencedDependency)
134
153
  .forEach(symbol => devDependencyIssues.push({ type: 'devDependencies', filePath: manifestPath, symbol }));
135
154
  }
136
155
  return { dependencyIssues, devDependencyIssues };
@@ -1,5 +1,5 @@
1
1
  import ts from 'typescript';
2
- import { ProjectPrincipal } from './project-principal.js';
2
+ import { ProjectPrincipal } from './ProjectPrincipal.js';
3
3
  import type { SyncCompilers, AsyncCompilers } from './types/compilers.js';
4
4
  import type { Report } from './types/issues.js';
5
5
  type Paths = ts.CompilerOptions['paths'];
@@ -1,4 +1,4 @@
1
- import { ProjectPrincipal } from './project-principal.js';
1
+ import { ProjectPrincipal } from './ProjectPrincipal.js';
2
2
  import { join, isAbsolute } from './util/path.js';
3
3
  const mergePaths = (cwd, compilerOptions, paths = {}) => {
4
4
  const overridePaths = Object.keys(paths).reduce((overridePaths, key) => {
@@ -1,7 +1,7 @@
1
1
  import ts from 'typescript';
2
2
  import { SourceFileManager } from './typescript/SourceFileManager.js';
3
- import type { ExportItem, ExportItemMember } from './types/ast.js';
4
3
  import type { SyncCompilers, AsyncCompilers } from './types/compilers.js';
4
+ import type { ExportItem, ExportItemMember } from './types/exports.js';
5
5
  import type { Report } from './types/issues.js';
6
6
  type ProjectPrincipalOptions = {
7
7
  compilerOptions: ts.CompilerOptions;
@@ -39,12 +39,15 @@ export declare class ProjectPrincipal {
39
39
  getUnreferencedFiles(): string[];
40
40
  analyzeSourceFile(filePath: string): {
41
41
  imports: {
42
- internal: import("./types/ast.js").Imports;
42
+ internal: import("./types/imports.js").Imports;
43
43
  unresolved: Set<string>;
44
44
  external: Set<string>;
45
45
  };
46
- exports: import("./types/ast.js").ExportItems;
47
- duplicateExports: string[][];
46
+ exports: {
47
+ exported: import("./types/exports.js").ExportItems;
48
+ duplicate: string[][];
49
+ };
50
+ scripts: Set<string>;
48
51
  };
49
52
  private resolveModule;
50
53
  hasExternalReferences(filePath: string, exportedItem: ExportItem): boolean;
@@ -1,10 +1,10 @@
1
1
  import ts from 'typescript';
2
2
  import { DEFAULT_EXTENSIONS } from './constants.js';
3
3
  import { IGNORED_FILE_EXTENSIONS } from './constants.js';
4
- import { getImportsAndExports } from './typescript/ast-walker.js';
5
4
  import { createHosts } from './typescript/createHosts.js';
5
+ import { getImportsAndExports } from './typescript/getImportsAndExports.js';
6
6
  import { extname, isInNodeModules } from './util/path.js';
7
- import { timerify } from './util/performance.js';
7
+ import { timerify } from './util/Performance.js';
8
8
  const baseCompilerOptions = {
9
9
  allowJs: true,
10
10
  jsx: ts.JsxEmit.Preserve,
@@ -109,7 +109,7 @@ export class ProjectPrincipal {
109
109
  throw new Error(`Unable to find ${filePath}`);
110
110
  const skipTypeOnly = !this.isReportTypes;
111
111
  const skipExports = this.skipExportsAnalysis.has(filePath);
112
- const { imports, exports, duplicateExports } = getImportsAndExports(sourceFile, { skipTypeOnly, skipExports });
112
+ const { imports, exports, scripts } = getImportsAndExports(sourceFile, { skipTypeOnly, skipExports });
113
113
  const { internal, unresolved, external } = imports;
114
114
  const unresolvedImports = new Set();
115
115
  unresolved.forEach(specifier => {
@@ -144,7 +144,7 @@ export class ProjectPrincipal {
144
144
  external,
145
145
  },
146
146
  exports,
147
- duplicateExports,
147
+ scripts,
148
148
  };
149
149
  }
150
150
  resolveModule(specifier, filePath = specifier) {
@@ -159,6 +159,8 @@ export class ProjectPrincipal {
159
159
  findUnusedMembers(filePath, members) {
160
160
  return members
161
161
  .filter(member => {
162
+ if (this.isPublicExport(member))
163
+ return false;
162
164
  const referencedSymbols = this.findReferences(filePath, member.node);
163
165
  const files = referencedSymbols
164
166
  .flatMap(refs => refs.references)
@@ -50,7 +50,7 @@ export declare class WorkspaceWorker {
50
50
  peerDependencies: PeerDependencies;
51
51
  installedBinaries: InstalledBinaries;
52
52
  referencedDependencies: ReferencedDependencies;
53
- enabledPlugins: ("typescript" | "ava" | "babel" | "capacitor" | "changesets" | "commitizen" | "commitlint" | "cspell" | "cypress" | "eslint" | "gatsby" | "husky" | "jest" | "lefthook" | "markdownlint" | "mocha" | "next" | "nx" | "nyc" | "playwright" | "postcss" | "prettier" | "remark" | "remix" | "rollup" | "sentry" | "storybook" | "stryker" | "tailwind" | "typedoc" | "vite" | "vitest" | "webpack" | "githubActions" | "lintStaged" | "npmPackageJsonLint" | "releaseIt" | "semanticRelease" | "svelte")[];
53
+ enabledPlugins: ("ava" | "babel" | "capacitor" | "changesets" | "commitizen" | "commitlint" | "cspell" | "cypress" | "eslint" | "gatsby" | "husky" | "jest" | "lefthook" | "markdownlint" | "mocha" | "next" | "nx" | "nyc" | "playwright" | "postcss" | "prettier" | "remark" | "remix" | "rollup" | "sentry" | "storybook" | "stryker" | "tailwind" | "typedoc" | "typescript" | "vite" | "vitest" | "webpack" | "githubActions" | "lintStaged" | "npmPackageJsonLint" | "releaseIt" | "semanticRelease" | "svelte")[];
54
54
  }>;
55
55
  }
56
56
  export {};
@@ -58,7 +58,6 @@ export class WorkspaceWorker {
58
58
  }
59
59
  async initReferencedDependencies() {
60
60
  const { dependencies, peerDependencies, installedBinaries } = await npm.findDependencies({
61
- config: this.config,
62
61
  manifest: this.manifest,
63
62
  isProduction: this.isProduction,
64
63
  isStrict: this.isStrict,
@@ -218,7 +217,6 @@ export class WorkspaceWorker {
218
217
  cwd,
219
218
  manifest: this.manifest,
220
219
  config: pluginConfig,
221
- workspaceConfig: this.config,
222
220
  isProduction: this.isProduction,
223
221
  });
224
222
  dependencies.forEach(specifier => {
@@ -1,2 +1,2 @@
1
- import type { GetReferencesFromScripts } from './types.js';
2
- export declare const _getReferencesFromScripts: GetReferencesFromScripts;
1
+ import type { GetDependenciesFromScripts } from './types.js';
2
+ export declare const _getDependenciesFromScripts: GetDependenciesFromScripts;
@@ -1,23 +1,19 @@
1
- import { IGNORED_GLOBAL_BINARIES } from '../constants.js';
2
1
  import { compact } from '../util/array.js';
3
- import { partition } from '../util/array.js';
4
2
  import { getPackageNameFromModuleSpecifier, stripBinary } from '../util/modules.js';
5
3
  import { isInternal } from '../util/path.js';
6
- import { timerify } from '../util/performance.js';
4
+ import { timerify } from '../util/Performance.js';
7
5
  import { getBinariesFromScript } from './bash-parser.js';
8
6
  const defaultCwd = process.cwd();
9
- const getReferencesFromScripts = (npmScripts, options = {}) => {
10
- const { cwd = defaultCwd, manifest = {}, ignore = [], knownGlobalsOnly = false } = options;
11
- const scripts = [npmScripts].flat();
7
+ const getDependenciesFromScripts = (npmScripts, options = {}) => {
8
+ const { cwd = defaultCwd, manifest = {}, knownGlobalsOnly = false } = options;
9
+ const scripts = typeof npmScripts === 'string' ? [npmScripts] : [...npmScripts];
12
10
  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 => !binaryName.startsWith('.'))
20
- .filter(binaryName => !IGNORED_GLOBAL_BINARIES.includes(binaryName) && !ignore.includes(binaryName)),
21
- };
11
+ return compact(results.map(identifier => {
12
+ if (isInternal(identifier))
13
+ return identifier;
14
+ const packageName = getPackageNameFromModuleSpecifier(stripBinary(identifier));
15
+ if (!packageName.startsWith('.'))
16
+ return packageName;
17
+ }));
22
18
  };
23
- export const _getReferencesFromScripts = timerify(getReferencesFromScripts);
19
+ export const _getDependenciesFromScripts = timerify(getDependenciesFromScripts);
@@ -1,14 +1,18 @@
1
1
  import parseArgs from 'minimist';
2
2
  import { compact } from '../../util/array.js';
3
3
  import { tryResolveFilePaths } from './util.js';
4
+ const withPositional = parsed => [parsed._[0], parsed.require].flat();
5
+ const withoutPositional = parsed => [parsed.require].flat();
4
6
  const argFilters = {
5
- 'babel-node': parsed => [parsed._[0], parsed.require].flat(),
6
- 'ts-node': parsed => [parsed._[0], parsed.require].flat(),
7
+ 'babel-node': withPositional,
8
+ nodemon: withPositional,
9
+ 'ts-node': withPositional,
10
+ zx: withPositional,
7
11
  tsx: parsed => parsed._.filter(p => p !== 'watch'),
8
- default: parsed => [parsed.require].flat(),
12
+ default: withoutPositional,
9
13
  };
10
14
  export const resolve = (binary, args, { cwd }) => {
11
- const parsed = parseArgs(args, { string: ['r'], alias: { require: ['r', 'loader'] } });
15
+ const parsed = parseArgs(args, { string: ['r'], alias: { require: ['r', 'loader'] }, boolean: ['quiet', 'verbose'] });
12
16
  const argFilter = argFilters[binary] ?? argFilters.default;
13
17
  const filteredArgs = compact(argFilter(parsed));
14
18
  return [binary, ...tryResolveFilePaths(cwd, filteredArgs)];
@@ -1,5 +1,7 @@
1
1
  import parseArgs from 'minimist';
2
2
  export const resolve = (binary, args, { fromArgs }) => {
3
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['--']) : [])];
4
+ const left = fromArgs(parsed._);
5
+ const right = parsed['--'] ? fromArgs(parsed['--']) : [];
6
+ return [...(parsed.yes ? left.slice(1) : left), ...right];
5
7
  };
@@ -2,13 +2,9 @@ import type { PackageJson } from 'type-fest';
2
2
  type Options = {
3
3
  cwd?: string;
4
4
  manifest?: PackageJson;
5
- ignore?: string[];
6
5
  knownGlobalsOnly?: boolean;
7
6
  };
8
- export type GetReferencesFromScripts = (npmScripts: string | string[], options?: Options) => {
9
- entryFiles: string[];
10
- binaries: string[];
11
- };
7
+ export type GetDependenciesFromScripts = (npmScripts: string | string[] | Set<string>, options?: Options) => string[];
12
8
  type FromArgs = (args: string[]) => string[];
13
9
  export type Resolver = (binary: string, args: string[], options: {
14
10
  cwd: string;
package/dist/cli.js CHANGED
@@ -6,7 +6,7 @@ import parsedArgs, { helpText } from './util/cli-arguments.js';
6
6
  import { isKnownError, ConfigurationError } from './util/errors.js';
7
7
  import { _load } from './util/loader.js';
8
8
  import { cwd, resolve } from './util/path.js';
9
- import { Performance } from './util/performance.js';
9
+ import { Performance } from './util/Performance.js';
10
10
  import { version } from './version.js';
11
11
  import { main } from './index.js';
12
12
  const { debug: isDebug = false, help: isHelp, 'max-issues': maxIssues = '0', 'no-exit-code': noExitCode = false, 'no-gitignore': isNoGitIgnore = false, 'no-progress': isNoProgress = false, performance: isObservePerf = false, production: isProduction = false, reporter = 'symbols', 'reporter-options': reporterOptions = '', strict: isStrict = false, tsConfig, version: isVersion, } = parsedArgs.values;