knip 5.65.0 → 5.66.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/dist/ConfigurationChief.d.ts +12 -6
- package/dist/ConfigurationChief.js +2 -0
- package/dist/ConsoleStreamer.d.ts +2 -1
- package/dist/ConsoleStreamer.js +10 -5
- package/dist/IssueCollector.d.ts +8 -1
- package/dist/IssueCollector.js +40 -5
- package/dist/compilers/index.d.ts +15 -11
- package/dist/constants.d.ts +28 -3
- package/dist/constants.js +10 -0
- package/dist/graph/build.js +2 -1
- package/dist/index.js +6 -1
- package/dist/plugins/danger/index.d.ts +8 -0
- package/dist/plugins/danger/index.js +11 -0
- package/dist/plugins/eleventy/helpers.d.ts +1 -0
- package/dist/plugins/eleventy/helpers.js +1 -0
- package/dist/plugins/index.d.ts +6 -0
- package/dist/plugins/index.js +2 -0
- package/dist/plugins/nuxt/index.js +5 -1
- package/dist/reporters/util/util.d.ts +2 -2
- package/dist/reporters/util/util.js +2 -3
- package/dist/reporters/watch.d.ts +2 -2
- package/dist/reporters/watch.js +3 -3
- package/dist/schema/configuration.d.ts +12 -6
- package/dist/schema/configuration.js +5 -8
- package/dist/schema/plugins.d.ts +5 -0
- package/dist/schema/plugins.js +1 -0
- package/dist/types/PluginNames.d.ts +2 -2
- package/dist/types/PluginNames.js +1 -0
- package/dist/types/config.d.ts +4 -2
- package/dist/types/issues.d.ts +2 -10
- package/dist/types/issues.js +1 -11
- package/dist/typescript/ast-helpers.d.ts +3 -3
- package/dist/typescript/ast-helpers.js +11 -12
- package/dist/typescript/visitors/exports/exportDeclaration.js +4 -5
- package/dist/typescript/visitors/exports/exportKeyword.js +9 -10
- package/dist/typescript/visitors/exports/exportsAccessExpression.js +2 -3
- package/dist/typescript/visitors/exports/moduleExportsAccessExpression.js +5 -6
- package/dist/util/Performance.d.ts +1 -1
- package/dist/util/Performance.js +2 -2
- package/dist/util/create-options.d.ts +17 -13
- package/dist/util/create-options.js +1 -1
- package/dist/util/fs.d.ts +2 -1
- package/dist/util/fs.js +14 -4
- package/dist/util/get-included-issue-types.js +1 -4
- package/dist/util/get-referenced-inputs.d.ts +2 -2
- package/dist/util/get-referenced-inputs.js +5 -5
- package/dist/util/has-strictly-ns-references.d.ts +1 -1
- package/dist/util/loader.js +6 -3
- package/dist/util/string.js +5 -1
- package/dist/util/watch.d.ts +7 -3
- package/dist/util/watch.js +106 -67
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/schema.json +20 -0
package/dist/util/loader.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LoaderError } from './errors.js';
|
|
2
|
-
import { loadFile, loadJSON, loadTOML, loadYAML,
|
|
2
|
+
import { loadFile, loadJSON, loadJSONC, loadTOML, loadYAML, parseJSONC, parseYAML } from './fs.js';
|
|
3
3
|
import { jiti } from './jiti.js';
|
|
4
4
|
import { timerify } from './Performance.js';
|
|
5
5
|
import { extname, isInternal } from './path.js';
|
|
@@ -12,7 +12,7 @@ const load = async (filePath) => {
|
|
|
12
12
|
return parseYAML(contents);
|
|
13
13
|
}
|
|
14
14
|
catch {
|
|
15
|
-
return
|
|
15
|
+
return parseJSONC(filePath, contents);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
if (ext === '.yaml' || ext === '.yml') {
|
|
@@ -21,9 +21,12 @@ const load = async (filePath) => {
|
|
|
21
21
|
if (ext === '' && isInternal(filePath)) {
|
|
22
22
|
return await loadFile(filePath);
|
|
23
23
|
}
|
|
24
|
-
if (ext === '.json'
|
|
24
|
+
if (ext === '.json') {
|
|
25
25
|
return await loadJSON(filePath);
|
|
26
26
|
}
|
|
27
|
+
if (ext === '.jsonc' || ext === '.json5') {
|
|
28
|
+
return await loadJSONC(filePath);
|
|
29
|
+
}
|
|
27
30
|
if (typeof Bun !== 'undefined') {
|
|
28
31
|
const imported = await import(filePath);
|
|
29
32
|
return imported.default ?? imported;
|
package/dist/util/string.js
CHANGED
|
@@ -64,5 +64,9 @@ export const prettyMilliseconds = (ms) => {
|
|
|
64
64
|
return `${hours}h ${minutes % 60}m ${Math.floor(seconds % 60)}s`;
|
|
65
65
|
if (minutes > 0)
|
|
66
66
|
return `${minutes}m ${Math.floor(seconds % 60)}s`;
|
|
67
|
-
|
|
67
|
+
if (seconds > 10)
|
|
68
|
+
return `${Math.round(seconds)}s`;
|
|
69
|
+
if (seconds > 1)
|
|
70
|
+
return `${seconds.toFixed(1)}s`;
|
|
71
|
+
return `${Math.round(ms)}ms`;
|
|
68
72
|
};
|
package/dist/util/watch.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import type { WatchListener } from 'node:fs';
|
|
2
2
|
import type { ConfigurationChief } from '../ConfigurationChief.js';
|
|
3
|
-
import type { ConsoleStreamer } from '../ConsoleStreamer.js';
|
|
4
3
|
import type { IssueCollector } from '../IssueCollector.js';
|
|
5
4
|
import type { PrincipalFactory } from '../PrincipalFactory.js';
|
|
6
5
|
import type { ProjectPrincipal } from '../ProjectPrincipal.js';
|
|
6
|
+
import type { Issues } from '../types/issues.js';
|
|
7
7
|
import type { ModuleGraph } from '../types/module-graph.js';
|
|
8
8
|
import type { MainOptions } from './create-options.js';
|
|
9
|
+
export type OnUpdate = (options: {
|
|
10
|
+
issues: Issues;
|
|
11
|
+
duration?: number;
|
|
12
|
+
}) => void;
|
|
9
13
|
type Watch = {
|
|
10
14
|
analyzedFiles: Set<string>;
|
|
11
15
|
analyzeSourceFile: (filePath: string, principal: ProjectPrincipal) => void;
|
|
@@ -15,8 +19,8 @@ type Watch = {
|
|
|
15
19
|
factory: PrincipalFactory;
|
|
16
20
|
graph: ModuleGraph;
|
|
17
21
|
isIgnored: (path: string) => boolean;
|
|
18
|
-
|
|
22
|
+
onUpdate: OnUpdate;
|
|
19
23
|
unreferencedFiles: Set<string>;
|
|
20
24
|
};
|
|
21
|
-
export declare const getWatchHandler: (options: MainOptions, { analyzedFiles, analyzeSourceFile, chief, collector, analyze, factory, graph, isIgnored,
|
|
25
|
+
export declare const getWatchHandler: (options: MainOptions, { analyzedFiles, analyzeSourceFile, chief, collector, analyze, factory, graph, isIgnored, onUpdate, unreferencedFiles, }: Watch) => Promise<WatchListener<string | Buffer<ArrayBufferLike>>>;
|
|
22
26
|
export {};
|
package/dist/util/watch.js
CHANGED
|
@@ -1,85 +1,124 @@
|
|
|
1
|
-
import watchReporter from '../reporters/watch.js';
|
|
2
1
|
import { debugLog } from './debug.js';
|
|
3
2
|
import { isFile } from './fs.js';
|
|
4
3
|
import { updateImportMap } from './module-graph.js';
|
|
5
|
-
import { join,
|
|
6
|
-
export const getWatchHandler = async (options, { analyzedFiles, analyzeSourceFile, chief, collector, analyze, factory, graph, isIgnored,
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
const
|
|
4
|
+
import { join, toAbsolute, toRelative } from './path.js';
|
|
5
|
+
export const getWatchHandler = async (options, { analyzedFiles, analyzeSourceFile, chief, collector, analyze, factory, graph, isIgnored, onUpdate, unreferencedFiles, }) => {
|
|
6
|
+
const getIssues = () => collector.getIssues().issues;
|
|
7
|
+
const processBatch = async (changes) => {
|
|
8
|
+
const startTime = performance.now();
|
|
9
|
+
const added = new Set();
|
|
10
|
+
const deleted = new Set();
|
|
11
|
+
const modified = new Set();
|
|
12
|
+
for (const [type, _path] of changes) {
|
|
13
|
+
const filePath = toAbsolute(_path, options.cwd);
|
|
14
|
+
const relativePath = toRelative(_path, options.cwd);
|
|
16
15
|
if (isIgnored(filePath)) {
|
|
17
|
-
debugLog('*', `ignoring ${
|
|
18
|
-
|
|
16
|
+
debugLog('*', `ignoring ${type} ${relativePath}`);
|
|
17
|
+
continue;
|
|
19
18
|
}
|
|
20
19
|
const workspace = chief.findWorkspaceByFilePath(filePath);
|
|
21
|
-
if (workspace)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
20
|
+
if (!workspace)
|
|
21
|
+
continue;
|
|
22
|
+
const principal = factory.getPrincipalByPackageName(workspace.pkgName);
|
|
23
|
+
if (!principal)
|
|
24
|
+
continue;
|
|
25
|
+
switch (type) {
|
|
26
|
+
case 'added':
|
|
27
|
+
added.add(filePath);
|
|
28
|
+
principal.addProjectPath(filePath);
|
|
29
|
+
principal.deletedFiles.delete(filePath);
|
|
30
|
+
debugLog(workspace.name, `Watcher: + ${relativePath}`);
|
|
31
|
+
break;
|
|
32
|
+
case 'deleted':
|
|
33
|
+
deleted.add(filePath);
|
|
34
|
+
analyzedFiles.delete(filePath);
|
|
35
|
+
principal.removeProjectPath(filePath);
|
|
36
|
+
debugLog(workspace.name, `Watcher: - ${relativePath}`);
|
|
37
|
+
break;
|
|
38
|
+
case 'modified':
|
|
39
|
+
modified.add(filePath);
|
|
40
|
+
debugLog(workspace.name, `Watcher: ± ${relativePath}`);
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
principal.invalidateFile(filePath);
|
|
44
|
+
}
|
|
45
|
+
if (added.size === 0 && deleted.size === 0 && modified.size === 0)
|
|
46
|
+
return;
|
|
47
|
+
unreferencedFiles.clear();
|
|
48
|
+
const cachedUnusedFiles = collector.purge();
|
|
49
|
+
for (const filePath of added)
|
|
50
|
+
cachedUnusedFiles.add(filePath);
|
|
51
|
+
for (const filePath of deleted)
|
|
52
|
+
cachedUnusedFiles.delete(filePath);
|
|
53
|
+
const filePaths = factory.getPrincipals().flatMap(p => p.getUsedResolvedFiles());
|
|
54
|
+
if (added.size > 0 || deleted.size > 0) {
|
|
55
|
+
graph.clear();
|
|
56
|
+
for (const filePath of filePaths) {
|
|
57
|
+
const workspace = chief.findWorkspaceByFilePath(filePath);
|
|
58
|
+
if (workspace) {
|
|
59
|
+
const principal = factory.getPrincipalByPackageName(workspace.pkgName);
|
|
60
|
+
if (principal)
|
|
61
|
+
analyzeSourceFile(filePath, principal);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
for (const [filePath, file] of graph) {
|
|
67
|
+
if (filePaths.includes(filePath)) {
|
|
68
|
+
file.imported = undefined;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
graph.delete(filePath);
|
|
72
|
+
analyzedFiles.delete(filePath);
|
|
73
|
+
const workspace = chief.findWorkspaceByFilePath(filePath);
|
|
74
|
+
if (workspace) {
|
|
75
|
+
const principal = factory.getPrincipalByPackageName(workspace.pkgName);
|
|
76
|
+
if (principal?.projectPaths.has(filePath))
|
|
32
77
|
cachedUnusedFiles.add(filePath);
|
|
33
|
-
debugLog(workspace.name, `Watcher: + ${filename}`);
|
|
34
|
-
break;
|
|
35
|
-
case 'deleted':
|
|
36
|
-
analyzedFiles.delete(filePath);
|
|
37
|
-
principal.removeProjectPath(filePath);
|
|
38
|
-
cachedUnusedFiles.delete(filePath);
|
|
39
|
-
debugLog(workspace.name, `Watcher: - ${filename}`);
|
|
40
|
-
break;
|
|
41
|
-
case 'modified':
|
|
42
|
-
debugLog(workspace.name, `Watcher: ± ${filename}`);
|
|
43
|
-
break;
|
|
44
78
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
for (const filePath of filePaths) {
|
|
82
|
+
if (!graph.has(filePath)) {
|
|
83
|
+
const workspace = chief.findWorkspaceByFilePath(filePath);
|
|
84
|
+
if (workspace) {
|
|
85
|
+
const principal = factory.getPrincipalByPackageName(workspace.pkgName);
|
|
86
|
+
if (principal)
|
|
49
87
|
analyzeSourceFile(filePath, principal);
|
|
50
88
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (principal.projectPaths.has(filePath))
|
|
60
|
-
cachedUnusedFiles.add(filePath);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
for (const filePath of filePaths)
|
|
64
|
-
if (!graph.has(filePath))
|
|
65
|
-
analyzeSourceFile(filePath, principal);
|
|
66
|
-
if (!cachedUnusedFiles.has(filePath))
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
for (const filePath of modified) {
|
|
92
|
+
if (!cachedUnusedFiles.has(filePath)) {
|
|
93
|
+
const workspace = chief.findWorkspaceByFilePath(filePath);
|
|
94
|
+
if (workspace) {
|
|
95
|
+
const principal = factory.getPrincipalByPackageName(workspace.pkgName);
|
|
96
|
+
if (principal)
|
|
67
97
|
analyzeSourceFile(filePath, principal);
|
|
68
|
-
for (const filePath of filePaths) {
|
|
69
|
-
const file = graph.get(filePath);
|
|
70
|
-
if (file?.internalImportCache)
|
|
71
|
-
updateImportMap(file, file.internalImportCache, graph);
|
|
72
|
-
}
|
|
73
98
|
}
|
|
74
|
-
await analyze();
|
|
75
|
-
const unusedFiles = [...cachedUnusedFiles].filter(filePath => !analyzedFiles.has(filePath));
|
|
76
|
-
collector.addFilesIssues(unusedFiles);
|
|
77
|
-
collector.addFileCounts({ processed: analyzedFiles.size, unused: unusedFiles.length });
|
|
78
|
-
await reportIssues(startTime);
|
|
79
99
|
}
|
|
80
100
|
}
|
|
101
|
+
for (const filePath of filePaths) {
|
|
102
|
+
const file = graph.get(filePath);
|
|
103
|
+
if (file?.internalImportCache)
|
|
104
|
+
updateImportMap(file, file.internalImportCache, graph);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
await analyze();
|
|
108
|
+
const unusedFiles = [...cachedUnusedFiles].filter(filePath => !analyzedFiles.has(filePath));
|
|
109
|
+
collector.addFilesIssues(unusedFiles);
|
|
110
|
+
collector.addFileCounts({ processed: analyzedFiles.size, unused: unusedFiles.length });
|
|
111
|
+
for (const issue of collector.getRetainedIssues())
|
|
112
|
+
collector.addIssue(issue);
|
|
113
|
+
onUpdate({ issues: getIssues(), duration: performance.now() - startTime });
|
|
114
|
+
};
|
|
115
|
+
const listener = (eventType, filename) => {
|
|
116
|
+
debugLog('*', `(raw) ${eventType} ${filename}`);
|
|
117
|
+
if (typeof filename === 'string') {
|
|
118
|
+
const event = eventType === 'rename' ? (isFile(join(options.cwd, filename)) ? 'added' : 'deleted') : 'modified';
|
|
119
|
+
processBatch([[event, filename]]);
|
|
81
120
|
}
|
|
82
121
|
};
|
|
83
|
-
|
|
122
|
+
onUpdate({ issues: getIssues() });
|
|
84
123
|
return listener;
|
|
85
124
|
};
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "5.
|
|
1
|
+
export declare const version = "5.66.1";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '5.
|
|
1
|
+
export const version = '5.66.1';
|
package/package.json
CHANGED
package/schema.json
CHANGED
|
@@ -98,11 +98,27 @@
|
|
|
98
98
|
},
|
|
99
99
|
"type": {
|
|
100
100
|
"type": "boolean"
|
|
101
|
+
},
|
|
102
|
+
"variable": {
|
|
103
|
+
"type": "boolean"
|
|
101
104
|
}
|
|
102
105
|
}
|
|
103
106
|
}
|
|
104
107
|
]
|
|
105
108
|
},
|
|
109
|
+
"ignoreIssues": {
|
|
110
|
+
"title": " Ignore specific issue types for specific file patterns",
|
|
111
|
+
"examples": [
|
|
112
|
+
{
|
|
113
|
+
"src/generated/**": ["exports", "types"],
|
|
114
|
+
"**/*.generated.ts": ["exports", "classMembers"]
|
|
115
|
+
}
|
|
116
|
+
],
|
|
117
|
+
"type": "object",
|
|
118
|
+
"additionalProperties": {
|
|
119
|
+
"$ref": "#/definitions/issueTypes"
|
|
120
|
+
}
|
|
121
|
+
},
|
|
106
122
|
"includeEntryExports": {
|
|
107
123
|
"title": "Include entry files when reporting unused exports",
|
|
108
124
|
"type": "boolean"
|
|
@@ -386,6 +402,10 @@
|
|
|
386
402
|
"title": "Cypress plugin configuration (https://knip.dev/reference/plugins/cypress)",
|
|
387
403
|
"$ref": "#/definitions/plugin"
|
|
388
404
|
},
|
|
405
|
+
"danger": {
|
|
406
|
+
"title": "danger plugin configuration (https://knip.dev/reference/plugins/danger)",
|
|
407
|
+
"$ref": "#/definitions/plugin"
|
|
408
|
+
},
|
|
389
409
|
"dependency-cruiser": {
|
|
390
410
|
"title": "dependency-cruiser plugin configuration (https://knip.dev/reference/plugins/dependency-cruiser)",
|
|
391
411
|
"$ref": "#/definitions/plugin"
|