knip 0.3.0 → 0.4.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 +13 -10
- package/dist/cli.js +14 -5
- package/dist/help.js +13 -10
- package/dist/types.d.ts +3 -2
- package/dist/util/fs.d.ts +2 -0
- package/dist/util/fs.js +29 -0
- package/dist/util/ignore.d.ts +2 -0
- package/dist/util/ignore.js +38 -0
- package/dist/util/path.d.ts +3 -1
- package/dist/util/path.js +10 -20
- package/dist/util/project.d.ts +1 -1
- package/dist/util/project.js +6 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -79,16 +79,18 @@ Please read on if you think you have too many results: [too many false positives
|
|
|
79
79
|
knip [options]
|
|
80
80
|
|
|
81
81
|
Options:
|
|
82
|
-
-c/--config [file]
|
|
83
|
-
-t/--tsConfig [file]
|
|
84
|
-
--dir
|
|
85
|
-
--include
|
|
86
|
-
--exclude
|
|
87
|
-
--
|
|
88
|
-
--no-
|
|
89
|
-
--
|
|
90
|
-
--
|
|
91
|
-
--
|
|
82
|
+
-c/--config [file] Configuration file path (default: ./knip.json or package.json#knip)
|
|
83
|
+
-t/--tsConfig [file] TypeScript configuration path (default: ./tsconfig.json)
|
|
84
|
+
--dir Working directory (default: current working directory)
|
|
85
|
+
--include Report only listed issue group(s) (see below)
|
|
86
|
+
--exclude Exclude issue group(s) from report (see below)
|
|
87
|
+
--ignore Ignore files matching this glob pattern (can be set multiple times)
|
|
88
|
+
--no-gitignore Don't use .gitignore
|
|
89
|
+
--dev Include `devDependencies` in report(s)
|
|
90
|
+
--no-progress Don't show dynamic progress updates
|
|
91
|
+
--max-issues Maximum number of issues before non-zero exit code (default: 0)
|
|
92
|
+
--reporter Select reporter: symbols, compact (default: symbols)
|
|
93
|
+
--jsdoc Enable JSDoc parsing, with options: public
|
|
92
94
|
|
|
93
95
|
Issue groups: files, dependencies, unlisted, exports, nsExports, types, nsTypes, duplicates
|
|
94
96
|
|
|
@@ -97,6 +99,7 @@ Examples:
|
|
|
97
99
|
$ knip
|
|
98
100
|
$ knip --dir packages/client --include files
|
|
99
101
|
$ knip -c ./knip.js --reporter compact --jsdoc public
|
|
102
|
+
$ knip --ignore 'lib/**/*.ts' --ignore build
|
|
100
103
|
|
|
101
104
|
More info: https://github.com/webpro/knip
|
|
102
105
|
```
|
package/dist/cli.js
CHANGED
|
@@ -9,10 +9,11 @@ const node_util_1 = require("node:util");
|
|
|
9
9
|
const typescript_1 = __importDefault(require("typescript"));
|
|
10
10
|
const help_1 = require("./help");
|
|
11
11
|
const config_1 = require("./util/config");
|
|
12
|
-
const
|
|
12
|
+
const fs_1 = require("./util/fs");
|
|
13
|
+
const ignore_1 = require("./util/ignore");
|
|
13
14
|
const reporters_1 = __importDefault(require("./reporters"));
|
|
14
15
|
const _1 = require(".");
|
|
15
|
-
const { values: { help, dir, config: configFilePath = 'knip.json', tsConfig: tsConfigFilePath, include = [], exclude = [], dev: isDev = false, 'no-progress': noProgress = false, reporter = 'symbols', jsdoc = [], 'max-issues': maxIssues = '0', }, } = (0, node_util_1.parseArgs)({
|
|
16
|
+
const { values: { help, dir, config: configFilePath = 'knip.json', tsConfig: tsConfigFilePath, include = [], exclude = [], dev: isDev = false, 'no-progress': noProgress = false, ignore = [], 'no-gitignore': isNoGitIgnore = false, reporter = 'symbols', jsdoc = [], 'max-issues': maxIssues = '0', }, } = (0, node_util_1.parseArgs)({
|
|
16
17
|
options: {
|
|
17
18
|
help: { type: 'boolean' },
|
|
18
19
|
config: { type: 'string', short: 'c' },
|
|
@@ -22,6 +23,8 @@ const { values: { help, dir, config: configFilePath = 'knip.json', tsConfig: tsC
|
|
|
22
23
|
exclude: { type: 'string', multiple: true },
|
|
23
24
|
dev: { type: 'boolean' },
|
|
24
25
|
'max-issues': { type: 'string' },
|
|
26
|
+
ignore: { type: 'string', multiple: true },
|
|
27
|
+
'no-gitignore': { type: 'boolean' },
|
|
25
28
|
'no-progress': { type: 'boolean' },
|
|
26
29
|
reporter: { type: 'string' },
|
|
27
30
|
jsdoc: { type: 'string', multiple: true },
|
|
@@ -36,8 +39,8 @@ const workingDir = dir ? node_path_1.default.resolve(dir) : cwd;
|
|
|
36
39
|
const isShowProgress = noProgress === false ? process.stdout.isTTY && typeof process.stdout.cursorTo === 'function' : !noProgress;
|
|
37
40
|
const printReport = reporter in reporters_1.default ? reporters_1.default[reporter] : require(node_path_1.default.join(workingDir, reporter));
|
|
38
41
|
const main = async () => {
|
|
39
|
-
const localConfigurationPath = await (0,
|
|
40
|
-
const manifestPath = await (0,
|
|
42
|
+
const localConfigurationPath = await (0, fs_1.findFile)(workingDir, configFilePath);
|
|
43
|
+
const manifestPath = await (0, fs_1.findFile)(workingDir, 'package.json');
|
|
41
44
|
const localConfiguration = localConfigurationPath && require(localConfigurationPath);
|
|
42
45
|
const manifest = manifestPath && require(manifestPath);
|
|
43
46
|
if (!localConfigurationPath && !manifest.knip) {
|
|
@@ -53,7 +56,7 @@ const main = async () => {
|
|
|
53
56
|
}
|
|
54
57
|
const report = (0, config_1.resolveIncludedIssueGroups)(include, exclude, resolvedConfig);
|
|
55
58
|
let tsConfigPaths = [];
|
|
56
|
-
const tsConfigPath = await (0,
|
|
59
|
+
const tsConfigPath = await (0, fs_1.findFile)(workingDir, tsConfigFilePath ?? 'tsconfig.json');
|
|
57
60
|
if (tsConfigFilePath && !tsConfigPath) {
|
|
58
61
|
console.error(`Unable to find ${tsConfigFilePath}\n`);
|
|
59
62
|
(0, help_1.printHelp)();
|
|
@@ -70,6 +73,11 @@ const main = async () => {
|
|
|
70
73
|
process.exit(1);
|
|
71
74
|
}
|
|
72
75
|
}
|
|
76
|
+
const ignorePatterns = ignore.map(ignore_1.convertPattern);
|
|
77
|
+
if (!isNoGitIgnore) {
|
|
78
|
+
const patterns = await (0, ignore_1.readIgnorePatterns)(cwd, workingDir);
|
|
79
|
+
patterns.forEach(pattern => ignorePatterns.push(pattern));
|
|
80
|
+
}
|
|
73
81
|
const config = {
|
|
74
82
|
workingDir,
|
|
75
83
|
report,
|
|
@@ -78,6 +86,7 @@ const main = async () => {
|
|
|
78
86
|
isDev: typeof resolvedConfig.dev === 'boolean' ? resolvedConfig.dev : isDev,
|
|
79
87
|
tsConfigFilePath,
|
|
80
88
|
tsConfigPaths,
|
|
89
|
+
ignorePatterns,
|
|
81
90
|
isShowProgress,
|
|
82
91
|
jsDocOptions: {
|
|
83
92
|
isReadPublicTag: jsdoc.includes('public'),
|
package/dist/help.js
CHANGED
|
@@ -5,16 +5,18 @@ const printHelp = () => {
|
|
|
5
5
|
console.log(`knip [options]
|
|
6
6
|
|
|
7
7
|
Options:
|
|
8
|
-
-c/--config [file]
|
|
9
|
-
-t/--tsConfig [file]
|
|
10
|
-
--dir
|
|
11
|
-
--include
|
|
12
|
-
--exclude
|
|
13
|
-
--
|
|
14
|
-
--no-
|
|
15
|
-
--
|
|
16
|
-
--
|
|
17
|
-
--
|
|
8
|
+
-c/--config [file] Configuration file path (default: ./knip.json or package.json#knip)
|
|
9
|
+
-t/--tsConfig [file] TypeScript configuration path (default: ./tsconfig.json)
|
|
10
|
+
--dir Working directory (default: current working directory)
|
|
11
|
+
--include Report only listed issue group(s) (see below)
|
|
12
|
+
--exclude Exclude issue group(s) from report (see below)
|
|
13
|
+
--ignore Ignore files matching this glob pattern (can be set multiple times)
|
|
14
|
+
--no-gitignore Don't use .gitignore
|
|
15
|
+
--dev Include \`devDependencies\` in report(s)
|
|
16
|
+
--no-progress Don't show dynamic progress updates
|
|
17
|
+
--max-issues Maximum number of issues before non-zero exit code (default: 0)
|
|
18
|
+
--reporter Select reporter: symbols, compact (default: symbols)
|
|
19
|
+
--jsdoc Enable JSDoc parsing, with options: public
|
|
18
20
|
|
|
19
21
|
Issue groups: files, dependencies, unlisted, exports, nsExports, types, nsTypes, duplicates
|
|
20
22
|
|
|
@@ -23,6 +25,7 @@ Examples:
|
|
|
23
25
|
$ knip
|
|
24
26
|
$ knip --dir packages/client --include files
|
|
25
27
|
$ knip -c ./knip.js --reporter compact --jsdoc public
|
|
28
|
+
$ knip --ignore 'lib/**/*.ts' --ignore build
|
|
26
29
|
|
|
27
30
|
More info: https://github.com/webpro/knip`);
|
|
28
31
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -20,11 +20,11 @@ export declare type Issues = {
|
|
|
20
20
|
nsTypes: UnusedExportIssues;
|
|
21
21
|
duplicates: UnusedExportIssues;
|
|
22
22
|
};
|
|
23
|
-
|
|
23
|
+
declare type IssueType = keyof Issues;
|
|
24
24
|
export declare type ProjectIssueType = Extract<IssueType, 'files' | 'dependencies' | 'devDependencies'>;
|
|
25
25
|
export declare type SymbolIssueType = Exclude<IssueType, ProjectIssueType>;
|
|
26
26
|
export declare type IssueGroup = 'files' | 'dependencies' | 'unlisted' | 'exports' | 'nsExports' | 'types' | 'nsTypes' | 'duplicates';
|
|
27
|
-
|
|
27
|
+
declare type BaseLocalConfiguration = {
|
|
28
28
|
entryFiles: string[];
|
|
29
29
|
projectFiles: string[];
|
|
30
30
|
};
|
|
@@ -46,6 +46,7 @@ export declare type Configuration = LocalConfiguration & {
|
|
|
46
46
|
isDev: boolean;
|
|
47
47
|
tsConfigFilePath: undefined | string;
|
|
48
48
|
tsConfigPaths: string[];
|
|
49
|
+
ignorePatterns: string[];
|
|
49
50
|
isShowProgress: boolean;
|
|
50
51
|
jsDocOptions: {
|
|
51
52
|
isReadPublicTag: boolean;
|
package/dist/util/fs.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
exports.findFile = exports.isFile = void 0;
|
|
7
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const isFile = async (filePath) => {
|
|
10
|
+
try {
|
|
11
|
+
const stats = await promises_1.default.stat(filePath);
|
|
12
|
+
return stats.isFile();
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
exports.isFile = isFile;
|
|
19
|
+
const findFile = async (cwd, fileName) => {
|
|
20
|
+
const filePath = node_path_1.default.join(cwd, fileName);
|
|
21
|
+
if (await (0, exports.isFile)(filePath)) {
|
|
22
|
+
return filePath;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const parentDir = node_path_1.default.resolve(cwd, '..');
|
|
26
|
+
return parentDir === '/' ? undefined : (0, exports.findFile)(parentDir, fileName);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
exports.findFile = findFile;
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
exports.readIgnorePatterns = exports.convertPattern = void 0;
|
|
7
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const fs_1 = require("./fs");
|
|
10
|
+
const path_1 = require("./path");
|
|
11
|
+
const convertPattern = (pattern) => (pattern.startsWith('!') ? pattern.substring(1) : `!${pattern}`);
|
|
12
|
+
exports.convertPattern = convertPattern;
|
|
13
|
+
const readIgnoreFile = async (filePath) => {
|
|
14
|
+
let contents = '';
|
|
15
|
+
try {
|
|
16
|
+
contents = (await promises_1.default.readFile(filePath)).toString();
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
}
|
|
20
|
+
return contents.split(/\r?\n/).filter(line => line && !line.startsWith('#'));
|
|
21
|
+
};
|
|
22
|
+
const traverseDirs = async (rootDir, currentDir, patterns = []) => {
|
|
23
|
+
const gitIgnorePath = node_path_1.default.join(currentDir, '.gitignore');
|
|
24
|
+
const parentDir = node_path_1.default.resolve(currentDir, '..');
|
|
25
|
+
if (await (0, fs_1.isFile)(gitIgnorePath)) {
|
|
26
|
+
(await readIgnoreFile(gitIgnorePath))
|
|
27
|
+
.map(pattern => (0, path_1.addWorkingDirToPattern)(currentDir, pattern))
|
|
28
|
+
.forEach(pattern => patterns.push(pattern));
|
|
29
|
+
}
|
|
30
|
+
if (rootDir === currentDir || parentDir === '/')
|
|
31
|
+
return patterns;
|
|
32
|
+
return traverseDirs(rootDir, parentDir, patterns);
|
|
33
|
+
};
|
|
34
|
+
const readIgnorePatterns = async (cwd, workingDir) => {
|
|
35
|
+
const patterns = await traverseDirs(cwd, workingDir);
|
|
36
|
+
return patterns.map(exports.convertPattern);
|
|
37
|
+
};
|
|
38
|
+
exports.readIgnorePatterns = readIgnorePatterns;
|
package/dist/util/path.d.ts
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Configuration } from '../types';
|
|
2
|
+
export declare const addWorkingDirToPattern: (workingDir: string, pattern: string) => string;
|
|
3
|
+
export declare const resolvePaths: (configuration: Configuration, patterns: string[]) => string[];
|
package/dist/util/path.js
CHANGED
|
@@ -3,26 +3,16 @@ 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.
|
|
7
|
-
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
6
|
+
exports.resolvePaths = exports.addWorkingDirToPattern = void 0;
|
|
8
7
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
8
|
+
const addWorkingDirToPattern = (workingDir, pattern) => {
|
|
9
|
+
if (pattern.startsWith('!'))
|
|
10
|
+
return '!' + node_path_1.default.join(workingDir, pattern.slice(1));
|
|
11
|
+
return node_path_1.default.join(workingDir, pattern);
|
|
17
12
|
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
const parentDir = node_path_1.default.resolve(cwd, '..');
|
|
25
|
-
return parentDir === '/' ? undefined : (0, exports.findFile)(parentDir, fileName);
|
|
26
|
-
}
|
|
13
|
+
exports.addWorkingDirToPattern = addWorkingDirToPattern;
|
|
14
|
+
const resolvePaths = (configuration, patterns) => {
|
|
15
|
+
const { workingDir } = configuration;
|
|
16
|
+
return patterns.map(pattern => (0, exports.addWorkingDirToPattern)(workingDir, pattern));
|
|
27
17
|
};
|
|
28
|
-
exports.
|
|
18
|
+
exports.resolvePaths = resolvePaths;
|
package/dist/util/project.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Project } from 'ts-morph';
|
|
2
2
|
import type { SourceFile } from 'ts-morph';
|
|
3
3
|
import type { Configuration } from '../types';
|
|
4
|
-
export declare const createProject: (configuration: Configuration, paths?: string
|
|
4
|
+
export declare const createProject: (configuration: Configuration, paths?: string[]) => Promise<Project>;
|
|
5
5
|
export declare const partitionSourceFiles: (projectFiles: SourceFile[], productionFiles: SourceFile[]) => SourceFile[][];
|
package/dist/util/project.js
CHANGED
|
@@ -1,28 +1,20 @@
|
|
|
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.partitionSourceFiles = exports.createProject = void 0;
|
|
7
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
8
4
|
const ts_morph_1 = require("ts-morph");
|
|
9
|
-
const
|
|
10
|
-
return [patterns].flat().map(pattern => {
|
|
11
|
-
if (pattern.startsWith('!'))
|
|
12
|
-
return '!' + node_path_1.default.join(cwd, pattern.slice(1));
|
|
13
|
-
return node_path_1.default.join(cwd, pattern);
|
|
14
|
-
});
|
|
15
|
-
};
|
|
5
|
+
const path_1 = require("./path");
|
|
16
6
|
const createProject = async (configuration, paths) => {
|
|
17
|
-
const { tsConfigFilePath,
|
|
7
|
+
const { tsConfigFilePath, ignorePatterns } = configuration;
|
|
18
8
|
const tsConfig = tsConfigFilePath ? { tsConfigFilePath } : { compilerOptions: { allowJs: true } };
|
|
19
9
|
const workspace = new ts_morph_1.Project({
|
|
20
10
|
...tsConfig,
|
|
21
11
|
skipAddingFilesFromTsConfig: true,
|
|
22
12
|
skipFileDependencyResolution: true,
|
|
23
13
|
});
|
|
24
|
-
if (paths)
|
|
25
|
-
|
|
14
|
+
if (paths) {
|
|
15
|
+
const resolvedPaths = (0, path_1.resolvePaths)(configuration, paths);
|
|
16
|
+
workspace.addSourceFilesAtPaths([...resolvedPaths, ...ignorePatterns]);
|
|
17
|
+
}
|
|
26
18
|
return workspace;
|
|
27
19
|
};
|
|
28
20
|
exports.createProject = createProject;
|