knip 0.5.0 → 0.7.0
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 +69 -4
- package/dist/cli.js +3 -2
- package/dist/help.js +3 -1
- package/dist/index.js +2 -0
- package/dist/reporters/codeowners.d.ts +3 -0
- package/dist/reporters/codeowners.js +98 -0
- package/dist/reporters/compact.d.ts +2 -7
- package/dist/reporters/compact.js +1 -1
- package/dist/reporters/index.d.ts +3 -12
- package/dist/reporters/index.js +2 -0
- package/dist/reporters/symbols.d.ts +2 -7
- package/dist/reporters/symbols.js +1 -1
- package/dist/types.d.ts +11 -0
- package/dist/util/dependencies.js +5 -4
- package/dist/util/fs.d.ts +0 -1
- package/dist/util/fs.js +2 -3
- package/dist/util/path.d.ts +0 -1
- package/dist/util/path.js +2 -3
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ This is where Knip comes in:
|
|
|
20
20
|
- [x] Finds duplicate exports of the same symbol.
|
|
21
21
|
- [x] Supports JavaScript inside TypeScript projects (`"allowJs": true`)
|
|
22
22
|
- [x] Supports JavaScript-only projects using ESM (without a `tsconfig.json`)
|
|
23
|
+
- [x] Features multiple [reporters](#reporters) and supports [custom reporters](#custom-reporters).
|
|
23
24
|
|
|
24
25
|
Knip really shines in larger projects where you have non-production files (such as `/docs`, `/tools` and `/scripts`).
|
|
25
26
|
The `includes` setting in `tsconfig.json` is often too broad, resulting in too many false negatives. To produce good
|
|
@@ -91,7 +92,8 @@ Options:
|
|
|
91
92
|
--dev Include `devDependencies` in report(s)
|
|
92
93
|
--no-progress Don't show dynamic progress updates
|
|
93
94
|
--max-issues Maximum number of issues before non-zero exit code (default: 0)
|
|
94
|
-
--reporter Select reporter: symbols, compact (default: symbols)
|
|
95
|
+
--reporter Select reporter: symbols, compact, codeowners (default: symbols)
|
|
96
|
+
--reporter-options Pass extra options to the reporter (as JSON string, see example)
|
|
95
97
|
--jsdoc Enable JSDoc parsing, with options: public
|
|
96
98
|
--debug Show debug output
|
|
97
99
|
--debug-level Set verbosity of debug output (default: 1, max: 2)
|
|
@@ -104,6 +106,7 @@ $ knip
|
|
|
104
106
|
$ knip --dir packages/client --include files
|
|
105
107
|
$ knip -c ./knip.js --reporter compact --jsdoc public
|
|
106
108
|
$ knip --ignore 'lib/**/*.ts' --ignore build
|
|
109
|
+
$ knip --reporter codeowners --reporter-options '{"path":".github/CODEOWNERS"}'
|
|
107
110
|
|
|
108
111
|
More info: https://github.com/webpro/knip
|
|
109
112
|
```
|
|
@@ -245,9 +248,38 @@ module.exports = { entryFiles, projectFiles };
|
|
|
245
248
|
This should give good results about unused files and exports for the monorepo. After the first run, the configuration
|
|
246
249
|
can be tweaked further to the project structure.
|
|
247
250
|
|
|
248
|
-
##
|
|
251
|
+
## Reporters
|
|
249
252
|
|
|
250
|
-
|
|
253
|
+
For starters, Knip already contains a few useful reporters:
|
|
254
|
+
|
|
255
|
+
- `symbol` (default)
|
|
256
|
+
- `compact`
|
|
257
|
+
- `codeowners`
|
|
258
|
+
|
|
259
|
+
### Custom Reporters
|
|
260
|
+
|
|
261
|
+
When a `--reporter ./my-reporter` is passed, the default export of that module should have this interface:
|
|
262
|
+
|
|
263
|
+
```ts
|
|
264
|
+
type Reporter = (options: ReporterOptions) => void;
|
|
265
|
+
|
|
266
|
+
type ReporterOptions = {
|
|
267
|
+
report: Report;
|
|
268
|
+
issues: Issues;
|
|
269
|
+
cwd: string;
|
|
270
|
+
workingDir: string;
|
|
271
|
+
isDev: boolean;
|
|
272
|
+
options: string;
|
|
273
|
+
};
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
The data can then be used to write issues to `stdout`, a JSON or CSV file, or sent to a service, anything really!
|
|
277
|
+
|
|
278
|
+
### Example Output
|
|
279
|
+
|
|
280
|
+
#### Symbol (default)
|
|
281
|
+
|
|
282
|
+
The default reporter shows the sorted symbols first:
|
|
251
283
|
|
|
252
284
|
```
|
|
253
285
|
$ knip
|
|
@@ -274,7 +306,9 @@ Registration, default src/components/Registration.tsx
|
|
|
274
306
|
ProductsList, default src/components/Products.tsx
|
|
275
307
|
```
|
|
276
308
|
|
|
277
|
-
|
|
309
|
+
#### Compact
|
|
310
|
+
|
|
311
|
+
The compact reporter shows the sorted files first, and then a list of symbols:
|
|
278
312
|
|
|
279
313
|
```
|
|
280
314
|
$ knip --reporter compact
|
|
@@ -299,6 +333,37 @@ src/components/Registration.tsx: Registration, default
|
|
|
299
333
|
src/components/Products.tsx: ProductsList, default
|
|
300
334
|
```
|
|
301
335
|
|
|
336
|
+
#### Code Owners
|
|
337
|
+
|
|
338
|
+
The `codeowners` reporter is like `compact`, but shows the sorted code owners (according to `.github/CODEOWNERS`) first:
|
|
339
|
+
|
|
340
|
+
```
|
|
341
|
+
$ knip --reporter codeowners
|
|
342
|
+
--- UNUSED FILES (2)
|
|
343
|
+
@org/team src/chat/helpers.ts
|
|
344
|
+
@org/owner src/components/SideBar.tsx
|
|
345
|
+
--- UNUSED DEPENDENCIES (1)
|
|
346
|
+
@org/admin moment
|
|
347
|
+
--- UNLISTED DEPENDENCIES (1)
|
|
348
|
+
@org/owner src/components/Registration.tsx react
|
|
349
|
+
--- UNUSED EXPORTS (4)
|
|
350
|
+
@org/team src/common/src/string/index.ts: lowercaseFirstLetter
|
|
351
|
+
@org/owner src/components/Registration.tsx: RegistrationBox
|
|
352
|
+
@org/owner src/css.ts: clamp
|
|
353
|
+
@org/owner src/services/authentication.ts: restoreSession, PREFIX
|
|
354
|
+
--- UNUSED TYPES (3)
|
|
355
|
+
@org/owner src/components/Registration/registrationMachine.ts: RegistrationServices, RegistrationAction
|
|
356
|
+
@org/owner src/components/Registration.tsx: ComponentProps
|
|
357
|
+
@org/owner src/types/Product.ts: ProductDetail
|
|
358
|
+
--- DUPLICATE EXPORTS (2)
|
|
359
|
+
@org/owner src/components/Registration.tsx: Registration, default
|
|
360
|
+
@org/owner src/components/Products.tsx: ProductsList, default
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
The owner of `package.json` is considered the owner of unused (dev) dependencies.
|
|
364
|
+
|
|
365
|
+
Use `--reporter-options '{"path":".github/CODEOWNERS"}'` to pass another location for the code owners file.
|
|
366
|
+
|
|
302
367
|
## Why Yet Another unused file/dependency/export finder?
|
|
303
368
|
|
|
304
369
|
There are already some great packages available. Getting good results when finding unused files, dependencies and
|
package/dist/cli.js
CHANGED
|
@@ -10,7 +10,7 @@ const _1 = require(".");
|
|
|
10
10
|
const help_1 = require("./help");
|
|
11
11
|
const reporters_1 = __importDefault(require("./reporters"));
|
|
12
12
|
const errors_1 = require("./util/errors");
|
|
13
|
-
const { values: { help, dir, config: configFilePath = 'knip.json', tsConfig: tsConfigFilePath, include = [], exclude = [], ignore = [], 'no-gitignore': isNoGitIgnore = false, dev: isDev = false, 'no-progress': noProgress = false, reporter = 'symbols', 'max-issues': maxIssues = '0', jsdoc: jsDoc = [], debug: isDebug = false, 'debug-level': debugLevel = '1', }, } = (0, node_util_1.parseArgs)({
|
|
13
|
+
const { values: { help, dir, config: configFilePath = 'knip.json', tsConfig: tsConfigFilePath, include = [], exclude = [], ignore = [], 'no-gitignore': isNoGitIgnore = false, dev: isDev = false, 'no-progress': noProgress = false, reporter = 'symbols', 'reporter-options': reporterOptions = '', 'max-issues': maxIssues = '0', jsdoc: jsDoc = [], debug: isDebug = false, 'debug-level': debugLevel = '1', }, } = (0, node_util_1.parseArgs)({
|
|
14
14
|
options: {
|
|
15
15
|
help: { type: 'boolean' },
|
|
16
16
|
config: { type: 'string', short: 'c' },
|
|
@@ -24,6 +24,7 @@ const { values: { help, dir, config: configFilePath = 'knip.json', tsConfig: tsC
|
|
|
24
24
|
'no-progress': { type: 'boolean' },
|
|
25
25
|
'max-issues': { type: 'string' },
|
|
26
26
|
reporter: { type: 'string' },
|
|
27
|
+
'reporter-options': { type: 'string' },
|
|
27
28
|
jsdoc: { type: 'string', multiple: true },
|
|
28
29
|
debug: { type: 'boolean' },
|
|
29
30
|
'debug-level': { type: 'string' },
|
|
@@ -56,7 +57,7 @@ const run = async () => {
|
|
|
56
57
|
level: isDebug ? Number(debugLevel) : 0,
|
|
57
58
|
},
|
|
58
59
|
});
|
|
59
|
-
printReport({ report, issues, workingDir, isDev });
|
|
60
|
+
printReport({ report, issues, cwd, workingDir, isDev, options: reporterOptions });
|
|
60
61
|
const reportGroup = report.files ? 'files' : Object.keys(report).find(key => report[key]);
|
|
61
62
|
const counterGroup = reportGroup === 'unlisted' ? 'unresolved' : reportGroup;
|
|
62
63
|
if (counterGroup) {
|
package/dist/help.js
CHANGED
|
@@ -15,7 +15,8 @@ Options:
|
|
|
15
15
|
--dev Include \`devDependencies\` in report(s)
|
|
16
16
|
--no-progress Don't show dynamic progress updates
|
|
17
17
|
--max-issues Maximum number of issues before non-zero exit code (default: 0)
|
|
18
|
-
--reporter Select reporter: symbols, compact (default: symbols)
|
|
18
|
+
--reporter Select reporter: symbols, compact, codeowners (default: symbols)
|
|
19
|
+
--reporter-options Pass extra options to the reporter (as JSON string, see example)
|
|
19
20
|
--jsdoc Enable JSDoc parsing, with options: public
|
|
20
21
|
--debug Show debug output
|
|
21
22
|
--debug-level Set verbosity of debug output (default: 1, max: 2)
|
|
@@ -28,6 +29,7 @@ $ knip
|
|
|
28
29
|
$ knip --dir packages/client --include files
|
|
29
30
|
$ knip -c ./knip.js --reporter compact --jsdoc public
|
|
30
31
|
$ knip --ignore 'lib/**/*.ts' --ignore build
|
|
32
|
+
$ knip --reporter codeowners --reporter-options '{"path":".github/CODEOWNERS"}'
|
|
31
33
|
|
|
32
34
|
More info: https://github.com/webpro/knip`);
|
|
33
35
|
};
|
package/dist/index.js
CHANGED
|
@@ -78,6 +78,8 @@ const main = async (options) => {
|
|
|
78
78
|
productionFiles,
|
|
79
79
|
projectFiles,
|
|
80
80
|
dependencies: Object.keys(manifest.dependencies ?? {}),
|
|
81
|
+
peerDependencies: Object.keys(manifest.peerDependencies ?? {}),
|
|
82
|
+
optionalDependencies: Object.keys(manifest.optionalDependencies ?? {}),
|
|
81
83
|
devDependencies: Object.keys(manifest.devDependencies ?? {}),
|
|
82
84
|
isDev: typeof resolvedConfig.dev === 'boolean' ? resolvedConfig.dev : isDev,
|
|
83
85
|
tsConfigPaths,
|
|
@@ -0,0 +1,98 @@
|
|
|
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 ownership_1 = require("@snyk/github-codeowners/dist/lib/ownership");
|
|
8
|
+
const logIssueLine = (owner, cwd, filePath, symbols) => {
|
|
9
|
+
console.log(`${owner} ${node_path_1.default.relative(cwd, filePath)}${symbols ? `: ${symbols.join(', ')}` : ''}`);
|
|
10
|
+
};
|
|
11
|
+
const logIssueGroupResult = (issues, cwd, title) => {
|
|
12
|
+
title && console.log(`--- ${title} (${issues.length})`);
|
|
13
|
+
if (issues.length) {
|
|
14
|
+
issues
|
|
15
|
+
.sort((a, b) => (a.owner < b.owner ? -1 : 1))
|
|
16
|
+
.forEach(issue => console.log(issue.owner, issue.symbol.startsWith('/') ? node_path_1.default.relative(cwd, issue.symbol) : issue.symbol));
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
console.log('Not found');
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const logIssueGroupResults = (issues, cwd, title) => {
|
|
23
|
+
title && console.log(`--- ${title} (${issues.length})`);
|
|
24
|
+
if (issues.length) {
|
|
25
|
+
const sortedByFilePath = issues.sort((a, b) => (a.owner < b.owner ? -1 : 1));
|
|
26
|
+
sortedByFilePath.forEach(({ filePath, symbols, owner }) => logIssueLine(owner, cwd, filePath, symbols));
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
console.log('Not found');
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
exports.default = ({ report, issues, cwd, isDev, options }) => {
|
|
33
|
+
let opts = {};
|
|
34
|
+
try {
|
|
35
|
+
opts = JSON.parse(options);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
console.error(error);
|
|
39
|
+
}
|
|
40
|
+
const codeownersFilePath = node_path_1.default.resolve(opts.path ?? '.github/CODEOWNERS');
|
|
41
|
+
const codeownersEngine = ownership_1.OwnershipEngine.FromCodeownersFile(codeownersFilePath);
|
|
42
|
+
const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
|
|
43
|
+
const [dependenciesOwner = '[no-owner]'] = codeownersEngine.calcFileOwnership('package.json');
|
|
44
|
+
const fallbackOwner = dependenciesOwner;
|
|
45
|
+
const calcFileOwnership = (filePath) => codeownersEngine.calcFileOwnership(node_path_1.default.relative(cwd, filePath))[0] ?? fallbackOwner;
|
|
46
|
+
const toIssueWithOwner = (issues) => {
|
|
47
|
+
const items = Object.values(issues);
|
|
48
|
+
return { ...items[0], symbols: items.map(i => i.symbol), owner: calcFileOwnership(items[0].filePath) };
|
|
49
|
+
};
|
|
50
|
+
if (report.files) {
|
|
51
|
+
const unreferencedFilesByOwner = Array.from(issues.files).map(filePath => ({
|
|
52
|
+
symbol: filePath,
|
|
53
|
+
owner: calcFileOwnership(filePath),
|
|
54
|
+
}));
|
|
55
|
+
logIssueGroupResult(unreferencedFilesByOwner, cwd, reportMultipleGroups && 'UNUSED FILES');
|
|
56
|
+
}
|
|
57
|
+
if (report.dependencies) {
|
|
58
|
+
const unreferencedDependencies = Array.from(issues.dependencies).map(dependency => ({
|
|
59
|
+
symbol: dependency,
|
|
60
|
+
owner: dependenciesOwner,
|
|
61
|
+
}));
|
|
62
|
+
logIssueGroupResult(unreferencedDependencies, cwd, reportMultipleGroups && 'UNUSED DEPENDENCIES');
|
|
63
|
+
}
|
|
64
|
+
if (report.dependencies && isDev) {
|
|
65
|
+
const unreferencedDevDependencies = Array.from(issues.devDependencies).map(dependency => ({
|
|
66
|
+
symbol: dependency,
|
|
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');
|
|
97
|
+
}
|
|
98
|
+
};
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
declare const _default: ({ report, issues, workingDir, isDev
|
|
3
|
-
report: Report;
|
|
4
|
-
issues: Issues;
|
|
5
|
-
workingDir: string;
|
|
6
|
-
isDev: boolean;
|
|
7
|
-
}) => void;
|
|
1
|
+
import type { ReporterOptions } from '../types';
|
|
2
|
+
declare const _default: ({ report, issues, workingDir, isDev }: ReporterOptions) => void;
|
|
8
3
|
export default _default;
|
|
@@ -26,7 +26,7 @@ const logIssueGroupResults = (issues, workingDir, title) => {
|
|
|
26
26
|
console.log('Not found');
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
|
-
exports.default = ({ report, issues, workingDir, isDev
|
|
29
|
+
exports.default = ({ report, issues, workingDir, isDev }) => {
|
|
30
30
|
const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
|
|
31
31
|
if (report.files) {
|
|
32
32
|
const unreferencedFiles = Array.from(issues.files);
|
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
declare const _default: {
|
|
2
|
-
symbols: ({ report, issues, workingDir, isDev
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
workingDir: string;
|
|
6
|
-
isDev: boolean;
|
|
7
|
-
}) => void;
|
|
8
|
-
compact: ({ report, issues, workingDir, isDev, }: {
|
|
9
|
-
report: import("../types").Report;
|
|
10
|
-
issues: import("../types").Issues;
|
|
11
|
-
workingDir: string;
|
|
12
|
-
isDev: boolean;
|
|
13
|
-
}) => void;
|
|
2
|
+
symbols: ({ report, issues, workingDir, isDev }: import("../types").ReporterOptions) => void;
|
|
3
|
+
compact: ({ report, issues, workingDir, isDev }: import("../types").ReporterOptions) => void;
|
|
4
|
+
codeowners: ({ report, issues, cwd, isDev, options }: import("../types").ReporterOptions) => void;
|
|
14
5
|
};
|
|
15
6
|
export default _default;
|
package/dist/reporters/index.js
CHANGED
|
@@ -5,7 +5,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const symbols_1 = __importDefault(require("./symbols"));
|
|
7
7
|
const compact_1 = __importDefault(require("./compact"));
|
|
8
|
+
const codeowners_1 = __importDefault(require("./codeowners"));
|
|
8
9
|
exports.default = {
|
|
9
10
|
symbols: symbols_1.default,
|
|
10
11
|
compact: compact_1.default,
|
|
12
|
+
codeowners: codeowners_1.default,
|
|
11
13
|
};
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
declare const _default: ({ report, issues, workingDir, isDev
|
|
3
|
-
report: Report;
|
|
4
|
-
issues: Issues;
|
|
5
|
-
workingDir: string;
|
|
6
|
-
isDev: boolean;
|
|
7
|
-
}) => void;
|
|
1
|
+
import type { ReporterOptions } from '../types';
|
|
2
|
+
declare const _default: ({ report, issues, workingDir, isDev }: ReporterOptions) => void;
|
|
8
3
|
export default _default;
|
|
@@ -28,7 +28,7 @@ const logIssueGroupResults = (issues, workingDir, title) => {
|
|
|
28
28
|
console.log('Not found');
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
|
-
exports.default = ({ report, issues, workingDir, isDev
|
|
31
|
+
exports.default = ({ report, issues, workingDir, isDev }) => {
|
|
32
32
|
const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
|
|
33
33
|
if (report.files) {
|
|
34
34
|
const unreferencedFiles = Array.from(issues.files);
|
package/dist/types.d.ts
CHANGED
|
@@ -62,6 +62,8 @@ export declare type Configuration = {
|
|
|
62
62
|
productionFiles: SourceFile[];
|
|
63
63
|
entryFiles: SourceFile[];
|
|
64
64
|
dependencies: string[];
|
|
65
|
+
peerDependencies: string[];
|
|
66
|
+
optionalDependencies: string[];
|
|
65
67
|
devDependencies: string[];
|
|
66
68
|
isDev: boolean;
|
|
67
69
|
tsConfigPaths: string[];
|
|
@@ -74,4 +76,13 @@ export declare type Configuration = {
|
|
|
74
76
|
level: number;
|
|
75
77
|
};
|
|
76
78
|
};
|
|
79
|
+
export declare type ReporterOptions = {
|
|
80
|
+
report: Report;
|
|
81
|
+
issues: Issues;
|
|
82
|
+
cwd: string;
|
|
83
|
+
workingDir: string;
|
|
84
|
+
isDev: boolean;
|
|
85
|
+
options: string;
|
|
86
|
+
};
|
|
87
|
+
export declare type Reporter = (options: ReporterOptions) => void;
|
|
77
88
|
export {};
|
|
@@ -9,7 +9,8 @@ const is_builtin_module_1 = __importDefault(require("is-builtin-module"));
|
|
|
9
9
|
const micromatch_1 = __importDefault(require("micromatch"));
|
|
10
10
|
const compact = (collection) => Array.from(new Set(collection)).filter((value) => Boolean(value));
|
|
11
11
|
const getDependencyAnalyzer = (configuration) => {
|
|
12
|
-
const { dependencies, devDependencies, tsConfigPaths } = configuration;
|
|
12
|
+
const { dependencies, devDependencies, peerDependencies, optionalDependencies, tsConfigPaths } = configuration;
|
|
13
|
+
const productionDependencies = [...dependencies, ...peerDependencies, ...optionalDependencies];
|
|
13
14
|
const referencedDependencies = new Set();
|
|
14
15
|
const getUnresolvedDependencies = (sourceFile) => {
|
|
15
16
|
const unresolvedDependencies = new Set();
|
|
@@ -29,16 +30,16 @@ const getDependencyAnalyzer = (configuration) => {
|
|
|
29
30
|
return;
|
|
30
31
|
const parts = moduleSpecifier.split('/').slice(0, 2);
|
|
31
32
|
const packageName = moduleSpecifier.startsWith('@') ? parts.join('/') : parts[0];
|
|
32
|
-
if (!
|
|
33
|
+
if (!productionDependencies.includes(packageName) && !devDependencies.includes(packageName)) {
|
|
33
34
|
unresolvedDependencies.add({ filePath: sourceFile.getFilePath(), symbol: moduleSpecifier });
|
|
34
35
|
}
|
|
35
|
-
if (
|
|
36
|
+
if (productionDependencies.includes(packageName) || devDependencies.includes(packageName)) {
|
|
36
37
|
referencedDependencies.add(packageName);
|
|
37
38
|
}
|
|
38
39
|
});
|
|
39
40
|
return unresolvedDependencies;
|
|
40
41
|
};
|
|
41
|
-
const getUnusedDependencies = () =>
|
|
42
|
+
const getUnusedDependencies = () => productionDependencies.filter(dependency => !referencedDependencies.has(dependency));
|
|
42
43
|
const getUnusedDevDependencies = () => devDependencies.filter(dependency => !referencedDependencies.has(dependency));
|
|
43
44
|
return { getUnresolvedDependencies, getUnusedDependencies, getUnusedDevDependencies };
|
|
44
45
|
};
|
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 =
|
|
6
|
+
exports.findFile = 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,10 +15,9 @@ const isFile = async (filePath) => {
|
|
|
15
15
|
return false;
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
|
-
exports.isFile = isFile;
|
|
19
18
|
const findFile = async (cwd, fileName) => {
|
|
20
19
|
const filePath = node_path_1.default.join(cwd, fileName);
|
|
21
|
-
if (await
|
|
20
|
+
if (await isFile(filePath)) {
|
|
22
21
|
return filePath;
|
|
23
22
|
}
|
|
24
23
|
else {
|
package/dist/util/path.d.ts
CHANGED
package/dist/util/path.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.resolvePaths =
|
|
6
|
+
exports.resolvePaths = void 0;
|
|
7
7
|
const node_path_1 = __importDefault(require("node:path"));
|
|
8
8
|
let _globby;
|
|
9
9
|
const glob = async function (patterns, options) {
|
|
@@ -18,8 +18,7 @@ const prependDirToPattern = (workingDir, pattern) => {
|
|
|
18
18
|
return '!' + node_path_1.default.join(workingDir, pattern.slice(1));
|
|
19
19
|
return node_path_1.default.join(workingDir, pattern);
|
|
20
20
|
};
|
|
21
|
-
|
|
22
|
-
const resolvePaths = async ({ cwd, workingDir, patterns, ignore, gitignore, }) => glob(patterns.map(pattern => (0, exports.prependDirToPattern)(node_path_1.default.relative(cwd, workingDir), pattern)), {
|
|
21
|
+
const resolvePaths = async ({ cwd, workingDir, patterns, ignore, gitignore, }) => glob(patterns.map(pattern => prependDirToPattern(node_path_1.default.relative(cwd, workingDir), pattern)), {
|
|
23
22
|
cwd,
|
|
24
23
|
ignore,
|
|
25
24
|
gitignore,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knip",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Find unused files, dependencies and exports in your TypeScript and JavaScript project",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"find",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"license": "ISC",
|
|
42
42
|
"dependencies": {
|
|
43
|
+
"@snyk/github-codeowners": "1.0.0",
|
|
43
44
|
"globby": "13.1.2",
|
|
44
45
|
"is-builtin-module": "3.2.0",
|
|
45
46
|
"micromatch": "4.0.5",
|