knip 5.62.0 → 5.63.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 +22 -24
- package/dist/CacheConsultant.d.ts +3 -9
- package/dist/CacheConsultant.js +5 -5
- package/dist/ConfigurationChief.d.ts +588 -38
- package/dist/ConfigurationChief.js +43 -124
- package/dist/ConsoleStreamer.d.ts +2 -3
- package/dist/ConsoleStreamer.js +2 -2
- package/dist/DependencyDeputy.d.ts +2 -6
- package/dist/IssueCollector.d.ts +4 -12
- package/dist/IssueCollector.js +10 -10
- package/dist/IssueFixer.d.ts +3 -14
- package/dist/IssueFixer.js +11 -21
- package/dist/PrincipalFactory.d.ts +3 -2
- package/dist/PrincipalFactory.js +11 -11
- package/dist/ProjectPrincipal.d.ts +5 -3
- package/dist/ProjectPrincipal.js +17 -11
- package/dist/WorkspaceWorker.d.ts +4 -9
- package/dist/WorkspaceWorker.js +8 -12
- package/dist/binaries/bash-parser.js +1 -1
- package/dist/binaries/fallback.js +4 -2
- package/dist/binaries/package-manager/pnpm.js +6 -1
- package/dist/cli.js +43 -60
- package/dist/compilers/index.d.ts +34 -4
- package/dist/graph/analyze.d.ts +3 -8
- package/dist/graph/analyze.js +24 -27
- package/dist/graph/build.d.ts +3 -17
- package/dist/graph/build.js +60 -47
- package/dist/index.d.ts +3 -6
- package/dist/index.js +23 -62
- package/dist/plugins/astro/index.d.ts +1 -0
- package/dist/plugins/astro/index.js +4 -0
- package/dist/plugins/index.d.ts +24 -1
- package/dist/plugins/index.js +6 -0
- package/dist/plugins/lefthook/index.js +2 -0
- package/dist/plugins/node-modules-inspector/index.d.ts +12 -0
- package/dist/plugins/node-modules-inspector/index.js +17 -0
- package/dist/plugins/nuxt/index.js +4 -3
- package/dist/plugins/nuxt/types.d.ts +3 -2
- package/dist/plugins/playwright/index.js +8 -1
- package/dist/plugins/playwright/types.d.ts +20 -14
- package/dist/plugins/pnpm/index.d.ts +7 -0
- package/dist/plugins/pnpm/index.js +8 -0
- package/dist/plugins/preconstruct/index.js +2 -1
- package/dist/plugins/react-router/index.js +18 -8
- package/dist/plugins/rsbuild/index.js +28 -2
- package/dist/plugins/rsbuild/types.d.ts +11 -0
- package/dist/plugins/rslib/index.d.ts +10 -0
- package/dist/plugins/rslib/index.js +15 -0
- package/dist/plugins/rslib/types.d.ts +1 -0
- package/dist/plugins/rspack/index.js +1 -1
- package/dist/plugins/typescript/index.d.ts +1 -1
- package/dist/plugins.js +3 -2
- package/dist/reporters/codeclimate.d.ts +1 -1
- package/dist/reporters/codeclimate.js +10 -10
- package/dist/reporters/codeowners.d.ts +1 -1
- package/dist/reporters/codeowners.js +5 -5
- package/dist/reporters/compact.d.ts +1 -1
- package/dist/reporters/compact.js +7 -7
- package/dist/reporters/disclosure.d.ts +1 -1
- package/dist/reporters/disclosure.js +2 -2
- package/dist/reporters/index.d.ts +6 -6
- package/dist/reporters/json.d.ts +1 -1
- package/dist/reporters/json.js +3 -3
- package/dist/reporters/markdown.d.ts +1 -1
- package/dist/reporters/markdown.js +4 -4
- package/dist/reporters/symbols.js +4 -2
- package/dist/reporters/util/configuration-hints.d.ts +1 -1
- package/dist/reporters/util/configuration-hints.js +58 -23
- package/dist/reporters/util/util.d.ts +2 -4
- package/dist/reporters/util/util.js +6 -6
- package/dist/reporters/watch.d.ts +3 -4
- package/dist/reporters/watch.js +5 -5
- package/dist/schema/configuration.d.ts +176 -8
- package/dist/schema/plugins.d.ts +69 -0
- package/dist/schema/plugins.js +3 -0
- package/dist/types/PluginNames.d.ts +2 -2
- package/dist/types/PluginNames.js +3 -0
- package/dist/types/config.d.ts +4 -10
- package/dist/types/entries.d.ts +3 -0
- package/dist/types/entries.js +1 -0
- package/dist/types/issues.d.ts +4 -3
- package/dist/types/{cli.d.ts → options.d.ts} +2 -2
- package/dist/types/options.js +1 -0
- package/dist/types/package-json.d.ts +5 -0
- package/dist/types/project.d.ts +1 -7
- package/dist/types/tsconfig-json.d.ts +14 -0
- package/dist/types/tsconfig-json.js +1 -0
- package/dist/typescript/ast-helpers.js +1 -1
- package/dist/typescript/get-imports-and-exports.d.ts +2 -2
- package/dist/typescript/get-imports-and-exports.js +9 -10
- package/dist/util/Performance.js +16 -6
- package/dist/util/cli-arguments.d.ts +1 -2
- package/dist/util/cli-arguments.js +3 -13
- package/dist/util/create-options.d.ts +1219 -0
- package/dist/util/create-options.js +112 -0
- package/dist/util/debug.js +3 -4
- package/dist/util/errors.d.ts +1 -1
- package/dist/util/file-entry-cache.js +3 -3
- package/dist/util/fs.d.ts +1 -1
- package/dist/util/get-included-issue-types.d.ts +9 -13
- package/dist/util/get-included-issue-types.js +10 -16
- package/dist/util/get-referenced-inputs.js +1 -1
- package/dist/util/glob-core.d.ts +1 -1
- package/dist/util/glob-core.js +8 -7
- package/dist/util/glob.d.ts +1 -0
- package/dist/util/glob.js +1 -1
- package/dist/util/input.d.ts +1 -1
- package/dist/util/input.js +1 -1
- package/dist/util/is-identifier-referenced.d.ts +1 -1
- package/dist/util/is-identifier-referenced.js +19 -19
- package/dist/util/load-config.d.ts +1 -0
- package/dist/util/load-config.js +24 -0
- package/dist/util/package-json.d.ts +2 -1
- package/dist/util/package-json.js +24 -12
- package/dist/util/parse-and-convert-gitignores.js +2 -0
- package/dist/util/path.d.ts +4 -4
- package/dist/util/path.js +5 -7
- package/dist/util/reporter.js +3 -3
- package/dist/util/require.js +1 -2
- package/dist/util/table.js +1 -3
- package/dist/util/tag.d.ts +1 -1
- package/dist/util/to-source-path.d.ts +1 -1
- package/dist/util/to-source-path.js +5 -5
- package/dist/util/trace.d.ts +6 -6
- package/dist/util/trace.js +18 -22
- package/dist/util/watch.d.ts +2 -5
- package/dist/util/watch.js +3 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +10 -15
- package/schema.json +12 -0
- package/dist/util/unwrap-function.d.ts +0 -1
- package/dist/util/unwrap-function.js +0 -13
- /package/dist/{types/cli.js → plugins/rslib/types.js} +0 -0
package/dist/graph/analyze.js
CHANGED
|
@@ -4,16 +4,10 @@ import { getPackageNameFromModuleSpecifier } from '../util/modules.js';
|
|
|
4
4
|
import { findMatch } from '../util/regex.js';
|
|
5
5
|
import { getShouldIgnoreHandler, getShouldIgnoreTagHandler } from '../util/tag.js';
|
|
6
6
|
import { createAndPrintTrace, printTrace } from '../util/trace.js';
|
|
7
|
-
export const analyze = async (options) => {
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const isReportTypes = report.types || report.nsTypes || report.enumMembers;
|
|
12
|
-
const isReportClassMembers = report.classMembers;
|
|
13
|
-
const isSkipLibs = !(isIncludeLibs || isReportClassMembers);
|
|
14
|
-
const shouldIgnore = getShouldIgnoreHandler(isProduction);
|
|
15
|
-
const shouldIgnoreTags = getShouldIgnoreTagHandler(tags);
|
|
16
|
-
const isIdentifierReferenced = getIsIdentifierReferencedHandler(graph, entryPaths);
|
|
7
|
+
export const analyze = async ({ analyzedFiles, chief, collector, deputy, entryPaths, factory, fixer, graph, streamer, unreferencedFiles, options, }) => {
|
|
8
|
+
const shouldIgnore = getShouldIgnoreHandler(options.isProduction);
|
|
9
|
+
const shouldIgnoreTags = getShouldIgnoreTagHandler(options.tags);
|
|
10
|
+
const isIdentifierReferenced = getIsIdentifierReferencedHandler(graph, entryPaths, options.isTrace);
|
|
17
11
|
const ignoreExportsUsedInFile = chief.config.ignoreExportsUsedInFile;
|
|
18
12
|
const isExportedItemReferenced = (exportedItem) => exportedItem.refs[1] ||
|
|
19
13
|
(exportedItem.refs[0] > 0 &&
|
|
@@ -21,7 +15,7 @@ export const analyze = async (options) => {
|
|
|
21
15
|
? exportedItem.type !== 'unknown' && !!ignoreExportsUsedInFile[exportedItem.type]
|
|
22
16
|
: ignoreExportsUsedInFile));
|
|
23
17
|
const analyzeGraph = async () => {
|
|
24
|
-
if (isReportValues || isReportTypes) {
|
|
18
|
+
if (options.isReportValues || options.isReportTypes) {
|
|
25
19
|
streamer.cast('Connecting the dots');
|
|
26
20
|
for (const [filePath, file] of graph.entries()) {
|
|
27
21
|
const exportItems = file.exports;
|
|
@@ -33,7 +27,7 @@ export const analyze = async (options) => {
|
|
|
33
27
|
const principal = factory.getPrincipalByPackageName(workspace.pkgName);
|
|
34
28
|
const isEntry = entryPaths.has(filePath);
|
|
35
29
|
if (!isIncludeEntryExports && isEntry) {
|
|
36
|
-
createAndPrintTrace(filePath, { isEntry });
|
|
30
|
+
createAndPrintTrace(filePath, options, { isEntry });
|
|
37
31
|
continue;
|
|
38
32
|
}
|
|
39
33
|
const importsForExport = file.imported;
|
|
@@ -45,7 +39,7 @@ export const analyze = async (options) => {
|
|
|
45
39
|
const { isReferenced, reExportingEntryFile, traceNode } = isIdentifierReferenced(filePath, identifier, isIncludeEntryExports);
|
|
46
40
|
if ((isReferenced || exportedItem.refs[1]) && isIgnored) {
|
|
47
41
|
for (const tagName of exportedItem.jsDocTags) {
|
|
48
|
-
if (tags[1].includes(tagName.replace(/^@/, ''))) {
|
|
42
|
+
if (options.tags[1].includes(tagName.replace(/^@/, ''))) {
|
|
49
43
|
collector.addTagHint({ type: 'tag', filePath, identifier, tagName });
|
|
50
44
|
}
|
|
51
45
|
}
|
|
@@ -54,7 +48,7 @@ export const analyze = async (options) => {
|
|
|
54
48
|
continue;
|
|
55
49
|
if (reExportingEntryFile) {
|
|
56
50
|
if (!isIncludeEntryExports) {
|
|
57
|
-
createAndPrintTrace(filePath, { identifier, isEntry, hasRef: isReferenced });
|
|
51
|
+
createAndPrintTrace(filePath, options, { identifier, isEntry, hasRef: isReferenced });
|
|
58
52
|
continue;
|
|
59
53
|
}
|
|
60
54
|
const reExportedItem = graph.get(reExportingEntryFile)?.exports.get(identifier);
|
|
@@ -62,10 +56,10 @@ export const analyze = async (options) => {
|
|
|
62
56
|
continue;
|
|
63
57
|
}
|
|
64
58
|
if (traceNode)
|
|
65
|
-
printTrace(traceNode, filePath, identifier);
|
|
59
|
+
printTrace(traceNode, filePath, options, identifier);
|
|
66
60
|
if (isReferenced) {
|
|
67
|
-
if (
|
|
68
|
-
if (!
|
|
61
|
+
if (options.includedIssueTypes.enumMembers && exportedItem.type === 'enum') {
|
|
62
|
+
if (!options.includedIssueTypes.nsTypes && importsForExport.refs.has(identifier))
|
|
69
63
|
continue;
|
|
70
64
|
if (hasStrictlyEnumReferences(importsForExport, identifier))
|
|
71
65
|
continue;
|
|
@@ -91,12 +85,12 @@ export const analyze = async (options) => {
|
|
|
91
85
|
line: member.line,
|
|
92
86
|
col: member.col,
|
|
93
87
|
});
|
|
94
|
-
if (isFix && isIssueAdded && member.fix)
|
|
88
|
+
if (options.isFix && isIssueAdded && member.fix)
|
|
95
89
|
fixer.addUnusedTypeNode(filePath, [member.fix]);
|
|
96
90
|
}
|
|
97
91
|
else if (isIgnored) {
|
|
98
92
|
for (const tagName of exportedItem.jsDocTags) {
|
|
99
|
-
if (tags[1].includes(tagName.replace(/^@/, ''))) {
|
|
93
|
+
if (options.tags[1].includes(tagName.replace(/^@/, ''))) {
|
|
100
94
|
collector.addTagHint({ type: 'tag', filePath, identifier: id, tagName });
|
|
101
95
|
}
|
|
102
96
|
}
|
|
@@ -104,13 +98,13 @@ export const analyze = async (options) => {
|
|
|
104
98
|
}
|
|
105
99
|
}
|
|
106
100
|
}
|
|
107
|
-
if (principal && isReportClassMembers && exportedItem.type === 'class') {
|
|
101
|
+
if (principal && options.isReportClassMembers && exportedItem.type === 'class') {
|
|
108
102
|
const members = exportedItem.members.filter(member => !(findMatch(workspace.ignoreMembers, member.identifier) || shouldIgnore(member.jsDocTags)));
|
|
109
103
|
for (const member of principal.findUnusedMembers(filePath, members)) {
|
|
110
104
|
if (shouldIgnoreTags(member.jsDocTags)) {
|
|
111
105
|
const identifier = `${exportedItem.identifier}.${member.identifier}`;
|
|
112
106
|
for (const tagName of exportedItem.jsDocTags) {
|
|
113
|
-
if (tags[1].includes(tagName.replace(/^@/, ''))) {
|
|
107
|
+
if (options.tags[1].includes(tagName.replace(/^@/, ''))) {
|
|
114
108
|
collector.addTagHint({ type: 'tag', filePath, identifier, tagName });
|
|
115
109
|
}
|
|
116
110
|
}
|
|
@@ -126,7 +120,7 @@ export const analyze = async (options) => {
|
|
|
126
120
|
line: member.line,
|
|
127
121
|
col: member.col,
|
|
128
122
|
});
|
|
129
|
-
if (isFix && isIssueAdded && member.fix)
|
|
123
|
+
if (options.isFix && isIssueAdded && member.fix)
|
|
130
124
|
fixer.addUnusedTypeNode(filePath, [member.fix]);
|
|
131
125
|
}
|
|
132
126
|
}
|
|
@@ -135,12 +129,13 @@ export const analyze = async (options) => {
|
|
|
135
129
|
}
|
|
136
130
|
const [hasStrictlyNsRefs, namespace] = hasStrictlyNsReferences(graph, importsForExport, identifier);
|
|
137
131
|
const isType = ['enum', 'type', 'interface'].includes(exportedItem.type);
|
|
138
|
-
if (hasStrictlyNsRefs &&
|
|
132
|
+
if (hasStrictlyNsRefs &&
|
|
133
|
+
((!options.includedIssueTypes.nsTypes && isType) || !(options.includedIssueTypes.nsExports || isType)))
|
|
139
134
|
continue;
|
|
140
135
|
if (!isExportedItemReferenced(exportedItem)) {
|
|
141
136
|
if (isIgnored)
|
|
142
137
|
continue;
|
|
143
|
-
if (!isSkipLibs && principal?.hasExternalReferences(filePath, exportedItem))
|
|
138
|
+
if (!options.isSkipLibs && principal?.hasExternalReferences(filePath, exportedItem))
|
|
144
139
|
continue;
|
|
145
140
|
const type = getType(hasStrictlyNsRefs, isType);
|
|
146
141
|
const isIssueAdded = collector.addIssue({
|
|
@@ -154,7 +149,7 @@ export const analyze = async (options) => {
|
|
|
154
149
|
line: exportedItem.line,
|
|
155
150
|
col: exportedItem.col,
|
|
156
151
|
});
|
|
157
|
-
if (isFix && isIssueAdded) {
|
|
152
|
+
if (options.isFix && isIssueAdded) {
|
|
158
153
|
if (isType)
|
|
159
154
|
fixer.addUnusedTypeNode(filePath, exportedItem.fixes);
|
|
160
155
|
else
|
|
@@ -201,11 +196,11 @@ export const analyze = async (options) => {
|
|
|
201
196
|
const unusedFiles = [...unreferencedFiles].filter(filePath => !analyzedFiles.has(filePath));
|
|
202
197
|
collector.addFilesIssues(unusedFiles);
|
|
203
198
|
collector.addFileCounts({ processed: analyzedFiles.size, unused: unusedFiles.length });
|
|
204
|
-
if (isReportDependencies) {
|
|
199
|
+
if (options.isReportDependencies) {
|
|
205
200
|
const { dependencyIssues, devDependencyIssues, optionalPeerDependencyIssues } = deputy.settleDependencyIssues();
|
|
206
201
|
for (const issue of dependencyIssues)
|
|
207
202
|
collector.addIssue(issue);
|
|
208
|
-
if (!isProduction)
|
|
203
|
+
if (!options.isProduction)
|
|
209
204
|
for (const issue of devDependencyIssues)
|
|
210
205
|
collector.addIssue(issue);
|
|
211
206
|
for (const issue of optionalPeerDependencyIssues)
|
|
@@ -219,6 +214,8 @@ export const analyze = async (options) => {
|
|
|
219
214
|
for (const identifier of unusedIgnoredWorkspaces) {
|
|
220
215
|
collector.addConfigurationHint({ type: 'ignoreWorkspaces', identifier });
|
|
221
216
|
}
|
|
217
|
+
for (const hint of chief.getConfigurationHints())
|
|
218
|
+
collector.addConfigurationHint(hint);
|
|
222
219
|
};
|
|
223
220
|
await analyzeGraph();
|
|
224
221
|
return analyzeGraph;
|
package/dist/graph/build.d.ts
CHANGED
|
@@ -4,33 +4,19 @@ import type { DependencyDeputy } from '../DependencyDeputy.js';
|
|
|
4
4
|
import type { IssueCollector } from '../IssueCollector.js';
|
|
5
5
|
import type { PrincipalFactory } from '../PrincipalFactory.js';
|
|
6
6
|
import type { ProjectPrincipal } from '../ProjectPrincipal.js';
|
|
7
|
-
import type { Tags } from '../types/cli.js';
|
|
8
|
-
import type { Report } from '../types/issues.js';
|
|
9
7
|
import type { ModuleGraph } from '../types/module-graph.js';
|
|
8
|
+
import type { MainOptions } from '../util/create-options.js';
|
|
10
9
|
interface BuildOptions {
|
|
11
|
-
cacheLocation: string;
|
|
12
10
|
chief: ConfigurationChief;
|
|
13
11
|
collector: IssueCollector;
|
|
14
|
-
cwd: string;
|
|
15
12
|
deputy: DependencyDeputy;
|
|
16
13
|
factory: PrincipalFactory;
|
|
17
|
-
gitignore: boolean;
|
|
18
|
-
isCache: boolean;
|
|
19
|
-
isFixExports: boolean;
|
|
20
|
-
isFixTypes: boolean;
|
|
21
14
|
isGitIgnored: (path: string) => boolean;
|
|
22
|
-
isIsolateWorkspaces: boolean;
|
|
23
|
-
isProduction: boolean;
|
|
24
|
-
isSkipLibs: boolean;
|
|
25
|
-
isStrict: boolean;
|
|
26
|
-
isWatch: boolean;
|
|
27
|
-
report: Report;
|
|
28
15
|
streamer: ConsoleStreamer;
|
|
29
|
-
tags: Tags;
|
|
30
|
-
tsConfigFile?: string;
|
|
31
16
|
workspaces: Workspace[];
|
|
17
|
+
options: MainOptions;
|
|
32
18
|
}
|
|
33
|
-
export declare function build({
|
|
19
|
+
export declare function build({ chief, collector, deputy, factory, isGitIgnored, streamer, workspaces, options, }: BuildOptions): Promise<{
|
|
34
20
|
graph: ModuleGraph;
|
|
35
21
|
entryPaths: Set<string>;
|
|
36
22
|
analyzedFiles: Set<string>;
|
package/dist/graph/build.js
CHANGED
|
@@ -5,30 +5,37 @@ import { DEFAULT_EXTENSIONS, FOREIGN_FILE_EXTENSIONS } from '../constants.js';
|
|
|
5
5
|
import { perfObserver } from '../util/Performance.js';
|
|
6
6
|
import { debugLog, debugLogArray } from '../util/debug.js';
|
|
7
7
|
import { getReferencedInputsHandler } from '../util/get-referenced-inputs.js';
|
|
8
|
-
import { _glob, negate } from '../util/glob.js';
|
|
8
|
+
import { _glob, _syncGlob, negate } from '../util/glob.js';
|
|
9
9
|
import { isAlias, isConfig, isDeferResolveEntry, isDeferResolveProductionEntry, isEntry, isIgnore, isProductionEntry, isProject, toProductionEntry, } from '../util/input.js';
|
|
10
10
|
import { loadTSConfig } from '../util/load-tsconfig.js';
|
|
11
11
|
import { getOrCreateFileNode, updateImportMap } from '../util/module-graph.js';
|
|
12
12
|
import { getPackageNameFromModuleSpecifier, isStartsLikePackageName, sanitizeSpecifier } from '../util/modules.js';
|
|
13
|
-
import {
|
|
13
|
+
import { getEntrySpecifiersFromManifest, getManifestImportDependencies } from '../util/package-json.js';
|
|
14
14
|
import { dirname, extname, isAbsolute, join, relative, toRelative } from '../util/path.js';
|
|
15
15
|
import { augmentWorkspace, getToSourcePathHandler, getToSourcePathsHandler } from '../util/to-source-path.js';
|
|
16
|
-
export async function build({
|
|
16
|
+
export async function build({ chief, collector, deputy, factory, isGitIgnored, streamer, workspaces, options, }) {
|
|
17
17
|
const configFilesMap = new Map();
|
|
18
18
|
const enabledPluginsStore = new Map();
|
|
19
19
|
const toSourceFilePath = getToSourcePathHandler(chief);
|
|
20
20
|
const toSourceFilePaths = getToSourcePathsHandler(chief);
|
|
21
21
|
const getReferencedInternalFilePath = getReferencedInputsHandler(collector, deputy, chief, isGitIgnored);
|
|
22
|
-
const isReportClassMembers = report.classMembers;
|
|
23
22
|
for (const workspace of workspaces) {
|
|
24
23
|
const { name, dir, manifestPath, manifestStr } = workspace;
|
|
25
24
|
const manifest = chief.getManifestForWorkspace(name);
|
|
26
25
|
if (!manifest)
|
|
27
26
|
continue;
|
|
28
|
-
deputy.addWorkspace({
|
|
27
|
+
deputy.addWorkspace({
|
|
28
|
+
name,
|
|
29
|
+
cwd: options.cwd,
|
|
30
|
+
dir,
|
|
31
|
+
manifestPath,
|
|
32
|
+
manifestStr,
|
|
33
|
+
manifest,
|
|
34
|
+
...chief.getIgnores(name),
|
|
35
|
+
});
|
|
29
36
|
}
|
|
30
37
|
for (const workspace of workspaces) {
|
|
31
|
-
const { name, dir, ancestors, pkgName } = workspace;
|
|
38
|
+
const { name, dir, ancestors, pkgName, manifestPath: filePath } = workspace;
|
|
32
39
|
streamer.cast('Analyzing workspace', name);
|
|
33
40
|
const manifest = chief.getManifestForWorkspace(name);
|
|
34
41
|
if (!manifest)
|
|
@@ -38,29 +45,25 @@ export async function build({ cacheLocation, chief, collector, cwd, deputy, fact
|
|
|
38
45
|
const extensions = getCompilerExtensions(compilers);
|
|
39
46
|
const extensionGlobStr = `.{${[...DEFAULT_EXTENSIONS, ...extensions].map(ext => ext.slice(1)).join(',')}}`;
|
|
40
47
|
const config = chief.getConfigForWorkspace(name, extensions);
|
|
41
|
-
const tsConfigFilePath = join(dir, tsConfigFile ?? 'tsconfig.json');
|
|
48
|
+
const tsConfigFilePath = join(dir, options.tsConfigFile ?? 'tsconfig.json');
|
|
42
49
|
const { isFile, compilerOptions, definitionPaths } = await loadTSConfig(tsConfigFilePath);
|
|
43
50
|
if (isFile)
|
|
44
51
|
augmentWorkspace(workspace, dir, compilerOptions);
|
|
45
52
|
const worker = new WorkspaceWorker({
|
|
46
53
|
name,
|
|
47
54
|
dir,
|
|
48
|
-
cwd,
|
|
49
55
|
config,
|
|
50
56
|
manifest,
|
|
51
57
|
dependencies,
|
|
52
58
|
getReferencedInternalFilePath: (input) => getReferencedInternalFilePath(input, workspace),
|
|
53
59
|
findWorkspaceByFilePath: chief.findWorkspaceByFilePath.bind(chief),
|
|
54
|
-
isProduction,
|
|
55
|
-
isStrict,
|
|
56
60
|
rootIgnore: chief.config.ignore,
|
|
57
61
|
negatedWorkspacePatterns: chief.getNegatedWorkspacePatterns(name),
|
|
58
62
|
ignoredWorkspacePatterns: chief.getIgnoredWorkspacesFor(name),
|
|
59
63
|
enabledPluginsInAncestors: ancestors.flatMap(ancestor => enabledPluginsStore.get(ancestor) ?? []),
|
|
60
64
|
getSourceFile: (filePath) => principal.backend.fileManager.getSourceFile(filePath),
|
|
61
|
-
isCache,
|
|
62
|
-
cacheLocation,
|
|
63
65
|
configFilesMap,
|
|
66
|
+
options,
|
|
64
67
|
});
|
|
65
68
|
await worker.init();
|
|
66
69
|
const inputs = new Set();
|
|
@@ -70,25 +73,29 @@ export async function build({ cacheLocation, chief, collector, cwd, deputy, fact
|
|
|
70
73
|
inputs.add(toProductionEntry(id, { containingFilePath: tsConfigFilePath }));
|
|
71
74
|
}
|
|
72
75
|
const ignore = worker.getIgnorePatterns();
|
|
73
|
-
const sharedGlobOptions = { cwd, dir, gitignore };
|
|
74
|
-
collector.addIgnorePatterns(ignore.map(pattern => join(cwd, pattern)));
|
|
75
|
-
const
|
|
76
|
-
for (const filePath of await toSourceFilePaths(
|
|
76
|
+
const sharedGlobOptions = { cwd: options.cwd, dir, gitignore: options.gitignore };
|
|
77
|
+
collector.addIgnorePatterns(ignore.map(pattern => join(options.cwd, pattern)));
|
|
78
|
+
const entrySpecifiersFromManifest = getEntrySpecifiersFromManifest(manifest);
|
|
79
|
+
for (const filePath of await toSourceFilePaths(entrySpecifiersFromManifest, dir, extensionGlobStr)) {
|
|
77
80
|
inputs.add(toProductionEntry(filePath));
|
|
78
81
|
}
|
|
79
|
-
const
|
|
80
|
-
|
|
82
|
+
for (const identifier of entrySpecifiersFromManifest) {
|
|
83
|
+
if (!identifier.startsWith('!') && !isGitIgnored(join(dir, identifier))) {
|
|
84
|
+
const files = _syncGlob({ patterns: [identifier], cwd: dir });
|
|
85
|
+
if (files.length === 0) {
|
|
86
|
+
collector.addConfigurationHint({ type: 'package-entry', filePath, identifier, workspaceName: name });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
for (const dep of getManifestImportDependencies(manifest))
|
|
91
|
+
deputy.addReferencedDependency(name, dep);
|
|
92
|
+
const principal = factory.createPrincipal(options, {
|
|
93
|
+
dir,
|
|
81
94
|
isFile,
|
|
82
95
|
compilerOptions,
|
|
83
96
|
compilers,
|
|
84
97
|
pkgName,
|
|
85
|
-
isIsolateWorkspaces,
|
|
86
|
-
isSkipLibs,
|
|
87
|
-
isWatch,
|
|
88
98
|
toSourceFilePath,
|
|
89
|
-
isCache,
|
|
90
|
-
cacheLocation,
|
|
91
|
-
isProduction,
|
|
92
99
|
});
|
|
93
100
|
principal.addPaths(config.paths, dir);
|
|
94
101
|
const inputsFromPlugins = await worker.runPlugins();
|
|
@@ -142,7 +149,7 @@ export async function build({ cacheLocation, chief, collector, cwd, deputy, fact
|
|
|
142
149
|
productionPatternsSkipExports.add(resolvedFilePath);
|
|
143
150
|
}
|
|
144
151
|
else if (isDeferResolveEntry(input)) {
|
|
145
|
-
if (!isProduction || !input.optional)
|
|
152
|
+
if (!options.isProduction || !input.optional)
|
|
146
153
|
entryPatternsSkipExports.add(resolvedFilePath);
|
|
147
154
|
}
|
|
148
155
|
else {
|
|
@@ -151,7 +158,7 @@ export async function build({ cacheLocation, chief, collector, cwd, deputy, fact
|
|
|
151
158
|
}
|
|
152
159
|
}
|
|
153
160
|
}
|
|
154
|
-
if (isProduction) {
|
|
161
|
+
if (options.isProduction) {
|
|
155
162
|
const negatedEntryPatterns = [...entryPatterns, ...entryPatternsSkipExports].map(negate);
|
|
156
163
|
{
|
|
157
164
|
const label = 'entry paths';
|
|
@@ -160,7 +167,7 @@ export async function build({ cacheLocation, chief, collector, cwd, deputy, fact
|
|
|
160
167
|
principal.addEntryPaths(workspaceEntryPaths);
|
|
161
168
|
}
|
|
162
169
|
{
|
|
163
|
-
const label = 'production entry paths from plugins (
|
|
170
|
+
const label = 'production entry paths from plugins (ignore exports)';
|
|
164
171
|
const patterns = Array.from(productionPatternsSkipExports);
|
|
165
172
|
const pluginWorkspaceEntryPaths = await _glob({ ...sharedGlobOptions, patterns, label });
|
|
166
173
|
principal.addEntryPaths(pluginWorkspaceEntryPaths, { skipExportsAnalysis: true });
|
|
@@ -181,7 +188,7 @@ export async function build({ cacheLocation, chief, collector, cwd, deputy, fact
|
|
|
181
188
|
}
|
|
182
189
|
else {
|
|
183
190
|
{
|
|
184
|
-
const label = 'entry paths from plugins (
|
|
191
|
+
const label = 'entry paths from plugins (ignore exports)';
|
|
185
192
|
const patterns = worker.getPluginEntryFilePatterns([
|
|
186
193
|
...entryPatternsSkipExports,
|
|
187
194
|
...productionPatternsSkipExports,
|
|
@@ -212,7 +219,7 @@ export async function build({ cacheLocation, chief, collector, cwd, deputy, fact
|
|
|
212
219
|
principal.addProjectPath(projectPath);
|
|
213
220
|
}
|
|
214
221
|
{
|
|
215
|
-
const label = 'plugin configuration paths (
|
|
222
|
+
const label = 'plugin configuration paths (ignore exports)';
|
|
216
223
|
const patterns = worker.getPluginConfigPatterns();
|
|
217
224
|
const configurationEntryPaths = await _glob({ ...sharedGlobOptions, patterns, label });
|
|
218
225
|
principal.addEntryPaths(configurationEntryPaths, { skipExportsAnalysis: true });
|
|
@@ -228,8 +235,8 @@ export async function build({ cacheLocation, chief, collector, cwd, deputy, fact
|
|
|
228
235
|
principal.addProjectPath(projectPath);
|
|
229
236
|
}
|
|
230
237
|
}
|
|
231
|
-
if (
|
|
232
|
-
|
|
238
|
+
if (options.configFilePath) {
|
|
239
|
+
factory.getPrincipals().at(0)?.addEntryPath(options.configFilePath, { skipExportsAnalysis: true });
|
|
233
240
|
}
|
|
234
241
|
worker.onDispose();
|
|
235
242
|
}
|
|
@@ -245,20 +252,20 @@ export async function build({ cacheLocation, chief, collector, cwd, deputy, fact
|
|
|
245
252
|
if (workspace)
|
|
246
253
|
return factory.getPrincipalByPackageName(workspace.pkgName);
|
|
247
254
|
};
|
|
255
|
+
const analyzeOpts = {
|
|
256
|
+
isFixExports: options.isFixUnusedExports,
|
|
257
|
+
isFixTypes: options.isFixUnusedTypes,
|
|
258
|
+
isReportClassMembers: options.isReportClassMembers,
|
|
259
|
+
skipTypeOnly: options.isStrict,
|
|
260
|
+
tags: options.tags,
|
|
261
|
+
};
|
|
248
262
|
const analyzeSourceFile = (filePath, principal) => {
|
|
249
|
-
if (!isWatch && analyzedFiles.has(filePath))
|
|
263
|
+
if (!options.isWatch && analyzedFiles.has(filePath))
|
|
250
264
|
return;
|
|
251
265
|
analyzedFiles.add(filePath);
|
|
252
266
|
const workspace = chief.findWorkspaceByFilePath(filePath);
|
|
253
267
|
if (workspace) {
|
|
254
|
-
const file = principal.analyzeSourceFile(filePath,
|
|
255
|
-
skipTypeOnly: isStrict,
|
|
256
|
-
isFixExports,
|
|
257
|
-
isFixTypes,
|
|
258
|
-
ignoreExportsUsedInFile: chief.config.ignoreExportsUsedInFile,
|
|
259
|
-
isReportClassMembers,
|
|
260
|
-
tags,
|
|
261
|
-
});
|
|
268
|
+
const file = principal.analyzeSourceFile(filePath, analyzeOpts, chief.config.ignoreExportsUsedInFile);
|
|
262
269
|
const _unresolved = new Set();
|
|
263
270
|
for (const unresolvedImport of file.imports.unresolved) {
|
|
264
271
|
const { specifier } = unresolvedImport;
|
|
@@ -297,8 +304,14 @@ export async function build({ cacheLocation, chief, collector, cwd, deputy, fact
|
|
|
297
304
|
const dependencies = deputy.getDependencies(workspace.name);
|
|
298
305
|
const manifestScriptNames = new Set(Object.keys(chief.getManifestForWorkspace(workspace.name)?.scripts ?? {}));
|
|
299
306
|
const dir = dirname(filePath);
|
|
300
|
-
const
|
|
301
|
-
|
|
307
|
+
const opts = {
|
|
308
|
+
cwd: dir,
|
|
309
|
+
rootCwd: options.cwd,
|
|
310
|
+
containingFilePath: filePath,
|
|
311
|
+
dependencies,
|
|
312
|
+
manifestScriptNames,
|
|
313
|
+
};
|
|
314
|
+
const inputs = _getInputsFromScripts(file.scripts, opts);
|
|
302
315
|
for (const input of inputs) {
|
|
303
316
|
input.containingFilePath ??= filePath;
|
|
304
317
|
input.dir ??= dir;
|
|
@@ -324,7 +337,7 @@ export async function build({ cacheLocation, chief, collector, cwd, deputy, fact
|
|
|
324
337
|
streamer.cast('Running async compilers');
|
|
325
338
|
await principal.runAsyncCompilers();
|
|
326
339
|
}
|
|
327
|
-
streamer.cast('Analyzing source files', toRelative(principal.cwd));
|
|
340
|
+
streamer.cast('Analyzing source files', toRelative(principal.cwd, options.cwd));
|
|
328
341
|
let size = principal.entryPaths.size;
|
|
329
342
|
let round = 0;
|
|
330
343
|
do {
|
|
@@ -340,16 +353,16 @@ export async function build({ cacheLocation, chief, collector, cwd, deputy, fact
|
|
|
340
353
|
for (const filePath of principal.entryPaths)
|
|
341
354
|
entryPaths.add(filePath);
|
|
342
355
|
principal.reconcileCache(graph);
|
|
343
|
-
if (isIsolateWorkspaces || (isSkipLibs && !isWatch)) {
|
|
344
|
-
factory.deletePrincipal(principal);
|
|
356
|
+
if (options.isIsolateWorkspaces || (options.isSkipLibs && !options.isWatch)) {
|
|
357
|
+
factory.deletePrincipal(principal, options.cwd);
|
|
345
358
|
principals[i] = undefined;
|
|
346
359
|
}
|
|
347
360
|
perfObserver.addMemoryMark(factory.getPrincipalCount());
|
|
348
361
|
}
|
|
349
|
-
if (!isWatch && isSkipLibs && !isIsolateWorkspaces) {
|
|
362
|
+
if (!options.isWatch && options.isSkipLibs && !options.isIsolateWorkspaces) {
|
|
350
363
|
for (const principal of principals) {
|
|
351
364
|
if (principal)
|
|
352
|
-
factory.deletePrincipal(principal);
|
|
365
|
+
factory.deletePrincipal(principal, options.cwd);
|
|
353
366
|
}
|
|
354
367
|
principals.length = 0;
|
|
355
368
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MainOptions } from './util/create-options.js';
|
|
2
2
|
export type { RawConfiguration as KnipConfig } from './types/config.js';
|
|
3
3
|
export type { Preprocessor, Reporter, ReporterOptions } from './types/issues.js';
|
|
4
|
-
export declare const main: (
|
|
5
|
-
report: import("./types/issues.js").Report;
|
|
4
|
+
export declare const main: (options: MainOptions) => Promise<{
|
|
6
5
|
issues: import("./types/issues.js").Issues;
|
|
7
6
|
counters: import("./types/issues.js").Counters;
|
|
8
|
-
rules: import("./types/issues.js").Rules;
|
|
9
7
|
tagHints: Set<import("./types/issues.js").TagHint>;
|
|
10
8
|
configurationHints: Set<import("./types/issues.js").ConfigurationHint>;
|
|
11
|
-
|
|
12
|
-
includedWorkspaces: import("./ConfigurationChief.js").Workspace[];
|
|
9
|
+
includedWorkspaceDirs: string[];
|
|
13
10
|
}>;
|
package/dist/index.js
CHANGED
|
@@ -11,57 +11,30 @@ import { build } from './graph/build.js';
|
|
|
11
11
|
import { debugLogArray, debugLogObject } from './util/debug.js';
|
|
12
12
|
import { getGitIgnoredHandler } from './util/glob-core.js';
|
|
13
13
|
import { getWatchHandler } from './util/watch.js';
|
|
14
|
-
export const main = async (
|
|
15
|
-
const {
|
|
16
|
-
debugLogObject('*', 'Unresolved configuration
|
|
17
|
-
|
|
18
|
-
const
|
|
14
|
+
export const main = async (options) => {
|
|
15
|
+
const { cwd } = options;
|
|
16
|
+
debugLogObject('*', 'Unresolved configuration', options);
|
|
17
|
+
debugLogObject('*', 'Included issue types', options.includedIssueTypes);
|
|
18
|
+
const chief = new ConfigurationChief(options);
|
|
19
|
+
const deputy = new DependencyDeputy(options);
|
|
19
20
|
const factory = new PrincipalFactory();
|
|
20
|
-
const streamer = new ConsoleStreamer(
|
|
21
|
+
const streamer = new ConsoleStreamer(options);
|
|
22
|
+
const fixer = new IssueFixer(options);
|
|
23
|
+
const collector = new IssueCollector(options);
|
|
21
24
|
streamer.cast('Reading workspace configuration');
|
|
22
|
-
await chief.
|
|
23
|
-
const
|
|
24
|
-
const report = chief.getIncludedIssueTypes({
|
|
25
|
-
includedIssueTypes,
|
|
26
|
-
excludedIssueTypes,
|
|
27
|
-
isDependenciesShorthand,
|
|
28
|
-
isExportsShorthand,
|
|
29
|
-
isFilesShorthand,
|
|
30
|
-
});
|
|
31
|
-
const rules = chief.getRules();
|
|
32
|
-
const filters = chief.getFilters();
|
|
33
|
-
const finalTags = tags[0].length > 0 || tags[1].length > 0 ? tags : chief.getTags();
|
|
34
|
-
const fixer = new IssueFixer({ isEnabled: isFix, cwd, fixTypes, isRemoveFiles });
|
|
35
|
-
debugLogObject('*', 'Included issue types', report);
|
|
36
|
-
const isReportClassMembers = report.classMembers;
|
|
37
|
-
const isSkipLibs = !(isIncludeLibs || isReportClassMembers);
|
|
38
|
-
const collector = new IssueCollector({ cwd, rules, filters });
|
|
39
|
-
const o = () => workspaces.map(w => ({ pkgName: w.pkgName, name: w.name, config: w.config, ancestors: w.ancestors }));
|
|
25
|
+
const workspaces = await chief.getWorkspaces();
|
|
26
|
+
const isGitIgnored = await getGitIgnoredHandler(options);
|
|
40
27
|
debugLogObject('*', 'Included workspaces', () => workspaces.map(w => w.pkgName));
|
|
41
|
-
debugLogObject('*', 'Included workspace configs',
|
|
42
|
-
const isGitIgnored = await getGitIgnoredHandler({ cwd, gitignore });
|
|
28
|
+
debugLogObject('*', 'Included workspace configs', () => workspaces.map(w => ({ pkgName: w.pkgName, name: w.name, config: w.config, ancestors: w.ancestors })));
|
|
43
29
|
const { graph, entryPaths, analyzedFiles, unreferencedFiles, analyzeSourceFile } = await build({
|
|
44
|
-
cacheLocation,
|
|
45
30
|
chief,
|
|
46
31
|
collector,
|
|
47
|
-
cwd,
|
|
48
32
|
deputy,
|
|
49
33
|
factory,
|
|
50
|
-
gitignore,
|
|
51
|
-
isCache,
|
|
52
|
-
isFixExports: fixer.isEnabled && fixer.isFixUnusedExports,
|
|
53
|
-
isFixTypes: fixer.isEnabled && fixer.isFixUnusedTypes,
|
|
54
34
|
isGitIgnored,
|
|
55
|
-
isIsolateWorkspaces,
|
|
56
|
-
isProduction,
|
|
57
|
-
isSkipLibs,
|
|
58
|
-
isStrict,
|
|
59
|
-
isWatch,
|
|
60
|
-
report,
|
|
61
35
|
streamer,
|
|
62
|
-
tags: finalTags,
|
|
63
|
-
tsConfigFile,
|
|
64
36
|
workspaces,
|
|
37
|
+
options,
|
|
65
38
|
});
|
|
66
39
|
const reAnalyze = await analyze({
|
|
67
40
|
analyzedFiles,
|
|
@@ -72,41 +45,32 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
72
45
|
factory,
|
|
73
46
|
fixer,
|
|
74
47
|
graph,
|
|
75
|
-
isFix,
|
|
76
|
-
isIncludeLibs,
|
|
77
|
-
isProduction,
|
|
78
|
-
report,
|
|
79
48
|
streamer,
|
|
80
|
-
tags: finalTags,
|
|
81
49
|
unreferencedFiles,
|
|
50
|
+
options,
|
|
82
51
|
});
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (isWatch) {
|
|
87
|
-
const isIgnored = (filePath) => filePath.startsWith(cacheLocation) || filePath.includes('/.git/') || isGitIgnored(filePath);
|
|
88
|
-
const watchHandler = await getWatchHandler({
|
|
52
|
+
if (options.isWatch) {
|
|
53
|
+
const isIgnored = (filePath) => filePath.startsWith(options.cacheLocation) || filePath.includes('/.git/') || isGitIgnored(filePath);
|
|
54
|
+
const watchHandler = await getWatchHandler(options, {
|
|
89
55
|
analyzedFiles,
|
|
90
56
|
analyzeSourceFile,
|
|
91
57
|
chief,
|
|
92
58
|
collector,
|
|
93
59
|
analyze: reAnalyze,
|
|
94
|
-
cwd,
|
|
95
60
|
factory,
|
|
96
61
|
graph,
|
|
97
|
-
isDebug,
|
|
98
62
|
isIgnored,
|
|
99
|
-
report,
|
|
100
63
|
streamer,
|
|
101
64
|
unreferencedFiles,
|
|
102
65
|
});
|
|
103
66
|
watch('.', { recursive: true }, watchHandler);
|
|
104
67
|
}
|
|
105
|
-
|
|
68
|
+
const { issues, counters, tagHints, configurationHints } = collector.getIssues();
|
|
69
|
+
if (options.isFix) {
|
|
106
70
|
const touchedFiles = await fixer.fixIssues(issues);
|
|
107
|
-
if (isFormat) {
|
|
71
|
+
if (options.isFormat) {
|
|
108
72
|
const report = await formatly(Array.from(touchedFiles), { cwd });
|
|
109
|
-
if (report.ran && report.result.code === 0) {
|
|
73
|
+
if (report.ran && report.result && (report.result.runner === 'virtual' || report.result.code === 0)) {
|
|
110
74
|
debugLogArray('*', `Formatted files using ${report.formatter.name} (${report.formatter.runner})`, touchedFiles);
|
|
111
75
|
}
|
|
112
76
|
else {
|
|
@@ -114,16 +78,13 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
114
78
|
}
|
|
115
79
|
}
|
|
116
80
|
}
|
|
117
|
-
if (!isWatch)
|
|
81
|
+
if (!options.isWatch)
|
|
118
82
|
streamer.clear();
|
|
119
83
|
return {
|
|
120
|
-
report,
|
|
121
84
|
issues,
|
|
122
85
|
counters,
|
|
123
|
-
rules,
|
|
124
86
|
tagHints,
|
|
125
87
|
configurationHints,
|
|
126
|
-
|
|
127
|
-
includedWorkspaces: chief.includedWorkspaces,
|
|
88
|
+
includedWorkspaceDirs: chief.includedWorkspaces.map(w => w.dir),
|
|
128
89
|
};
|
|
129
90
|
};
|
|
@@ -6,8 +6,11 @@ const enablers = ['astro'];
|
|
|
6
6
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
7
7
|
export const config = ['astro.config.{js,cjs,mjs,ts,mts}'];
|
|
8
8
|
const entry = ['src/content/config.ts', 'src/content.config.ts'];
|
|
9
|
+
const project = ['src/**/*'];
|
|
9
10
|
const production = [
|
|
10
11
|
'src/pages/**/*.{astro,mdx,js,ts}',
|
|
12
|
+
'!src/pages/**/_*',
|
|
13
|
+
'!src/pages/**/_*/**',
|
|
11
14
|
'src/content/**/*.mdx',
|
|
12
15
|
'src/middleware.{js,ts}',
|
|
13
16
|
'src/actions/index.{js,ts}',
|
|
@@ -39,4 +42,5 @@ export default {
|
|
|
39
42
|
production,
|
|
40
43
|
resolveFromAST,
|
|
41
44
|
resolve,
|
|
45
|
+
project,
|
|
42
46
|
};
|