knip 0.2.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 +59 -21
- package/dist/cli.js +37 -24
- package/dist/help.js +14 -10
- package/dist/index.js +5 -3
- package/dist/reporters/compact.js +1 -1
- package/dist/reporters/symbols.js +1 -1
- package/dist/types.d.ts +9 -3
- package/dist/util/config.d.ts +4 -1
- package/dist/util/config.js +12 -7
- 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 +2 -1
- package/dist/util/project.js +8 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
# ✂️ Knip
|
|
2
2
|
|
|
3
|
-
Knip scans your TypeScript projects for **unused files and exports**.
|
|
4
|
-
|
|
3
|
+
Knip scans your JavaScript and TypeScript projects for **unused files, dependencies and exports**. Things that should be
|
|
4
|
+
eliminated. Less code means better performance and less to maintain, important for both UX and DX!
|
|
5
|
+
|
|
6
|
+
For comparison, ESLint finds unused variables inside files in isolation, but this will not be flagged:
|
|
5
7
|
|
|
6
8
|
```ts
|
|
7
9
|
export const myVar = true;
|
|
8
10
|
```
|
|
9
11
|
|
|
10
|
-
Unused files will also not be detected by ESLint. So how do you know which files and exports are no longer
|
|
11
|
-
requires an analysis of all the right files in the project.
|
|
12
|
+
Unused files will also not be detected by ESLint. So how do you know which files, dependencies and exports are no longer
|
|
13
|
+
used? This requires an analysis of all the right files in the project.
|
|
12
14
|
|
|
13
15
|
This is where Knip comes in:
|
|
14
16
|
|
|
@@ -17,7 +19,7 @@ This is where Knip comes in:
|
|
|
17
19
|
- [x] Finds dependencies not listed in `package.json`.
|
|
18
20
|
- [x] Finds duplicate exports of the same symbol.
|
|
19
21
|
- [x] Supports JavaScript inside TypeScript projects (`"allowJs": true`)
|
|
20
|
-
- [
|
|
22
|
+
- [x] Supports JavaScript-only projects using ESM (without a `tsconfig.json`)
|
|
21
23
|
|
|
22
24
|
Knip really shines in larger projects where you have non-production files (such as `/docs`, `/tools` and `/scripts`).
|
|
23
25
|
The `includes` setting in `tsconfig.json` is often too broad, resulting in too many false negatives. Similar projects
|
|
@@ -77,23 +79,27 @@ Please read on if you think you have too many results: [too many false positives
|
|
|
77
79
|
knip [options]
|
|
78
80
|
|
|
79
81
|
Options:
|
|
80
|
-
-c/--config [file]
|
|
81
|
-
|
|
82
|
-
--
|
|
83
|
-
--
|
|
84
|
-
--
|
|
85
|
-
--
|
|
86
|
-
--
|
|
87
|
-
--
|
|
88
|
-
--
|
|
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
|
|
89
94
|
|
|
90
95
|
Issue groups: files, dependencies, unlisted, exports, nsExports, types, nsTypes, duplicates
|
|
91
96
|
|
|
92
97
|
Examples:
|
|
93
98
|
|
|
94
99
|
$ knip
|
|
95
|
-
$ knip --
|
|
100
|
+
$ knip --dir packages/client --include files
|
|
96
101
|
$ knip -c ./knip.js --reporter compact --jsdoc public
|
|
102
|
+
$ knip --ignore 'lib/**/*.ts' --ignore build
|
|
97
103
|
|
|
98
104
|
More info: https://github.com/webpro/knip
|
|
99
105
|
```
|
|
@@ -143,8 +149,10 @@ Excluding non-production files from the `projectFiles` allows Knip to understand
|
|
|
143
149
|
|
|
144
150
|
Non-production code includes files such as end-to-end tests, tooling, scripts, Storybook stories, etc.
|
|
145
151
|
|
|
152
|
+
Think of it the same way as you would split `dependencies` and `devDependencies` in `package.json`.
|
|
153
|
+
|
|
146
154
|
To include both production and test files to analyze the project as a whole, include both sets of files to `entryFiles`,
|
|
147
|
-
and add `dev: true`:
|
|
155
|
+
and add `dev: true` to a file named such as `knip.dev.json`:
|
|
148
156
|
|
|
149
157
|
```json
|
|
150
158
|
{
|
|
@@ -154,7 +162,29 @@ and add `dev: true`:
|
|
|
154
162
|
}
|
|
155
163
|
```
|
|
156
164
|
|
|
157
|
-
|
|
165
|
+
Use `-c knip.dev.json` and unused files and exports for the combined set of files as configured in `entryFiles` will be
|
|
166
|
+
reported.
|
|
167
|
+
|
|
168
|
+
An alternative way to store `dev` configuration is in this example `package.json`:
|
|
169
|
+
|
|
170
|
+
```json
|
|
171
|
+
{
|
|
172
|
+
"name": "my-package",
|
|
173
|
+
"scripts": {
|
|
174
|
+
"knip": "knip"
|
|
175
|
+
},
|
|
176
|
+
"knip": {
|
|
177
|
+
"entryFiles": ["src/index.ts"],
|
|
178
|
+
"projectFiles": ["src/**/*.ts", "!**/*.spec.ts"],
|
|
179
|
+
"dev": {
|
|
180
|
+
"entryFiles": ["src/index.ts", "src/**/*.spec.ts", "src/**/*.e2e.ts"],
|
|
181
|
+
"projectFiles": ["src/**/*.ts"]
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
This way, the `--dev` flag will use the `dev` options (and also add `devDependencies` to the `dependencies` report).
|
|
158
188
|
|
|
159
189
|
## More configuration examples
|
|
160
190
|
|
|
@@ -179,8 +209,8 @@ Packages can also be explicitly configured per package directory.
|
|
|
179
209
|
To scan the packages separately, using the first match from the configuration file:
|
|
180
210
|
|
|
181
211
|
```
|
|
182
|
-
knip --cwd packages/client
|
|
183
|
-
knip --cwd packages/services
|
|
212
|
+
knip --cwd packages/client
|
|
213
|
+
knip --cwd packages/services
|
|
184
214
|
```
|
|
185
215
|
|
|
186
216
|
#### Connected projects
|
|
@@ -217,10 +247,14 @@ can be tweaked further to the project structure.
|
|
|
217
247
|
### Default reporter
|
|
218
248
|
|
|
219
249
|
```
|
|
220
|
-
$ knip
|
|
250
|
+
$ knip
|
|
221
251
|
--- UNUSED FILES (2)
|
|
222
252
|
src/chat/helpers.ts
|
|
223
253
|
src/components/SideBar.tsx
|
|
254
|
+
--- UNUSED DEPENDENCIES (1)
|
|
255
|
+
moment
|
|
256
|
+
--- UNLISTED DEPENDENCIES (1)
|
|
257
|
+
react
|
|
224
258
|
--- UNUSED EXPORTS (5)
|
|
225
259
|
lowercaseFirstLetter src/common/src/string/index.ts
|
|
226
260
|
RegistrationBox src/components/Registration.tsx
|
|
@@ -240,10 +274,14 @@ ProductsList, default src/components/Products.tsx
|
|
|
240
274
|
### Compact
|
|
241
275
|
|
|
242
276
|
```
|
|
243
|
-
$ knip --
|
|
277
|
+
$ knip --reporter compact
|
|
244
278
|
--- UNUSED FILES (2)
|
|
245
279
|
src/chat/helpers.ts
|
|
246
280
|
src/components/SideBar.tsx
|
|
281
|
+
--- UNUSED DEPENDENCIES (1)
|
|
282
|
+
moment
|
|
283
|
+
--- UNLISTED DEPENDENCIES (1)
|
|
284
|
+
react
|
|
247
285
|
--- UNUSED EXPORTS (4)
|
|
248
286
|
src/common/src/string/index.ts: lowercaseFirstLetter
|
|
249
287
|
src/components/Registration.tsx: RegistrationBox
|
package/dist/cli.js
CHANGED
|
@@ -9,18 +9,22 @@ 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,
|
|
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' },
|
|
19
|
-
|
|
20
|
+
tsConfig: { type: 'string', short: 't' },
|
|
21
|
+
dir: { type: 'string' },
|
|
20
22
|
include: { type: 'string', multiple: true },
|
|
21
23
|
exclude: { type: 'string', multiple: true },
|
|
22
24
|
dev: { type: 'boolean' },
|
|
23
25
|
'max-issues': { type: 'string' },
|
|
26
|
+
ignore: { type: 'string', multiple: true },
|
|
27
|
+
'no-gitignore': { type: 'boolean' },
|
|
24
28
|
'no-progress': { type: 'boolean' },
|
|
25
29
|
reporter: { type: 'string' },
|
|
26
30
|
jsdoc: { type: 'string', multiple: true },
|
|
@@ -31,49 +35,58 @@ if (help) {
|
|
|
31
35
|
process.exit(0);
|
|
32
36
|
}
|
|
33
37
|
const cwd = process.cwd();
|
|
34
|
-
const workingDir =
|
|
38
|
+
const workingDir = dir ? node_path_1.default.resolve(dir) : cwd;
|
|
35
39
|
const isShowProgress = noProgress === false ? process.stdout.isTTY && typeof process.stdout.cursorTo === 'function' : !noProgress;
|
|
36
40
|
const printReport = reporter in reporters_1.default ? reporters_1.default[reporter] : require(node_path_1.default.join(workingDir, reporter));
|
|
37
41
|
const main = async () => {
|
|
38
|
-
const localConfigurationPath = await (0,
|
|
39
|
-
const manifestPath = await (0,
|
|
40
|
-
|
|
42
|
+
const localConfigurationPath = await (0, fs_1.findFile)(workingDir, configFilePath);
|
|
43
|
+
const manifestPath = await (0, fs_1.findFile)(workingDir, 'package.json');
|
|
44
|
+
const localConfiguration = localConfigurationPath && require(localConfigurationPath);
|
|
45
|
+
const manifest = manifestPath && require(manifestPath);
|
|
46
|
+
if (!localConfigurationPath && !manifest.knip) {
|
|
41
47
|
const location = workingDir === cwd ? 'current directory' : `${node_path_1.default.relative(cwd, workingDir)} or up.`;
|
|
42
|
-
console.error(`Unable to find ${configFilePath}
|
|
48
|
+
console.error(`Unable to find ${configFilePath} or package.json#knip in ${location}\n`);
|
|
43
49
|
(0, help_1.printHelp)();
|
|
44
50
|
process.exit(1);
|
|
45
51
|
}
|
|
46
|
-
const
|
|
47
|
-
const manifest = require(manifestPath);
|
|
48
|
-
const resolvedConfig = (0, config_1.resolveConfig)(manifest.knip ?? localConfiguration, cwdArg);
|
|
52
|
+
const resolvedConfig = (0, config_1.resolveConfig)(manifest.knip ?? localConfiguration, { workingDir: dir, isDev });
|
|
49
53
|
if (!resolvedConfig) {
|
|
50
54
|
(0, help_1.printHelp)();
|
|
51
55
|
process.exit(1);
|
|
52
56
|
}
|
|
53
57
|
const report = (0, config_1.resolveIncludedIssueGroups)(include, exclude, resolvedConfig);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
console.error(`Unable to find ${
|
|
58
|
+
let tsConfigPaths = [];
|
|
59
|
+
const tsConfigPath = await (0, fs_1.findFile)(workingDir, tsConfigFilePath ?? 'tsconfig.json');
|
|
60
|
+
if (tsConfigFilePath && !tsConfigPath) {
|
|
61
|
+
console.error(`Unable to find ${tsConfigFilePath}\n`);
|
|
58
62
|
(0, help_1.printHelp)();
|
|
59
63
|
process.exit(1);
|
|
60
64
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
if (tsConfigPath) {
|
|
66
|
+
const tsConfig = typescript_1.default.readConfigFile(tsConfigPath, typescript_1.default.sys.readFile);
|
|
67
|
+
tsConfigPaths = tsConfig.config.compilerOptions?.paths
|
|
68
|
+
? Object.keys(tsConfig.config.compilerOptions.paths).map(p => p.replace(/\*/g, '**'))
|
|
69
|
+
: [];
|
|
70
|
+
if (tsConfig.error) {
|
|
71
|
+
console.error(`An error occured when reading ${node_path_1.default.relative(cwd, tsConfigPath)}.\n`);
|
|
72
|
+
(0, help_1.printHelp)();
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
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));
|
|
69
80
|
}
|
|
70
81
|
const config = {
|
|
71
82
|
workingDir,
|
|
72
83
|
report,
|
|
73
84
|
dependencies: Object.keys(manifest.dependencies ?? {}),
|
|
74
85
|
devDependencies: Object.keys(manifest.devDependencies ?? {}),
|
|
75
|
-
isDev: resolvedConfig.dev
|
|
86
|
+
isDev: typeof resolvedConfig.dev === 'boolean' ? resolvedConfig.dev : isDev,
|
|
87
|
+
tsConfigFilePath,
|
|
76
88
|
tsConfigPaths,
|
|
89
|
+
ignorePatterns,
|
|
77
90
|
isShowProgress,
|
|
78
91
|
jsDocOptions: {
|
|
79
92
|
isReadPublicTag: jsdoc.includes('public'),
|
package/dist/help.js
CHANGED
|
@@ -5,23 +5,27 @@ const printHelp = () => {
|
|
|
5
5
|
console.log(`knip [options]
|
|
6
6
|
|
|
7
7
|
Options:
|
|
8
|
-
-c/--config [file]
|
|
9
|
-
|
|
10
|
-
--
|
|
11
|
-
--
|
|
12
|
-
--
|
|
13
|
-
--
|
|
14
|
-
--
|
|
15
|
-
--
|
|
16
|
-
--
|
|
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
|
|
17
20
|
|
|
18
21
|
Issue groups: files, dependencies, unlisted, exports, nsExports, types, nsTypes, duplicates
|
|
19
22
|
|
|
20
23
|
Examples:
|
|
21
24
|
|
|
22
25
|
$ knip
|
|
23
|
-
$ knip --
|
|
26
|
+
$ knip --dir packages/client --include files
|
|
24
27
|
$ knip -c ./knip.js --reporter compact --jsdoc public
|
|
28
|
+
$ knip --ignore 'lib/**/*.ts' --ignore build
|
|
25
29
|
|
|
26
30
|
More info: https://github.com/webpro/knip`);
|
|
27
31
|
};
|
package/dist/index.js
CHANGED
|
@@ -15,11 +15,11 @@ const lineRewriter = new log_1.LineRewriter();
|
|
|
15
15
|
async function run(configuration) {
|
|
16
16
|
const { workingDir, isShowProgress, report, isDev, jsDocOptions } = configuration;
|
|
17
17
|
const { getUnresolvedDependencies, getUnusedDependencies, getUnusedDevDependencies } = (0, dependencies_1.getDependencyAnalyzer)(configuration);
|
|
18
|
-
const production = await (0, project_1.createProject)(
|
|
18
|
+
const production = await (0, project_1.createProject)(configuration, configuration.entryFiles);
|
|
19
19
|
const entryFiles = production.getSourceFiles();
|
|
20
20
|
production.resolveSourceFileDependencies();
|
|
21
21
|
const productionFiles = production.getSourceFiles();
|
|
22
|
-
const project = await (0, project_1.createProject)(
|
|
22
|
+
const project = await (0, project_1.createProject)(configuration, configuration.projectFiles);
|
|
23
23
|
const projectFiles = project.getSourceFiles();
|
|
24
24
|
const [usedProductionFiles, unreferencedProductionFiles] = (0, project_1.partitionSourceFiles)(projectFiles, productionFiles);
|
|
25
25
|
const [usedEntryFiles, usedNonEntryFiles] = (0, project_1.partitionSourceFiles)(usedProductionFiles, entryFiles);
|
|
@@ -127,6 +127,8 @@ async function run(configuration) {
|
|
|
127
127
|
if (declaration.isKind(ts_morph_1.ts.SyntaxKind.Identifier)) {
|
|
128
128
|
identifier = declaration;
|
|
129
129
|
}
|
|
130
|
+
else if (declaration.isKind(ts_morph_1.ts.SyntaxKind.ArrowFunction)) {
|
|
131
|
+
}
|
|
130
132
|
else if (declaration.isKind(ts_morph_1.ts.SyntaxKind.FunctionDeclaration) ||
|
|
131
133
|
declaration.isKind(ts_morph_1.ts.SyntaxKind.ClassDeclaration) ||
|
|
132
134
|
declaration.isKind(ts_morph_1.ts.SyntaxKind.TypeAliasDeclaration) ||
|
|
@@ -156,7 +158,7 @@ async function run(configuration) {
|
|
|
156
158
|
}
|
|
157
159
|
else {
|
|
158
160
|
const refFiles = new Set(refs.map(r => r.compilerObject.references.map(r => r.fileName)).flat());
|
|
159
|
-
const isReferencedOnlyBySelf = refFiles.size === 1 && [...refFiles][0] ===
|
|
161
|
+
const isReferencedOnlyBySelf = refFiles.size === 1 && [...refFiles][0] === filePath;
|
|
160
162
|
if (!isReferencedOnlyBySelf)
|
|
161
163
|
return;
|
|
162
164
|
if ((0, ts_morph_helpers_1.findReferencingNamespaceNodes)(sourceFile).length > 0) {
|
|
@@ -39,7 +39,7 @@ exports.default = ({ issues, config, workingDir }) => {
|
|
|
39
39
|
}
|
|
40
40
|
if (report.dependencies && isDev) {
|
|
41
41
|
const unreferencedDevDependencies = Array.from(issues.devDependencies);
|
|
42
|
-
logIssueGroupResult(unreferencedDevDependencies, workingDir,
|
|
42
|
+
logIssueGroupResult(unreferencedDevDependencies, workingDir, 'UNUSED DEV DEPENDENCIES');
|
|
43
43
|
}
|
|
44
44
|
if (report.unlisted) {
|
|
45
45
|
const unreferencedDependencies = Object.values(issues.unresolved).map(issues => {
|
|
@@ -41,7 +41,7 @@ exports.default = ({ issues, config, workingDir }) => {
|
|
|
41
41
|
}
|
|
42
42
|
if (report.dependencies && isDev) {
|
|
43
43
|
const unreferencedDevDependencies = Array.from(issues.devDependencies);
|
|
44
|
-
logIssueGroupResult(unreferencedDevDependencies, workingDir,
|
|
44
|
+
logIssueGroupResult(unreferencedDevDependencies, workingDir, 'UNUSED DEV DEPENDENCIES');
|
|
45
45
|
}
|
|
46
46
|
if (report.unlisted) {
|
|
47
47
|
const unresolvedDependencies = Object.values(issues.unresolved).map(Object.values).flat();
|
package/dist/types.d.ts
CHANGED
|
@@ -20,12 +20,16 @@ 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
|
-
|
|
28
|
-
|
|
27
|
+
declare type BaseLocalConfiguration = {
|
|
28
|
+
entryFiles: string[];
|
|
29
|
+
projectFiles: string[];
|
|
30
|
+
};
|
|
31
|
+
export declare type LocalConfiguration = BaseLocalConfiguration & {
|
|
32
|
+
dev?: boolean | BaseLocalConfiguration;
|
|
29
33
|
entryFiles: string[];
|
|
30
34
|
projectFiles: string[];
|
|
31
35
|
include?: string[];
|
|
@@ -40,7 +44,9 @@ export declare type Configuration = LocalConfiguration & {
|
|
|
40
44
|
dependencies: string[];
|
|
41
45
|
devDependencies: string[];
|
|
42
46
|
isDev: boolean;
|
|
47
|
+
tsConfigFilePath: undefined | string;
|
|
43
48
|
tsConfigPaths: string[];
|
|
49
|
+
ignorePatterns: string[];
|
|
44
50
|
isShowProgress: boolean;
|
|
45
51
|
jsDocOptions: {
|
|
46
52
|
isReadPublicTag: boolean;
|
package/dist/util/config.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { ImportedConfiguration, LocalConfiguration } from '../types';
|
|
2
|
-
export declare const resolveConfig: (importedConfiguration: ImportedConfiguration,
|
|
2
|
+
export declare const resolveConfig: (importedConfiguration: ImportedConfiguration, options?: {
|
|
3
|
+
workingDir?: string;
|
|
4
|
+
isDev?: boolean;
|
|
5
|
+
}) => LocalConfiguration | undefined;
|
|
3
6
|
export declare const resolveIncludedIssueGroups: (includeArg: string[], excludeArg: string[], resolvedConfig?: LocalConfiguration) => {
|
|
4
7
|
files: boolean;
|
|
5
8
|
dependencies: boolean;
|
package/dist/util/config.js
CHANGED
|
@@ -5,20 +5,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.resolveIncludedIssueGroups = exports.resolveConfig = void 0;
|
|
7
7
|
const micromatch_1 = __importDefault(require("micromatch"));
|
|
8
|
-
const resolveConfig = (importedConfiguration,
|
|
8
|
+
const resolveConfig = (importedConfiguration, options) => {
|
|
9
|
+
let resolvedConfig = importedConfiguration;
|
|
10
|
+
const { workingDir, isDev } = options ?? {};
|
|
9
11
|
const configKeys = Object.keys(importedConfiguration);
|
|
10
|
-
if (
|
|
11
|
-
const importedConfigKey = configKeys.find(pattern => micromatch_1.default.isMatch(
|
|
12
|
+
if (workingDir && !('projectFiles' in importedConfiguration)) {
|
|
13
|
+
const importedConfigKey = configKeys.find(pattern => micromatch_1.default.isMatch(workingDir.replace(/\/$/, ''), pattern));
|
|
12
14
|
if (importedConfigKey) {
|
|
13
|
-
|
|
15
|
+
resolvedConfig = importedConfiguration[importedConfigKey];
|
|
14
16
|
}
|
|
15
17
|
}
|
|
16
|
-
if (
|
|
18
|
+
if (isDev && typeof resolvedConfig.dev === 'object' && 'projectFiles' in resolvedConfig.dev) {
|
|
19
|
+
resolvedConfig = resolvedConfig.dev;
|
|
20
|
+
}
|
|
21
|
+
if (!resolvedConfig.entryFiles || !resolvedConfig.projectFiles) {
|
|
17
22
|
console.error('Unable to find `entryFiles` and/or `projectFiles` in configuration.');
|
|
18
|
-
console.info(`Add
|
|
23
|
+
console.info(`Add these properties at root level, or use --cwd and match one of: ${configKeys.join(', ')}\n`);
|
|
19
24
|
return;
|
|
20
25
|
}
|
|
21
|
-
return
|
|
26
|
+
return resolvedConfig;
|
|
22
27
|
};
|
|
23
28
|
exports.resolveConfig = resolveConfig;
|
|
24
29
|
const resolveIncludedIssueGroups = (includeArg, excludeArg, resolvedConfig) => {
|
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,4 +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[]) => Promise<Project>;
|
|
4
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
5
|
const path_1 = require("./path");
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return '!' + node_path_1.default.join(cwd, pattern.slice(1));
|
|
14
|
-
return node_path_1.default.join(cwd, pattern);
|
|
15
|
-
});
|
|
16
|
-
};
|
|
17
|
-
const createProject = async (cwd, paths) => {
|
|
18
|
-
const tsConfigFilePath = await (0, path_1.findFile)(cwd, 'tsconfig.json');
|
|
6
|
+
const createProject = async (configuration, paths) => {
|
|
7
|
+
const { tsConfigFilePath, ignorePatterns } = configuration;
|
|
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;
|