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.
- package/README.md +10 -8
- package/dist/{configuration-chief.js → ConfigurationChief.js} +39 -38
- package/dist/{dependency-deputy.d.ts → DependencyDeputy.d.ts} +4 -2
- package/dist/{dependency-deputy.js → DependencyDeputy.js} +29 -10
- package/dist/{principal-factory.d.ts → PrincipalFactory.d.ts} +1 -1
- package/dist/{principal-factory.js → PrincipalFactory.js} +1 -1
- package/dist/{project-principal.d.ts → ProjectPrincipal.d.ts} +7 -4
- package/dist/{project-principal.js → ProjectPrincipal.js} +6 -4
- package/dist/{workspace-worker.d.ts → WorkspaceWorker.d.ts} +1 -1
- package/dist/{workspace-worker.js → WorkspaceWorker.js} +0 -2
- package/dist/binaries/index.d.ts +2 -2
- package/dist/binaries/index.js +12 -16
- package/dist/binaries/resolvers/fallback.js +8 -4
- package/dist/binaries/resolvers/npx.js +3 -1
- package/dist/binaries/types.d.ts +1 -5
- package/dist/cli.js +1 -1
- package/dist/index.js +57 -47
- package/dist/manifest/index.d.ts +1 -3
- package/dist/manifest/index.js +11 -25
- package/dist/plugins/_template/index.js +1 -1
- package/dist/plugins/ava/index.js +4 -6
- package/dist/plugins/babel/index.js +1 -1
- package/dist/plugins/capacitor/index.js +1 -1
- package/dist/plugins/changesets/index.js +1 -1
- package/dist/plugins/commitizen/index.js +1 -1
- package/dist/plugins/commitlint/index.js +1 -1
- package/dist/plugins/cspell/index.js +1 -1
- package/dist/plugins/eslint/index.js +1 -1
- package/dist/plugins/gatsby/index.js +1 -1
- package/dist/plugins/github-actions/index.js +4 -6
- package/dist/plugins/husky/index.js +4 -6
- package/dist/plugins/jest/index.js +1 -1
- package/dist/plugins/lefthook/index.js +4 -6
- package/dist/plugins/lint-staged/index.js +7 -7
- package/dist/plugins/markdownlint/index.js +1 -1
- package/dist/plugins/mocha/index.js +1 -1
- package/dist/plugins/npm-package-json-lint/index.js +1 -1
- package/dist/plugins/nx/index.js +4 -4
- package/dist/plugins/nyc/index.js +1 -1
- package/dist/plugins/postcss/index.js +1 -1
- package/dist/plugins/prettier/index.js +1 -1
- package/dist/plugins/release-it/index.js +4 -4
- package/dist/plugins/remark/index.js +1 -1
- package/dist/plugins/semantic-release/index.js +1 -1
- package/dist/plugins/storybook/index.js +1 -1
- package/dist/plugins/stryker/index.js +1 -1
- package/dist/plugins/typedoc/index.js +1 -1
- package/dist/plugins/typescript/index.js +1 -1
- package/dist/plugins/vitest/index.js +1 -1
- package/dist/plugins/webpack/index.js +1 -1
- package/dist/types/config.d.ts +1 -1
- package/dist/types/{ast.d.ts → exports.d.ts} +0 -10
- package/dist/types/imports.d.ts +14 -0
- package/dist/types/imports.js +1 -0
- package/dist/types/plugins.d.ts +1 -2
- package/dist/types/workspace.d.ts +1 -0
- package/dist/typescript/SourceFile.d.ts +1 -0
- package/dist/typescript/getImportsAndExports.d.ts +29 -0
- package/dist/typescript/getImportsAndExports.js +158 -0
- package/dist/typescript/visitors/exports/exportAssignment.d.ts +3 -0
- package/dist/typescript/visitors/exports/exportAssignment.js +8 -0
- package/dist/typescript/visitors/exports/exportDeclaration.d.ts +3 -0
- package/dist/typescript/visitors/exports/exportDeclaration.js +13 -0
- package/dist/typescript/visitors/exports/exportKeyword.d.ts +3 -0
- package/dist/typescript/visitors/exports/exportKeyword.js +77 -0
- package/dist/typescript/visitors/exports/index.d.ts +3 -0
- package/dist/typescript/visitors/exports/index.js +6 -0
- package/dist/typescript/visitors/exports/moduleExportsAccessExpression.d.ts +3 -0
- package/dist/typescript/visitors/exports/moduleExportsAccessExpression.js +31 -0
- package/dist/typescript/visitors/helpers.d.ts +3 -0
- package/dist/typescript/visitors/helpers.js +3 -0
- package/dist/typescript/visitors/imports/importCall.d.ts +3 -0
- package/dist/typescript/visitors/imports/importCall.js +35 -0
- package/dist/typescript/visitors/imports/importDeclaration.d.ts +3 -0
- package/dist/typescript/visitors/imports/importDeclaration.js +32 -0
- package/dist/typescript/visitors/imports/importEqualsDeclaration.d.ts +3 -0
- package/dist/typescript/visitors/imports/importEqualsDeclaration.js +11 -0
- package/dist/typescript/visitors/imports/index.d.ts +3 -0
- package/dist/typescript/visitors/imports/index.js +17 -0
- package/dist/typescript/visitors/imports/jsDocType.d.ts +3 -0
- package/dist/typescript/visitors/imports/jsDocType.js +11 -0
- package/dist/typescript/visitors/imports/reExportDeclaration.d.ts +3 -0
- package/dist/typescript/visitors/imports/reExportDeclaration.js +21 -0
- package/dist/typescript/visitors/imports/requireCall.d.ts +3 -0
- package/dist/typescript/visitors/imports/requireCall.js +46 -0
- package/dist/typescript/visitors/imports/requireResolveCall.d.ts +3 -0
- package/dist/typescript/visitors/imports/requireResolveCall.js +14 -0
- package/dist/typescript/visitors/index.d.ts +10 -0
- package/dist/typescript/visitors/index.js +15 -0
- package/dist/typescript/visitors/scripts/index.d.ts +3 -0
- package/dist/typescript/visitors/scripts/index.js +3 -0
- package/dist/typescript/visitors/scripts/zx.d.ts +3 -0
- package/dist/typescript/visitors/scripts/zx.js +8 -0
- package/dist/util/array.d.ts +0 -1
- package/dist/util/array.js +0 -7
- package/dist/util/compilers.d.ts +5 -4
- package/dist/util/compilers.js +1 -3
- package/dist/util/glob.js +1 -1
- package/dist/util/loader.js +1 -1
- package/dist/util/plugin.js +1 -1
- package/dist/util/require.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/dist/typescript/ast-walker.d.ts +0 -16
- package/dist/typescript/ast-walker.js +0 -364
- package/dist/{configuration-chief.d.ts → ConfigurationChief.d.ts} +0 -0
- package/dist/{configuration-validator.d.ts → ConfigurationValidator.d.ts} +6 -6
- /package/dist/{configuration-validator.js → ConfigurationValidator.js} +0 -0
- /package/dist/{console-streamer.d.ts → ConsoleStreamer.d.ts} +0 -0
- /package/dist/{console-streamer.js → ConsoleStreamer.js} +0 -0
- /package/dist/{issue-collector.d.ts → IssueCollector.d.ts} +0 -0
- /package/dist/{issue-collector.js → IssueCollector.js} +0 -0
- /package/dist/types/{ast.js → exports.js} +0 -0
- /package/dist/util/{performance.d.ts → Performance.d.ts} +0 -0
- /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]
|
|
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
|
-
```
|
|
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
|
|
443
|
-
- Only the `
|
|
444
|
-
- Only `exports`, `nsExports` and `classMembers` 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
|
-
| [
|
|
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 './
|
|
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
|
|
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
|
|
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 './
|
|
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
|
|
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 => !
|
|
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 => !
|
|
140
|
+
return !peerDependencies.find(peerDependency => !isNotReferencedDependency(peerDependency));
|
|
124
141
|
}
|
|
125
142
|
return false;
|
|
126
143
|
};
|
|
127
144
|
this.getProductionDependencies(workspaceName)
|
|
128
|
-
.filter(
|
|
129
|
-
.filter(
|
|
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(
|
|
133
|
-
.filter(
|
|
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 './
|
|
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 './
|
|
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/
|
|
42
|
+
internal: import("./types/imports.js").Imports;
|
|
43
43
|
unresolved: Set<string>;
|
|
44
44
|
external: Set<string>;
|
|
45
45
|
};
|
|
46
|
-
exports:
|
|
47
|
-
|
|
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/
|
|
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,
|
|
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
|
-
|
|
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: ("
|
|
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 => {
|
package/dist/binaries/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare const
|
|
1
|
+
import type { GetDependenciesFromScripts } from './types.js';
|
|
2
|
+
export declare const _getDependenciesFromScripts: GetDependenciesFromScripts;
|
package/dist/binaries/index.js
CHANGED
|
@@ -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/
|
|
4
|
+
import { timerify } from '../util/Performance.js';
|
|
7
5
|
import { getBinariesFromScript } from './bash-parser.js';
|
|
8
6
|
const defaultCwd = process.cwd();
|
|
9
|
-
const
|
|
10
|
-
const { cwd = defaultCwd, manifest = {},
|
|
11
|
-
const scripts = [npmScripts]
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
|
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':
|
|
6
|
-
|
|
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:
|
|
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
|
-
|
|
4
|
+
const left = fromArgs(parsed._);
|
|
5
|
+
const right = parsed['--'] ? fromArgs(parsed['--']) : [];
|
|
6
|
+
return [...(parsed.yes ? left.slice(1) : left), ...right];
|
|
5
7
|
};
|
package/dist/binaries/types.d.ts
CHANGED
|
@@ -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
|
|
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/
|
|
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;
|