knip 0.8.2 → 0.9.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 +62 -7
- package/dist/cli.js +2 -3
- package/dist/index.js +6 -9
- package/dist/progress.js +4 -7
- package/dist/reporters/codeowners.d.ts +1 -1
- package/dist/reporters/codeowners.js +31 -59
- package/dist/reporters/compact.d.ts +1 -1
- package/dist/reporters/compact.js +27 -63
- package/dist/reporters/constants.d.ts +11 -0
- package/dist/reporters/constants.js +14 -0
- package/dist/reporters/index.d.ts +4 -3
- package/dist/reporters/index.js +2 -0
- package/dist/reporters/json.d.ts +3 -0
- package/dist/reporters/json.js +54 -0
- package/dist/reporters/symbols.d.ts +1 -1
- package/dist/reporters/symbols.js +21 -46
- package/dist/runner.js +3 -3
- package/dist/types.d.ts +15 -18
- package/dist/util/config.d.ts +1 -1
- package/dist/util/config.js +7 -14
- package/dist/util/debug.d.ts +0 -1
- package/dist/util/debug.js +1 -2
- package/dist/util/fs.d.ts +1 -0
- package/dist/util/fs.js +3 -2
- package/dist/util/path.d.ts +2 -2
- package/dist/util/path.js +5 -2
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ with OpenAI_</sup>
|
|
|
36
36
|
|
|
37
37
|
npm install -D knip
|
|
38
38
|
|
|
39
|
-
Knip requires at least Node.js v16.17 or v18. Knip is _cutting edge!_
|
|
39
|
+
Knip supports LTS versions of Node.js, and currently requires at least Node.js v16.17 or v18.3. Knip is _cutting edge!_
|
|
40
40
|
|
|
41
41
|
## Usage
|
|
42
42
|
|
|
@@ -272,15 +272,18 @@ configuration can be tweaked further to the project structure.
|
|
|
272
272
|
|
|
273
273
|
## Reporters
|
|
274
274
|
|
|
275
|
-
|
|
275
|
+
Knip provides the following built-in reporters:
|
|
276
276
|
|
|
277
|
-
- `
|
|
278
|
-
- `
|
|
279
|
-
- `
|
|
277
|
+
- [`json`](#json)
|
|
278
|
+
- [`symbol`](#symbol-default) (default)
|
|
279
|
+
- [`compact`](#compact)
|
|
280
|
+
- [`codeowners`](#code-owners)
|
|
280
281
|
|
|
281
282
|
### Custom Reporters
|
|
282
283
|
|
|
283
|
-
When
|
|
284
|
+
When the provided built-in reporters are not quite sufficient, a custom reporter can be implemented.
|
|
285
|
+
|
|
286
|
+
Pass `--reporter ./my-reporter`, with the default export of that module having this interface:
|
|
284
287
|
|
|
285
288
|
```ts
|
|
286
289
|
type Reporter = (options: ReporterOptions) => void;
|
|
@@ -297,7 +300,59 @@ type ReporterOptions = {
|
|
|
297
300
|
|
|
298
301
|
The data can then be used to write issues to `stdout`, a JSON or CSV file, or sent to a service, anything really!
|
|
299
302
|
|
|
300
|
-
###
|
|
303
|
+
### JSON
|
|
304
|
+
|
|
305
|
+
The `json` reporter output is meant to be consumed by other tools. It reports in JSON format as an array with one object
|
|
306
|
+
per file like this:
|
|
307
|
+
|
|
308
|
+
```json
|
|
309
|
+
[
|
|
310
|
+
{
|
|
311
|
+
"file": "src/Registration.tsx",
|
|
312
|
+
"owners": ["@org/owner"],
|
|
313
|
+
"files": true,
|
|
314
|
+
"unlisted": ["react"],
|
|
315
|
+
"exports": ["lowercaseFirstLetter", "RegistrationBox"],
|
|
316
|
+
"types": ["RegistrationServices", "RegistrationAction"],
|
|
317
|
+
"duplicates": ["Registration", "default"]
|
|
318
|
+
}
|
|
319
|
+
]
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
The keys match the [known issue types](#reading-the-report).
|
|
323
|
+
|
|
324
|
+
#### Usage Ideas
|
|
325
|
+
|
|
326
|
+
Use tools like [miller](https://github.com/johnkerl/miller) or [jtbl](https://github.com/kellyjonbrazil/jtbl) to consume
|
|
327
|
+
the JSON and render a table in the terminal.
|
|
328
|
+
|
|
329
|
+
##### Table
|
|
330
|
+
|
|
331
|
+
```
|
|
332
|
+
$ npx knip --reporter json | mlr --ijson --opprint --no-auto-flatten cat
|
|
333
|
+
file owners files unlisted exports types duplicates
|
|
334
|
+
src/Registration.tsx @org/owner true react lowercaseFirstLetter, RegistrationBox RegistrationServices, RegistrationAction Registration, default
|
|
335
|
+
src/ProductsList.tsx @org/team false - - ProductDetail -
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
##### Markdown Table
|
|
339
|
+
|
|
340
|
+
```
|
|
341
|
+
$ npx knip --reporter json | mlr --ijson --omd --no-auto-flatten cat
|
|
342
|
+
| file | owners | files | duplicates |
|
|
343
|
+
| --- | --- | --- | --- |
|
|
344
|
+
| src/Registration.tsx | @org/owner | true | Registration, default |
|
|
345
|
+
| src/ProductsList.tsx | @org/team | false | |
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
Include specific issue types and/or replace the `cat` command with `put` for clean output:
|
|
349
|
+
|
|
350
|
+
```
|
|
351
|
+
npx knip --include files,duplicates --reporter json | mlr --ijson --opprint --no-auto-flatten put 'for (e in $*) { if(is_array($[e])) { $[e] = joinv($[e], ", ") } }'
|
|
352
|
+
npx knip --reporter json | mlr --ijson --omd --no-auto-flatten put 'for (e in $*) { if(is_array($[e])) { $[e] = joinv($[e], ", ") } }'
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### More Output Examples
|
|
301
356
|
|
|
302
357
|
#### Symbol (default)
|
|
303
358
|
|
package/dist/cli.js
CHANGED
|
@@ -59,10 +59,9 @@ const run = async () => {
|
|
|
59
59
|
level: isDebug ? Number(debugLevel) : 0,
|
|
60
60
|
},
|
|
61
61
|
});
|
|
62
|
-
printReport({ report, issues, cwd, workingDir, isDev, options: reporterOptions });
|
|
62
|
+
await printReport({ report, issues, cwd, workingDir, isDev, options: reporterOptions });
|
|
63
63
|
const totalErrorCount = Object.keys(report)
|
|
64
|
-
.filter(
|
|
65
|
-
.map(reportGroup => reportGroup === 'unlisted' ? 'unresolved' : reportGroup)
|
|
64
|
+
.filter(reportGroup => report[reportGroup])
|
|
66
65
|
.reduce((errorCount, reportGroup) => errorCount + counters[reportGroup], 0);
|
|
67
66
|
if (totalErrorCount > Number(maxIssues))
|
|
68
67
|
process.exit(totalErrorCount);
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.main = void 0;
|
|
7
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
8
7
|
const typescript_1 = __importDefault(require("typescript"));
|
|
9
8
|
const config_1 = require("./util/config");
|
|
10
9
|
const fs_1 = require("./util/fs");
|
|
@@ -17,7 +16,7 @@ const progress_1 = require("./progress");
|
|
|
17
16
|
const main = async (options) => {
|
|
18
17
|
const { cwd, workingDir, configFilePath: configFilePathArg, tsConfigFilePath: tsConfigFilePathArg, include, exclude, ignore, gitignore, isIncludeEntryFiles, isDev, isShowProgress, jsDoc, debug, } = options;
|
|
19
18
|
const updateMessage = (0, progress_1.getMessageUpdater)(options);
|
|
20
|
-
(0, debug_1.debugLogObject)(options, 1, 'Unresolved
|
|
19
|
+
(0, debug_1.debugLogObject)(options, 1, 'Unresolved configuration', options);
|
|
21
20
|
updateMessage('Reading configuration and manifest files...');
|
|
22
21
|
const manifestPath = await (0, fs_1.findFile)(cwd, workingDir, 'package.json');
|
|
23
22
|
const manifest = manifestPath && require(manifestPath);
|
|
@@ -39,12 +38,12 @@ const main = async (options) => {
|
|
|
39
38
|
? Object.keys(config.config.compilerOptions.paths).map(p => p.replace(/\*/g, '**'))
|
|
40
39
|
: [];
|
|
41
40
|
if (config.error) {
|
|
42
|
-
throw new errors_1.ConfigurationError(`Unable to read ${
|
|
41
|
+
throw new errors_1.ConfigurationError(`Unable to read ${(0, path_1.relative)(resolvedTsConfigFilePath)}`);
|
|
43
42
|
}
|
|
44
43
|
}
|
|
45
|
-
const dir =
|
|
44
|
+
const dir = (0, path_1.relative)(workingDir);
|
|
46
45
|
const resolvedConfig = (0, config_1.resolveConfig)(manifest.knip ?? localConfig, { workingDir: dir, isDev });
|
|
47
|
-
(0, debug_1.debugLogObject)(options, 1, 'Resolved
|
|
46
|
+
(0, debug_1.debugLogObject)(options, 1, 'Resolved configuration', resolvedConfig);
|
|
48
47
|
if (!resolvedConfigFilePath && !manifest.knip && !resolvedTsConfigFilePath) {
|
|
49
48
|
throw new errors_1.ConfigurationError(`Unable to find ${configFilePath} or package.json#knip or ${tsConfigFilePath}`);
|
|
50
49
|
}
|
|
@@ -56,7 +55,6 @@ const main = async (options) => {
|
|
|
56
55
|
: { compilerOptions: { allowJs: true } };
|
|
57
56
|
updateMessage('Resolving entry files...');
|
|
58
57
|
const entryPaths = await (0, path_1.resolvePaths)({
|
|
59
|
-
cwd,
|
|
60
58
|
workingDir,
|
|
61
59
|
patterns: resolvedConfig.entryFiles,
|
|
62
60
|
ignore,
|
|
@@ -71,7 +69,6 @@ const main = async (options) => {
|
|
|
71
69
|
(0, debug_1.debugLogSourceFiles)(options, 1, 'Included production source files', productionFiles);
|
|
72
70
|
updateMessage('Resolving project files...');
|
|
73
71
|
const projectPaths = await (0, path_1.resolvePaths)({
|
|
74
|
-
cwd,
|
|
75
72
|
workingDir,
|
|
76
73
|
patterns: resolvedConfig.projectFiles,
|
|
77
74
|
ignore,
|
|
@@ -90,7 +87,7 @@ const main = async (options) => {
|
|
|
90
87
|
return { entryFiles: files, productionFiles: files, projectFiles: files };
|
|
91
88
|
}
|
|
92
89
|
})();
|
|
93
|
-
const report = (0, config_1.
|
|
90
|
+
const report = (0, config_1.resolveIncludedIssueTypes)(include, resolvedConfig ? exclude : ['files'], resolvedConfig);
|
|
94
91
|
const config = {
|
|
95
92
|
workingDir,
|
|
96
93
|
report,
|
|
@@ -102,7 +99,7 @@ const main = async (options) => {
|
|
|
102
99
|
peerDependencies: Object.keys(manifest.peerDependencies ?? {}),
|
|
103
100
|
optionalDependencies: Object.keys(manifest.optionalDependencies ?? {}),
|
|
104
101
|
devDependencies: Object.keys(manifest.devDependencies ?? {}),
|
|
105
|
-
isDev:
|
|
102
|
+
isDev: Boolean(resolvedConfig?.dev),
|
|
106
103
|
tsConfigPaths,
|
|
107
104
|
isShowProgress,
|
|
108
105
|
jsDocOptions: {
|
package/dist/progress.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.getCountersUpdater = exports.getMessageUpdater = void 0;
|
|
7
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
8
4
|
const log_1 = require("./log");
|
|
5
|
+
const path_1 = require("./util/path");
|
|
9
6
|
const lineRewriter = new log_1.LineRewriter();
|
|
10
7
|
const getMessageUpdater = (configuration) => {
|
|
11
8
|
const { isShowProgress } = configuration;
|
|
@@ -15,7 +12,7 @@ const getMessageUpdater = (configuration) => {
|
|
|
15
12
|
};
|
|
16
13
|
exports.getMessageUpdater = getMessageUpdater;
|
|
17
14
|
const getCountersUpdater = (configuration, counters) => {
|
|
18
|
-
const {
|
|
15
|
+
const { isShowProgress, report } = configuration;
|
|
19
16
|
if (!isShowProgress)
|
|
20
17
|
return () => { };
|
|
21
18
|
return (issue) => {
|
|
@@ -25,7 +22,7 @@ const getCountersUpdater = (configuration, counters) => {
|
|
|
25
22
|
const percentage = Math.floor((processed / total) * 100);
|
|
26
23
|
const messages = [(0, log_1.getLine)(`${percentage}%`, `of files processed (${processed} of ${total})`)];
|
|
27
24
|
report.files && messages.push((0, log_1.getLine)(counters.files, 'unused files'));
|
|
28
|
-
report.unlisted && messages.push((0, log_1.getLine)(counters.
|
|
25
|
+
report.unlisted && messages.push((0, log_1.getLine)(counters.unlisted, 'unlisted dependencies'));
|
|
29
26
|
report.exports && messages.push((0, log_1.getLine)(counters.exports, 'unused exports'));
|
|
30
27
|
report.nsExports && messages.push((0, log_1.getLine)(counters.nsExports, 'unused exports in namespace'));
|
|
31
28
|
report.types && messages.push((0, log_1.getLine)(counters.types, 'unused types'));
|
|
@@ -33,7 +30,7 @@ const getCountersUpdater = (configuration, counters) => {
|
|
|
33
30
|
report.duplicates && messages.push((0, log_1.getLine)(counters.duplicates, 'duplicate exports'));
|
|
34
31
|
if (processed < total) {
|
|
35
32
|
messages.push('');
|
|
36
|
-
messages.push(`Processing: ${
|
|
33
|
+
messages.push(`Processing: ${(0, path_1.relative)(issue.filePath)}`);
|
|
37
34
|
}
|
|
38
35
|
lineRewriter.update(messages);
|
|
39
36
|
};
|
|
@@ -5,31 +5,33 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const node_path_1 = __importDefault(require("node:path"));
|
|
7
7
|
const ownership_1 = require("@snyk/github-codeowners/dist/lib/ownership");
|
|
8
|
-
const
|
|
9
|
-
|
|
8
|
+
const path_1 = require("../util/path");
|
|
9
|
+
const constants_1 = require("./constants");
|
|
10
|
+
const logIssueLine = (owner, filePath, symbols) => {
|
|
11
|
+
console.log(`${owner} ${(0, path_1.relative)(filePath)}${symbols ? `: ${symbols.join(', ')}` : ''}`);
|
|
10
12
|
};
|
|
11
|
-
const
|
|
13
|
+
const logIssueSet = (issues, title) => {
|
|
12
14
|
title && console.log(`--- ${title} (${issues.length})`);
|
|
13
15
|
if (issues.length) {
|
|
14
16
|
issues
|
|
15
17
|
.sort((a, b) => (a.owner < b.owner ? -1 : 1))
|
|
16
|
-
.forEach(issue => console.log(issue.owner, issue.symbol.startsWith('/') ?
|
|
18
|
+
.forEach(issue => console.log(issue.owner, issue.symbol.startsWith('/') ? (0, path_1.relative)(issue.symbol) : issue.symbol));
|
|
17
19
|
}
|
|
18
20
|
else {
|
|
19
21
|
console.log('Not found');
|
|
20
22
|
}
|
|
21
23
|
};
|
|
22
|
-
const
|
|
24
|
+
const logIssueRecord = (issues, title) => {
|
|
23
25
|
title && console.log(`--- ${title} (${issues.length})`);
|
|
24
26
|
if (issues.length) {
|
|
25
27
|
const sortedByFilePath = issues.sort((a, b) => (a.owner < b.owner ? -1 : 1));
|
|
26
|
-
sortedByFilePath.forEach(({ filePath, symbols, owner }) => logIssueLine(owner,
|
|
28
|
+
sortedByFilePath.forEach(({ filePath, symbols, owner }) => logIssueLine(owner, filePath, symbols));
|
|
27
29
|
}
|
|
28
30
|
else {
|
|
29
31
|
console.log('Not found');
|
|
30
32
|
}
|
|
31
33
|
};
|
|
32
|
-
exports.default = ({ report, issues,
|
|
34
|
+
exports.default = ({ report, issues, options }) => {
|
|
33
35
|
let opts = {};
|
|
34
36
|
try {
|
|
35
37
|
opts = options ? JSON.parse(options) : opts;
|
|
@@ -42,57 +44,27 @@ exports.default = ({ report, issues, cwd, isDev, options }) => {
|
|
|
42
44
|
const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
|
|
43
45
|
const [dependenciesOwner = '[no-owner]'] = codeownersEngine.calcFileOwnership('package.json');
|
|
44
46
|
const fallbackOwner = dependenciesOwner;
|
|
45
|
-
const calcFileOwnership = (filePath) => codeownersEngine.calcFileOwnership(
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
owner: dependenciesOwner,
|
|
68
|
-
}));
|
|
69
|
-
logIssueGroupResult(unreferencedDevDependencies, cwd, 'UNUSED DEV DEPENDENCIES');
|
|
70
|
-
}
|
|
71
|
-
if (report.unlisted) {
|
|
72
|
-
const unreferencedDependencies = Object.values(issues.unresolved).map(toIssueWithOwner);
|
|
73
|
-
logIssueGroupResults(unreferencedDependencies, cwd, reportMultipleGroups && 'UNLISTED DEPENDENCIES');
|
|
74
|
-
}
|
|
75
|
-
if (report.exports) {
|
|
76
|
-
const unreferencedExports = Object.values(issues.exports).map(toIssueWithOwner);
|
|
77
|
-
logIssueGroupResults(unreferencedExports, cwd, reportMultipleGroups && 'UNUSED EXPORTS');
|
|
78
|
-
}
|
|
79
|
-
if (report.nsExports) {
|
|
80
|
-
const unreferencedNsExports = Object.values(issues.nsExports).map(toIssueWithOwner);
|
|
81
|
-
logIssueGroupResults(unreferencedNsExports, cwd, reportMultipleGroups && 'UNUSED EXPORTS IN NAMESPACE');
|
|
82
|
-
}
|
|
83
|
-
if (report.types) {
|
|
84
|
-
const unreferencedTypes = Object.values(issues.types).map(toIssueWithOwner);
|
|
85
|
-
logIssueGroupResults(unreferencedTypes, cwd, reportMultipleGroups && 'UNUSED TYPES');
|
|
86
|
-
}
|
|
87
|
-
if (report.nsTypes) {
|
|
88
|
-
const unreferencedNsTypes = Object.values(issues.nsTypes).map(toIssueWithOwner);
|
|
89
|
-
logIssueGroupResults(unreferencedNsTypes, cwd, reportMultipleGroups && 'UNUSED TYPES IN NAMESPACE');
|
|
90
|
-
}
|
|
91
|
-
if (report.duplicates) {
|
|
92
|
-
const unreferencedDuplicates = Object.values(issues.duplicates)
|
|
93
|
-
.map(issues => Object.values(issues))
|
|
94
|
-
.flat()
|
|
95
|
-
.map(issue => ({ ...issue, owner: calcFileOwnership(issue.filePath) }));
|
|
96
|
-
logIssueGroupResults(unreferencedDuplicates, cwd, reportMultipleGroups && 'DUPLICATE EXPORTS');
|
|
47
|
+
const calcFileOwnership = (filePath) => codeownersEngine.calcFileOwnership((0, path_1.relative)(filePath))[0] ?? fallbackOwner;
|
|
48
|
+
const addOwner = (issue) => ({ ...issue, owner: calcFileOwnership(issue.filePath) });
|
|
49
|
+
for (const [reportType, isReportType] of Object.entries(report)) {
|
|
50
|
+
if (isReportType) {
|
|
51
|
+
const title = reportMultipleGroups && constants_1.ISSUE_TYPE_TITLE[reportType];
|
|
52
|
+
if (issues[reportType] instanceof Set) {
|
|
53
|
+
const toIssue = (filePath) => ({ filePath, symbol: filePath });
|
|
54
|
+
const issuesForType = Array.from(issues[reportType]).map(toIssue);
|
|
55
|
+
logIssueSet(issuesForType.map(addOwner), title);
|
|
56
|
+
}
|
|
57
|
+
else if (reportType === 'duplicates') {
|
|
58
|
+
const issuesForType = Object.values(issues[reportType]).map(Object.values).flat().map(addOwner);
|
|
59
|
+
logIssueRecord(issuesForType, title);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const issuesForType = Object.values(issues[reportType]).map(issues => {
|
|
63
|
+
const items = Object.values(issues);
|
|
64
|
+
return addOwner({ ...items[0], symbols: items.map(issue => issue.symbol) });
|
|
65
|
+
});
|
|
66
|
+
logIssueRecord(issuesForType, title);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
97
69
|
}
|
|
98
70
|
};
|
|
@@ -1,84 +1,48 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
3
|
+
const path_1 = require("../util/path");
|
|
4
|
+
const constants_1 = require("./constants");
|
|
5
|
+
const logIssueLine = (filePath, symbols) => {
|
|
6
|
+
console.log(`${(0, path_1.relative)(filePath)}${symbols ? `: ${symbols.join(', ')}` : ''}`);
|
|
9
7
|
};
|
|
10
|
-
const
|
|
8
|
+
const logIssueSet = (issues, title) => {
|
|
11
9
|
title && console.log(`--- ${title} (${issues.length})`);
|
|
12
10
|
if (issues.length) {
|
|
13
|
-
issues.sort().forEach(value => console.log(value.startsWith('/') ?
|
|
11
|
+
issues.sort().forEach(value => console.log(value.startsWith('/') ? (0, path_1.relative)(value) : value));
|
|
14
12
|
}
|
|
15
13
|
else {
|
|
16
14
|
console.log('Not found');
|
|
17
15
|
}
|
|
18
16
|
};
|
|
19
|
-
const
|
|
17
|
+
const logIssueRecord = (issues, title) => {
|
|
20
18
|
title && console.log(`--- ${title} (${issues.length})`);
|
|
21
19
|
if (issues.length) {
|
|
22
20
|
const sortedByFilePath = issues.sort((a, b) => (a.filePath > b.filePath ? 1 : -1));
|
|
23
|
-
sortedByFilePath.forEach(({ filePath, symbols }) => logIssueLine(
|
|
21
|
+
sortedByFilePath.forEach(({ filePath, symbols }) => logIssueLine(filePath, symbols));
|
|
24
22
|
}
|
|
25
23
|
else {
|
|
26
24
|
console.log('Not found');
|
|
27
25
|
}
|
|
28
26
|
};
|
|
29
|
-
exports.default = ({ report, issues
|
|
27
|
+
exports.default = ({ report, issues }) => {
|
|
30
28
|
const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
if (report.exports) {
|
|
51
|
-
const unreferencedExports = Object.values(issues.exports).map(issues => {
|
|
52
|
-
const items = Object.values(issues);
|
|
53
|
-
return { ...items[0], symbols: items.map(i => i.symbol) };
|
|
54
|
-
});
|
|
55
|
-
logIssueGroupResults(unreferencedExports, workingDir, reportMultipleGroups && 'UNUSED EXPORTS');
|
|
56
|
-
}
|
|
57
|
-
if (report.nsExports) {
|
|
58
|
-
const unreferencedNsExports = Object.values(issues.nsExports).map(issues => {
|
|
59
|
-
const items = Object.values(issues);
|
|
60
|
-
return { ...items[0], symbols: items.map(i => i.symbol) };
|
|
61
|
-
});
|
|
62
|
-
logIssueGroupResults(unreferencedNsExports, workingDir, reportMultipleGroups && 'UNUSED EXPORTS IN NAMESPACE');
|
|
63
|
-
}
|
|
64
|
-
if (report.types) {
|
|
65
|
-
const unreferencedTypes = Object.values(issues.types).map(issues => {
|
|
66
|
-
const items = Object.values(issues);
|
|
67
|
-
return { ...items[0], symbols: items.map(i => i.symbol) };
|
|
68
|
-
});
|
|
69
|
-
logIssueGroupResults(unreferencedTypes, workingDir, reportMultipleGroups && 'UNUSED TYPES');
|
|
70
|
-
}
|
|
71
|
-
if (report.nsTypes) {
|
|
72
|
-
const unreferencedNsTypes = Object.values(issues.nsTypes).map(issues => {
|
|
73
|
-
const items = Object.values(issues);
|
|
74
|
-
return { ...items[0], symbols: items.map(i => i.symbol) };
|
|
75
|
-
});
|
|
76
|
-
logIssueGroupResults(unreferencedNsTypes, workingDir, reportMultipleGroups && 'UNUSED TYPES IN NAMESPACE');
|
|
77
|
-
}
|
|
78
|
-
if (report.duplicates) {
|
|
79
|
-
const unreferencedDuplicates = Object.values(issues.duplicates)
|
|
80
|
-
.map(issues => Object.values(issues))
|
|
81
|
-
.flat();
|
|
82
|
-
logIssueGroupResults(unreferencedDuplicates, workingDir, reportMultipleGroups && 'DUPLICATE EXPORTS');
|
|
29
|
+
for (const [reportType, isReportType] of Object.entries(report)) {
|
|
30
|
+
if (isReportType) {
|
|
31
|
+
const title = reportMultipleGroups && constants_1.ISSUE_TYPE_TITLE[reportType];
|
|
32
|
+
if (issues[reportType] instanceof Set) {
|
|
33
|
+
logIssueSet(Array.from(issues[reportType]), title);
|
|
34
|
+
}
|
|
35
|
+
else if (reportType === 'duplicates') {
|
|
36
|
+
const issuesForType = Object.values(issues[reportType]).map(Object.values).flat();
|
|
37
|
+
logIssueRecord(issuesForType, title);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
const issuesForType = Object.values(issues[reportType]).map(issues => {
|
|
41
|
+
const items = Object.values(issues);
|
|
42
|
+
return { ...items[0], symbols: items.map(issue => issue.symbol) };
|
|
43
|
+
});
|
|
44
|
+
logIssueRecord(issuesForType, title);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
83
47
|
}
|
|
84
48
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ISSUE_TYPE_TITLE = void 0;
|
|
4
|
+
exports.ISSUE_TYPE_TITLE = {
|
|
5
|
+
files: 'UNUSED FILES',
|
|
6
|
+
dependencies: 'UNUSED DEPENDENCIES',
|
|
7
|
+
devDependencies: 'UNUSED DEV DEPENDENCIES',
|
|
8
|
+
unlisted: 'UNLISTED DEPENDENCIES',
|
|
9
|
+
exports: 'UNUSED EXPORTS',
|
|
10
|
+
nsExports: 'UNUSED EXPORTS IN NAMESPACE',
|
|
11
|
+
types: 'UNUSED TYPES',
|
|
12
|
+
nsTypes: 'UNUSED TYPES IN NAMESPACE',
|
|
13
|
+
duplicates: 'DUPLICATE EXPORTS',
|
|
14
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
declare const _default: {
|
|
2
|
-
symbols: ({ report, issues
|
|
3
|
-
compact: ({ report, issues
|
|
4
|
-
codeowners: ({ report, issues,
|
|
2
|
+
symbols: ({ report, issues }: import("../types").ReporterOptions) => void;
|
|
3
|
+
compact: ({ report, issues }: import("../types").ReporterOptions) => void;
|
|
4
|
+
codeowners: ({ report, issues, options }: import("../types").ReporterOptions) => void;
|
|
5
|
+
json: ({ report, issues, options }: import("../types").ReporterOptions) => Promise<void>;
|
|
5
6
|
};
|
|
6
7
|
export default _default;
|
package/dist/reporters/index.js
CHANGED
|
@@ -6,8 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const symbols_1 = __importDefault(require("./symbols"));
|
|
7
7
|
const compact_1 = __importDefault(require("./compact"));
|
|
8
8
|
const codeowners_1 = __importDefault(require("./codeowners"));
|
|
9
|
+
const json_1 = __importDefault(require("./json"));
|
|
9
10
|
exports.default = {
|
|
10
11
|
symbols: symbols_1.default,
|
|
11
12
|
compact: compact_1.default,
|
|
12
13
|
codeowners: codeowners_1.default,
|
|
14
|
+
json: json_1.default,
|
|
13
15
|
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
7
|
+
const fs_1 = require("../util/fs");
|
|
8
|
+
const path_1 = require("../util/path");
|
|
9
|
+
const ownership_1 = require("@snyk/github-codeowners/dist/lib/ownership");
|
|
10
|
+
const mergeTypes = (type) => type === 'exports' || type === 'nsExports' ? 'exports' : type === 'types' || type === 'nsTypes' ? 'types' : type;
|
|
11
|
+
exports.default = async ({ report, issues, options }) => {
|
|
12
|
+
let opts = {};
|
|
13
|
+
try {
|
|
14
|
+
opts = options ? JSON.parse(options) : opts;
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
console.error(error);
|
|
18
|
+
}
|
|
19
|
+
const json = {};
|
|
20
|
+
const codeownersFilePath = node_path_1.default.resolve(opts.codeowners ?? '.github/CODEOWNERS');
|
|
21
|
+
const codeownersEngine = (await (0, fs_1.isFile)(codeownersFilePath)) && ownership_1.OwnershipEngine.FromCodeownersFile(codeownersFilePath);
|
|
22
|
+
const flatten = (issues) => Object.values(issues).map(Object.values).flat();
|
|
23
|
+
const initRow = (filePath) => {
|
|
24
|
+
const file = (0, path_1.relative)(filePath);
|
|
25
|
+
const row = {
|
|
26
|
+
file,
|
|
27
|
+
...(codeownersEngine && { owners: codeownersEngine.calcFileOwnership(file) }),
|
|
28
|
+
...(report.files && { files: false }),
|
|
29
|
+
...(report.unlisted && { unlisted: [] }),
|
|
30
|
+
...((report.exports || report.nsExports) && { exports: [] }),
|
|
31
|
+
...((report.types || report.nsTypes) && { types: [] }),
|
|
32
|
+
...(report.duplicates && { duplicates: [] }),
|
|
33
|
+
};
|
|
34
|
+
return row;
|
|
35
|
+
};
|
|
36
|
+
for (const [reportType, isReportType] of Object.entries(report)) {
|
|
37
|
+
if (isReportType) {
|
|
38
|
+
if (reportType === 'files') {
|
|
39
|
+
Array.from(issues[reportType]).forEach(filePath => {
|
|
40
|
+
json[filePath] = json[filePath] ?? initRow(filePath);
|
|
41
|
+
json[filePath][reportType] = true;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const type = mergeTypes(reportType);
|
|
46
|
+
flatten(issues[reportType]).forEach(({ filePath, symbol }) => {
|
|
47
|
+
json[filePath] = json[filePath] ?? initRow(filePath);
|
|
48
|
+
json[filePath][type]?.push(symbol);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
console.log(JSON.stringify(Object.values(json)));
|
|
54
|
+
};
|
|
@@ -1,72 +1,47 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const
|
|
3
|
+
const path_1 = require("../util/path");
|
|
4
|
+
const constants_1 = require("./constants");
|
|
7
5
|
const TRUNCATE_WIDTH = 40;
|
|
8
|
-
const logIssueLine = (issue,
|
|
6
|
+
const logIssueLine = (issue, maxWidth) => {
|
|
9
7
|
const symbols = issue.symbols ? issue.symbols.join(', ') : issue.symbol;
|
|
10
8
|
const truncatedSymbol = symbols.length > maxWidth ? symbols.slice(0, maxWidth - 3) + '...' : symbols;
|
|
11
|
-
const filePath =
|
|
9
|
+
const filePath = (0, path_1.relative)(issue.filePath);
|
|
12
10
|
console.log(`${truncatedSymbol.padEnd(maxWidth + 2)}${issue.symbolType?.padEnd(11) || ''}${filePath}`);
|
|
13
11
|
};
|
|
14
|
-
const
|
|
12
|
+
const logIssueSet = (issues, title) => {
|
|
15
13
|
title && console.log(`--- ${title} (${issues.length})`);
|
|
16
14
|
if (issues.length) {
|
|
17
|
-
issues.sort().forEach(value => console.log(value.startsWith('/') ?
|
|
15
|
+
issues.sort().forEach(value => console.log(value.startsWith('/') ? (0, path_1.relative)(value) : value));
|
|
18
16
|
}
|
|
19
17
|
else {
|
|
20
18
|
console.log('Not found');
|
|
21
19
|
}
|
|
22
20
|
};
|
|
23
|
-
const
|
|
21
|
+
const logIssueRecord = (issues, title, isTruncate = false) => {
|
|
24
22
|
title && console.log(`--- ${title} (${issues.length})`);
|
|
25
23
|
if (issues.length) {
|
|
26
24
|
const sortedByFilePath = issues.sort((a, b) => (a.filePath > b.filePath ? 1 : -1));
|
|
27
25
|
const maxWidth = isTruncate ? TRUNCATE_WIDTH : issues.reduce((max, issue) => Math.max(issue.symbol.length, max), 0);
|
|
28
|
-
sortedByFilePath.forEach(issue => logIssueLine(issue,
|
|
26
|
+
sortedByFilePath.forEach(issue => logIssueLine(issue, maxWidth));
|
|
29
27
|
}
|
|
30
28
|
else {
|
|
31
29
|
console.log('Not found');
|
|
32
30
|
}
|
|
33
31
|
};
|
|
34
|
-
exports.default = ({ report, issues
|
|
32
|
+
exports.default = ({ report, issues }) => {
|
|
35
33
|
const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (report.unlisted) {
|
|
49
|
-
const unresolvedDependencies = Object.values(issues.unresolved).map(Object.values).flat();
|
|
50
|
-
logIssueGroupResults(unresolvedDependencies, workingDir, reportMultipleGroups && 'UNLISTED DEPENDENCIES');
|
|
51
|
-
}
|
|
52
|
-
if (report.exports) {
|
|
53
|
-
const unreferencedExports = Object.values(issues.exports).map(Object.values).flat();
|
|
54
|
-
logIssueGroupResults(unreferencedExports, workingDir, reportMultipleGroups && 'UNUSED EXPORTS');
|
|
55
|
-
}
|
|
56
|
-
if (report.nsExports) {
|
|
57
|
-
const unreferencedNsExports = Object.values(issues.nsExports).map(Object.values).flat();
|
|
58
|
-
logIssueGroupResults(unreferencedNsExports, workingDir, reportMultipleGroups && 'UNUSED EXPORTS IN NAMESPACE');
|
|
59
|
-
}
|
|
60
|
-
if (report.types) {
|
|
61
|
-
const unreferencedTypes = Object.values(issues.types).map(Object.values).flat();
|
|
62
|
-
logIssueGroupResults(unreferencedTypes, workingDir, reportMultipleGroups && 'UNUSED TYPES');
|
|
63
|
-
}
|
|
64
|
-
if (report.nsTypes) {
|
|
65
|
-
const unreferencedNsTypes = Object.values(issues.nsTypes).map(Object.values).flat();
|
|
66
|
-
logIssueGroupResults(unreferencedNsTypes, workingDir, reportMultipleGroups && 'UNUSED TYPES IN NAMESPACE');
|
|
67
|
-
}
|
|
68
|
-
if (report.duplicates) {
|
|
69
|
-
const unreferencedDuplicates = Object.values(issues.duplicates).map(Object.values).flat();
|
|
70
|
-
logIssueGroupResults(unreferencedDuplicates, workingDir, reportMultipleGroups && 'DUPLICATE EXPORTS', true);
|
|
34
|
+
for (const [reportType, isReportType] of Object.entries(report)) {
|
|
35
|
+
if (isReportType) {
|
|
36
|
+
const title = reportMultipleGroups && constants_1.ISSUE_TYPE_TITLE[reportType];
|
|
37
|
+
if (issues[reportType] instanceof Set) {
|
|
38
|
+
logIssueSet(Array.from(issues[reportType]), title);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const issuesForType = Object.values(issues[reportType]).map(Object.values).flat();
|
|
42
|
+
const isTruncate = Boolean(issuesForType[0]?.symbols?.length);
|
|
43
|
+
logIssueRecord(issuesForType, title, isTruncate);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
71
46
|
}
|
|
72
47
|
};
|
package/dist/runner.js
CHANGED
|
@@ -27,7 +27,7 @@ async function findIssues(configuration) {
|
|
|
27
27
|
files: new Set(unreferencedProductionFiles.map(file => file.getFilePath())),
|
|
28
28
|
dependencies: new Set(),
|
|
29
29
|
devDependencies: new Set(),
|
|
30
|
-
|
|
30
|
+
unlisted: {},
|
|
31
31
|
exports: {},
|
|
32
32
|
types: {},
|
|
33
33
|
nsExports: {},
|
|
@@ -38,7 +38,7 @@ async function findIssues(configuration) {
|
|
|
38
38
|
files: issues.files.size,
|
|
39
39
|
dependencies: issues.dependencies.size,
|
|
40
40
|
devDependencies: issues.dependencies.size,
|
|
41
|
-
|
|
41
|
+
unlisted: 0,
|
|
42
42
|
exports: 0,
|
|
43
43
|
types: 0,
|
|
44
44
|
nsExports: 0,
|
|
@@ -76,7 +76,7 @@ async function findIssues(configuration) {
|
|
|
76
76
|
const filePath = sourceFile.getFilePath();
|
|
77
77
|
if (report.dependencies || report.unlisted) {
|
|
78
78
|
const unresolvedDependencies = getUnresolvedDependencies(sourceFile);
|
|
79
|
-
unresolvedDependencies.forEach(issue => addSymbolIssue('
|
|
79
|
+
unresolvedDependencies.forEach(issue => addSymbolIssue('unlisted', issue));
|
|
80
80
|
}
|
|
81
81
|
const exportDeclarations = sourceFile.getExportedDeclarations();
|
|
82
82
|
if (report.duplicates) {
|
package/dist/types.d.ts
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
import { SourceFile } from 'ts-morph';
|
|
2
2
|
declare type SymbolType = 'type' | 'interface' | 'enum';
|
|
3
|
-
declare type UnusedFileIssues = Set<string>;
|
|
4
|
-
declare type UnusedExportIssues = Record<string, Record<string, Issue>>;
|
|
5
|
-
declare type UnresolvedDependencyIssues = Record<string, Record<string, Issue>>;
|
|
6
|
-
declare type UnusedDependencyIssues = Set<string>;
|
|
7
3
|
export declare type Issue = {
|
|
8
4
|
filePath: string;
|
|
9
5
|
symbol: string;
|
|
10
6
|
symbols?: string[];
|
|
11
7
|
symbolType?: SymbolType;
|
|
12
8
|
};
|
|
9
|
+
export declare type IssueSet = Set<string>;
|
|
10
|
+
export declare type IssueRecords = Record<string, Record<string, Issue>>;
|
|
13
11
|
export declare type Issues = {
|
|
14
|
-
files:
|
|
15
|
-
dependencies:
|
|
16
|
-
devDependencies:
|
|
17
|
-
|
|
18
|
-
exports:
|
|
19
|
-
types:
|
|
20
|
-
nsExports:
|
|
21
|
-
nsTypes:
|
|
22
|
-
duplicates:
|
|
12
|
+
files: IssueSet;
|
|
13
|
+
dependencies: IssueSet;
|
|
14
|
+
devDependencies: IssueSet;
|
|
15
|
+
unlisted: IssueRecords;
|
|
16
|
+
exports: IssueRecords;
|
|
17
|
+
types: IssueRecords;
|
|
18
|
+
nsExports: IssueRecords;
|
|
19
|
+
nsTypes: IssueRecords;
|
|
20
|
+
duplicates: IssueRecords;
|
|
23
21
|
};
|
|
24
|
-
declare type IssueType = keyof Issues;
|
|
22
|
+
export declare type IssueType = keyof Issues;
|
|
25
23
|
export declare type ProjectIssueType = Extract<IssueType, 'files' | 'dependencies' | 'devDependencies'>;
|
|
26
24
|
export declare type SymbolIssueType = Exclude<IssueType, ProjectIssueType>;
|
|
27
|
-
export declare type
|
|
25
|
+
export declare type Report = {
|
|
26
|
+
[key in keyof Issues]: boolean;
|
|
27
|
+
};
|
|
28
28
|
declare type BaseLocalConfiguration = {
|
|
29
29
|
entryFiles: string[];
|
|
30
30
|
projectFiles: string[];
|
|
@@ -53,9 +53,6 @@ export declare type UnresolvedConfiguration = {
|
|
|
53
53
|
level: number;
|
|
54
54
|
};
|
|
55
55
|
};
|
|
56
|
-
export declare type Report = {
|
|
57
|
-
[key in IssueGroup]: boolean;
|
|
58
|
-
};
|
|
59
56
|
export declare type Configuration = {
|
|
60
57
|
workingDir: string;
|
|
61
58
|
report: Report;
|
package/dist/util/config.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ export declare const resolveConfig: (importedConfiguration: ImportedConfiguratio
|
|
|
3
3
|
workingDir?: string;
|
|
4
4
|
isDev?: boolean;
|
|
5
5
|
}) => LocalConfiguration | undefined;
|
|
6
|
-
export declare const
|
|
6
|
+
export declare const resolveIncludedIssueTypes: (includeArg: string[], excludeArg: string[], resolvedConfig?: LocalConfiguration) => import("../types").Report;
|
package/dist/util/config.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.resolveIncludedIssueTypes = exports.resolveConfig = void 0;
|
|
7
7
|
const micromatch_1 = __importDefault(require("micromatch"));
|
|
8
8
|
const resolveConfig = (importedConfiguration, options) => {
|
|
9
9
|
if (!importedConfiguration)
|
|
@@ -24,20 +24,13 @@ const resolveConfig = (importedConfiguration, options) => {
|
|
|
24
24
|
console.info(`Add these properties at root level, or use --dir and match one of: ${configKeys.join(', ')}\n`);
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
|
+
resolvedConfig.dev = Boolean(typeof resolvedConfig.dev === 'boolean' ? resolvedConfig.dev : isDev);
|
|
27
28
|
return resolvedConfig;
|
|
28
29
|
};
|
|
29
30
|
exports.resolveConfig = resolveConfig;
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
'dependencies',
|
|
34
|
-
'unlisted',
|
|
35
|
-
'exports',
|
|
36
|
-
'types',
|
|
37
|
-
'nsExports',
|
|
38
|
-
'nsTypes',
|
|
39
|
-
'duplicates',
|
|
40
|
-
];
|
|
31
|
+
const resolveIncludedIssueTypes = (includeArg, excludeArg, resolvedConfig) => {
|
|
32
|
+
const deps = resolvedConfig?.dev ? ['dependencies', 'devDependencies'] : ['dependencies'];
|
|
33
|
+
const groups = ['files', ...deps, 'unlisted', 'exports', 'types', 'nsExports', 'nsTypes', 'duplicates'];
|
|
41
34
|
const include = [includeArg, resolvedConfig?.include ?? []]
|
|
42
35
|
.flat()
|
|
43
36
|
.map(value => value.split(','))
|
|
@@ -46,7 +39,7 @@ const resolveIncludedIssueGroups = (includeArg, excludeArg, resolvedConfig) => {
|
|
|
46
39
|
.flat()
|
|
47
40
|
.map(value => value.split(','))
|
|
48
41
|
.flat();
|
|
49
|
-
const includes = (include.length > 0 ? include : groups).filter(
|
|
42
|
+
const includes = (include.length > 0 ? include : groups).filter(group => !exclude.includes(group));
|
|
50
43
|
return groups.reduce((r, group) => ((r[group] = includes.includes(group)), r), {});
|
|
51
44
|
};
|
|
52
|
-
exports.
|
|
45
|
+
exports.resolveIncludedIssueTypes = resolveIncludedIssueTypes;
|
package/dist/util/debug.d.ts
CHANGED
|
@@ -8,5 +8,4 @@ declare type Config = {
|
|
|
8
8
|
export declare const debugLogObject: (config: Config, minimumLevel: number, name: string, obj: unknown) => void;
|
|
9
9
|
export declare const debugLogFiles: (config: Config, minimumLevel: number, name: string, filePaths: string[]) => void;
|
|
10
10
|
export declare const debugLogSourceFiles: (config: Config, minimumLevel: number, name: string, sourceFiles: SourceFile[]) => void;
|
|
11
|
-
export declare const debugLogDiff: (config: Config, minimumLevel: number, name: string, arrA: string[], arrB: string[]) => void;
|
|
12
11
|
export {};
|
package/dist/util/debug.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.debugLogSourceFiles = exports.debugLogFiles = exports.debugLogObject = void 0;
|
|
7
7
|
const node_util_1 = __importDefault(require("node:util"));
|
|
8
8
|
const logArray = (collection) => console.log(node_util_1.default.inspect(collection, { maxArrayLength: null }));
|
|
9
9
|
const debugLogObject = (config, minimumLevel, name, obj) => {
|
|
@@ -51,4 +51,3 @@ const debugLogDiff = (config, minimumLevel, name, arrA, arrB) => {
|
|
|
51
51
|
console.log(`[knip] Only in right:`);
|
|
52
52
|
logArray(onlyInB);
|
|
53
53
|
};
|
|
54
|
-
exports.debugLogDiff = debugLogDiff;
|
package/dist/util/fs.d.ts
CHANGED
package/dist/util/fs.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.findFile = void 0;
|
|
6
|
+
exports.findFile = exports.isFile = void 0;
|
|
7
7
|
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
8
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
9
|
const isFile = async (filePath) => {
|
|
@@ -15,9 +15,10 @@ const isFile = async (filePath) => {
|
|
|
15
15
|
return false;
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
|
+
exports.isFile = isFile;
|
|
18
19
|
const findFile = async (cwd, workingDir, fileName) => {
|
|
19
20
|
const filePath = node_path_1.default.join(workingDir, fileName);
|
|
20
|
-
if (await isFile(filePath)) {
|
|
21
|
+
if (await (0, exports.isFile)(filePath)) {
|
|
21
22
|
return filePath;
|
|
22
23
|
}
|
|
23
24
|
else {
|
package/dist/util/path.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export declare const
|
|
2
|
-
|
|
1
|
+
export declare const relative: (to: string) => string;
|
|
2
|
+
export declare const resolvePaths: ({ workingDir, patterns, ignore, gitignore, }: {
|
|
3
3
|
workingDir: string;
|
|
4
4
|
patterns: string[];
|
|
5
5
|
ignore: string[];
|
package/dist/util/path.js
CHANGED
|
@@ -3,8 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.resolvePaths = void 0;
|
|
6
|
+
exports.resolvePaths = exports.relative = void 0;
|
|
7
7
|
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const cwd = process.cwd();
|
|
9
|
+
const relative = (to) => node_path_1.default.relative(cwd, to);
|
|
10
|
+
exports.relative = relative;
|
|
8
11
|
let _globby;
|
|
9
12
|
const glob = async function (patterns, options) {
|
|
10
13
|
if (!_globby) {
|
|
@@ -18,7 +21,7 @@ const prependDirToPattern = (workingDir, pattern) => {
|
|
|
18
21
|
return '!' + node_path_1.default.join(workingDir, pattern.slice(1));
|
|
19
22
|
return node_path_1.default.join(workingDir, pattern);
|
|
20
23
|
};
|
|
21
|
-
const resolvePaths = async ({
|
|
24
|
+
const resolvePaths = async ({ workingDir, patterns, ignore, gitignore, }) => glob(patterns.map(pattern => prependDirToPattern((0, exports.relative)(workingDir), pattern)), {
|
|
22
25
|
cwd,
|
|
23
26
|
ignore,
|
|
24
27
|
gitignore,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knip",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Find unused files, dependencies and exports in your TypeScript and JavaScript project",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"find",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"knip": "dist/cli.js"
|
|
25
25
|
},
|
|
26
26
|
"scripts": {
|
|
27
|
-
"knip": "node ./dist/cli.js --
|
|
27
|
+
"knip": "node ./dist/cli.js --jsdoc public",
|
|
28
28
|
"test": "node --loader tsx --test test/*.spec.ts",
|
|
29
29
|
"watch": "tsc --watch",
|
|
30
30
|
"build": "rm -rf dist && tsc",
|
|
@@ -49,10 +49,11 @@
|
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/micromatch": "4.0.2",
|
|
52
|
-
"@types/node": "18.
|
|
52
|
+
"@types/node": "18.11.2",
|
|
53
53
|
"prettier": "2.7.1",
|
|
54
54
|
"release-it": "15.5.0",
|
|
55
|
-
"tsx": "3.10.
|
|
55
|
+
"tsx": "3.10.3",
|
|
56
|
+
"type-fest": "3.1.0",
|
|
56
57
|
"typescript": "4.8.4"
|
|
57
58
|
},
|
|
58
59
|
"release-it": {
|
|
@@ -61,7 +62,7 @@
|
|
|
61
62
|
}
|
|
62
63
|
},
|
|
63
64
|
"engines": {
|
|
64
|
-
"node": ">=16.17.0"
|
|
65
|
+
"node": ">=16.17.0 <17 || >=18.3.0"
|
|
65
66
|
},
|
|
66
67
|
"engineStrict": true
|
|
67
68
|
}
|