knip 2.36.0 → 2.37.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 +1 -1
- package/dist/ProjectPrincipal.d.ts +6 -1
- package/dist/ProjectPrincipal.js +7 -5
- package/dist/index.js +27 -4
- package/dist/reporters/index.d.ts +1 -0
- package/dist/reporters/index.js +2 -0
- package/dist/reporters/jsonExt.d.ts +3 -0
- package/dist/reporters/jsonExt.js +73 -0
- package/dist/types/issues.d.ts +3 -0
- package/dist/typescript/ast-helpers.d.ts +1 -0
- package/dist/typescript/ast-helpers.js +3 -0
- package/dist/typescript/getImportsAndExports.js +2 -2
- package/dist/util/cli-arguments.d.ts +1 -1
- package/dist/util/cli-arguments.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -704,7 +704,7 @@ $ npx knip --help
|
|
|
704
704
|
-n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)
|
|
705
705
|
--preprocessor Preprocess the results before providing it to the reporter(s), can be repeated
|
|
706
706
|
--preprocessor-options Pass extra options to the preprocessor (as JSON string, see --reporter-options example)
|
|
707
|
-
--reporter Select reporter: symbols, compact, codeowners, json, can be repeated (default: symbols)
|
|
707
|
+
--reporter Select reporter: symbols, compact, codeowners, json, jsonExt, can be repeated (default: symbols)
|
|
708
708
|
--reporter-options Pass extra options to the reporter (as JSON string, see example)
|
|
709
709
|
--no-config-hints Suppress configuration hints
|
|
710
710
|
--no-exit-code Always exit with code zero (0)
|
|
@@ -58,7 +58,12 @@ export declare class ProjectPrincipal {
|
|
|
58
58
|
external: boolean;
|
|
59
59
|
internal: boolean;
|
|
60
60
|
};
|
|
61
|
-
findUnusedMembers(filePath: string, members: ExportItemMember[]):
|
|
61
|
+
findUnusedMembers(filePath: string, members: ExportItemMember[]): ExportItemMember[];
|
|
62
62
|
private findReferences;
|
|
63
|
+
getPos(node: ts.Node, pos: number): {
|
|
64
|
+
pos: number;
|
|
65
|
+
line: number;
|
|
66
|
+
col: number;
|
|
67
|
+
};
|
|
63
68
|
}
|
|
64
69
|
export {};
|
package/dist/ProjectPrincipal.js
CHANGED
|
@@ -2,7 +2,7 @@ import { isGitIgnoredSync } from 'globby';
|
|
|
2
2
|
import ts from 'typescript';
|
|
3
3
|
import { DEFAULT_EXTENSIONS } from './constants.js';
|
|
4
4
|
import { IGNORED_FILE_EXTENSIONS } from './constants.js';
|
|
5
|
-
import { getJSDocTags, isInModuleBlock } from './typescript/ast-helpers.js';
|
|
5
|
+
import { getJSDocTags, getLineAndCharacterOfPosition, isInModuleBlock } from './typescript/ast-helpers.js';
|
|
6
6
|
import { createHosts } from './typescript/createHosts.js';
|
|
7
7
|
import { getImportsAndExports } from './typescript/getImportsAndExports.js';
|
|
8
8
|
import { SourceFileManager } from './typescript/SourceFileManager.js';
|
|
@@ -176,8 +176,7 @@ export class ProjectPrincipal {
|
|
|
176
176
|
return hasReferences;
|
|
177
177
|
}
|
|
178
178
|
findUnusedMembers(filePath, members) {
|
|
179
|
-
return members
|
|
180
|
-
.filter(member => {
|
|
179
|
+
return members.filter(member => {
|
|
181
180
|
if (getJSDocTags(member.node).has('@public'))
|
|
182
181
|
return false;
|
|
183
182
|
const referencedSymbols = this.findReferences(filePath, member.pos);
|
|
@@ -188,8 +187,7 @@ export class ProjectPrincipal {
|
|
|
188
187
|
const internalRefs = files.filter(f => f === filePath);
|
|
189
188
|
const externalRefs = files.filter(f => f !== filePath);
|
|
190
189
|
return externalRefs.length === 0 && internalRefs.length === 0;
|
|
191
|
-
})
|
|
192
|
-
.map(member => member.identifier);
|
|
190
|
+
});
|
|
193
191
|
}
|
|
194
192
|
findReferences(filePath, pos) {
|
|
195
193
|
try {
|
|
@@ -199,4 +197,8 @@ export class ProjectPrincipal {
|
|
|
199
197
|
return [];
|
|
200
198
|
}
|
|
201
199
|
}
|
|
200
|
+
getPos(node, pos) {
|
|
201
|
+
const { line, character } = getLineAndCharacterOfPosition(node, pos);
|
|
202
|
+
return { pos, line: line + 1, col: character + 1 };
|
|
203
|
+
}
|
|
202
204
|
}
|
package/dist/index.js
CHANGED
|
@@ -304,12 +304,24 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
304
304
|
if (isProduction)
|
|
305
305
|
continue;
|
|
306
306
|
principal.findUnusedMembers(filePath, exportedItem.members).forEach(member => {
|
|
307
|
-
collector.addIssue({
|
|
307
|
+
collector.addIssue({
|
|
308
|
+
type: 'enumMembers',
|
|
309
|
+
filePath,
|
|
310
|
+
symbol: member.identifier,
|
|
311
|
+
parentSymbol: symbol,
|
|
312
|
+
...principal.getPos(member.node, member.pos),
|
|
313
|
+
});
|
|
308
314
|
});
|
|
309
315
|
}
|
|
310
316
|
if (report.classMembers && exportedItem.type === 'class' && exportedItem.members) {
|
|
311
317
|
principal.findUnusedMembers(filePath, exportedItem.members).forEach(member => {
|
|
312
|
-
collector.addIssue({
|
|
318
|
+
collector.addIssue({
|
|
319
|
+
type: 'classMembers',
|
|
320
|
+
filePath,
|
|
321
|
+
symbol: member.identifier,
|
|
322
|
+
parentSymbol: symbol,
|
|
323
|
+
...principal.getPos(member.node, member.pos),
|
|
324
|
+
});
|
|
313
325
|
});
|
|
314
326
|
}
|
|
315
327
|
continue;
|
|
@@ -321,11 +333,22 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
321
333
|
if (isProduction)
|
|
322
334
|
continue;
|
|
323
335
|
const type = isStar ? 'nsTypes' : 'types';
|
|
324
|
-
collector.addIssue({
|
|
336
|
+
collector.addIssue({
|
|
337
|
+
type,
|
|
338
|
+
filePath,
|
|
339
|
+
symbol,
|
|
340
|
+
symbolType: exportedItem.type,
|
|
341
|
+
...principal.getPos(exportedItem.node, exportedItem.pos),
|
|
342
|
+
});
|
|
325
343
|
}
|
|
326
344
|
else {
|
|
327
345
|
const type = isStar ? 'nsExports' : 'exports';
|
|
328
|
-
collector.addIssue({
|
|
346
|
+
collector.addIssue({
|
|
347
|
+
type,
|
|
348
|
+
filePath,
|
|
349
|
+
symbol,
|
|
350
|
+
...principal.getPos(exportedItem.node, exportedItem.pos),
|
|
351
|
+
});
|
|
329
352
|
}
|
|
330
353
|
}
|
|
331
354
|
}
|
|
@@ -3,5 +3,6 @@ declare const _default: {
|
|
|
3
3
|
compact: ({ report, issues, isShowProgress }: import("../index.js").ReporterOptions) => void;
|
|
4
4
|
codeowners: ({ report, issues, isShowProgress, options }: import("../index.js").ReporterOptions) => void;
|
|
5
5
|
json: ({ report, issues, options }: import("../index.js").ReporterOptions) => Promise<void>;
|
|
6
|
+
jsonExt: ({ report, issues, options }: import("../index.js").ReporterOptions) => Promise<void>;
|
|
6
7
|
};
|
|
7
8
|
export default _default;
|
package/dist/reporters/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import codeowners from './codeowners.js';
|
|
2
2
|
import compact from './compact.js';
|
|
3
3
|
import json from './json.js';
|
|
4
|
+
import jsonExt from './jsonExt.js';
|
|
4
5
|
import symbols from './symbols.js';
|
|
5
6
|
export default {
|
|
6
7
|
symbols,
|
|
7
8
|
compact,
|
|
8
9
|
codeowners,
|
|
9
10
|
json,
|
|
11
|
+
jsonExt,
|
|
10
12
|
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { OwnershipEngine } from '@snyk/github-codeowners/dist/lib/ownership/index.js';
|
|
2
|
+
import { isFile } from '../util/fs.js';
|
|
3
|
+
import { relative, resolve } from '../util/path.js';
|
|
4
|
+
const mergeTypes = (type) => type === 'exports' || type === 'nsExports' ? 'exports' : type === 'types' || type === 'nsTypes' ? 'types' : type;
|
|
5
|
+
export default async ({ report, issues, options }) => {
|
|
6
|
+
let opts = {};
|
|
7
|
+
try {
|
|
8
|
+
opts = options ? JSON.parse(options) : opts;
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
console.error(error);
|
|
12
|
+
}
|
|
13
|
+
const json = {};
|
|
14
|
+
const codeownersFilePath = resolve(opts.codeowners ?? '.github/CODEOWNERS');
|
|
15
|
+
const codeownersEngine = isFile(codeownersFilePath) && OwnershipEngine.FromCodeownersFile(codeownersFilePath);
|
|
16
|
+
const flatten = (issues) => Object.values(issues).flatMap(Object.values);
|
|
17
|
+
const initRow = (filePath) => {
|
|
18
|
+
const file = relative(filePath);
|
|
19
|
+
const row = {
|
|
20
|
+
file,
|
|
21
|
+
...(codeownersEngine && { owners: codeownersEngine.calcFileOwnership(file) }),
|
|
22
|
+
...(report.files && { files: false }),
|
|
23
|
+
...(report.dependencies && { dependencies: [] }),
|
|
24
|
+
...(report.devDependencies && { devDependencies: [] }),
|
|
25
|
+
...(report.optionalPeerDependencies && { optionalPeerDependencies: [] }),
|
|
26
|
+
...(report.unlisted && { unlisted: [] }),
|
|
27
|
+
...(report.binaries && { binaries: [] }),
|
|
28
|
+
...(report.unresolved && { unresolved: [] }),
|
|
29
|
+
...((report.exports || report.nsExports) && { exports: [] }),
|
|
30
|
+
...((report.types || report.nsTypes) && { types: [] }),
|
|
31
|
+
...(report.enumMembers && { enumMembers: {} }),
|
|
32
|
+
...(report.classMembers && { classMembers: {} }),
|
|
33
|
+
...(report.duplicates && { duplicates: [] }),
|
|
34
|
+
};
|
|
35
|
+
return row;
|
|
36
|
+
};
|
|
37
|
+
for (const [reportType, isReportType] of Object.entries(report)) {
|
|
38
|
+
if (isReportType) {
|
|
39
|
+
if (reportType === 'files') {
|
|
40
|
+
Array.from(issues[reportType]).forEach(filePath => {
|
|
41
|
+
json[filePath] = json[filePath] ?? initRow(filePath);
|
|
42
|
+
json[filePath][reportType] = true;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const type = mergeTypes(reportType);
|
|
47
|
+
flatten(issues[reportType]).forEach(issue => {
|
|
48
|
+
const { filePath, symbol, symbols, parentSymbol } = issue;
|
|
49
|
+
json[filePath] = json[filePath] ?? initRow(filePath);
|
|
50
|
+
if (type === 'duplicates') {
|
|
51
|
+
symbols && json[filePath][type]?.push(symbols.map(symbol => ({ name: symbol })));
|
|
52
|
+
}
|
|
53
|
+
else if (type === 'enumMembers' || type === 'classMembers') {
|
|
54
|
+
const item = json[filePath][type];
|
|
55
|
+
if (parentSymbol && item) {
|
|
56
|
+
item[parentSymbol] = item[parentSymbol] ?? [];
|
|
57
|
+
item[parentSymbol].push({ name: issue.symbol, line: issue.line, col: issue.col, pos: issue.pos });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
if (type === 'exports' || type === 'types') {
|
|
62
|
+
json[filePath][type]?.push({ name: issue.symbol, line: issue.line, col: issue.col, pos: issue.pos });
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
json[filePath][type]?.push({ name: symbol });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
console.log(JSON.stringify(Object.values(json)));
|
|
73
|
+
};
|
package/dist/types/issues.d.ts
CHANGED
|
@@ -15,6 +15,9 @@ export type Issue = {
|
|
|
15
15
|
symbolType?: SymbolType;
|
|
16
16
|
parentSymbol?: string;
|
|
17
17
|
severity?: IssueSeverity;
|
|
18
|
+
pos?: number;
|
|
19
|
+
line?: number;
|
|
20
|
+
col?: number;
|
|
18
21
|
};
|
|
19
22
|
export type IssueSet = Set<string>;
|
|
20
23
|
export type IssueRecords = Record<string, Record<string, Issue>>;
|
|
@@ -25,4 +25,5 @@ export declare function findDescendants<T>(node: ts.Node | undefined, callback:
|
|
|
25
25
|
export declare const isDeclarationFileExtension: (extension: string) => boolean;
|
|
26
26
|
export declare const isInModuleBlock: (node: ts.Node) => boolean;
|
|
27
27
|
export declare const getJSDocTags: (node: ts.Node) => Set<string>;
|
|
28
|
+
export declare const getLineAndCharacterOfPosition: (node: ts.Node, pos: number) => ts.LineAndCharacter;
|
|
28
29
|
export {};
|
|
@@ -95,10 +95,10 @@ export const getImportsAndExports = (sourceFile, options) => {
|
|
|
95
95
|
const item = exports.get(identifier);
|
|
96
96
|
const crew = [...item.members, ...members];
|
|
97
97
|
const tags = new Set([...item.jsDocTags, ...jsDocTags]);
|
|
98
|
-
exports.set(identifier, { ...item,
|
|
98
|
+
exports.set(identifier, { ...item, members: crew, jsDocTags: tags });
|
|
99
99
|
}
|
|
100
100
|
else {
|
|
101
|
-
exports.set(identifier, { node, type,
|
|
101
|
+
exports.set(identifier, { node, type, members, jsDocTags, pos });
|
|
102
102
|
}
|
|
103
103
|
if (!jsDocTags.has('@alias')) {
|
|
104
104
|
if (ts.isExportAssignment(node))
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const helpText = "\u2702\uFE0F Find unused files, dependencies and exports in your JavaScript and TypeScript projects\n\nUsage: knip [options]\n\nOptions:\n -c, --config [file] Configuration file path (default: [.]knip.json[c], knip.js, knip.ts or package.json#knip)\n -t, --tsConfig [file] TypeScript configuration path (default: tsconfig.json)\n --production Analyze only production source files (e.g. no tests, devDependencies, exported types)\n --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n --ignore-internal Ignore exports with tag @internal (JSDoc/TSDoc)\n -W, --workspace [dir] Analyze a single workspace (default: analyze all configured workspaces)\n --directory [dir] Run process from a different directory (default: cwd)\n --no-gitignore Don't use .gitignore\n --include Report only provided issue type(s), can be comma-separated or repeated (1)\n --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)\n --dependencies Shortcut for --include dependencies,unlisted,unresolved\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --include-entry-exports Include entry files when reporting unused exports\n -n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)\n --preprocessor Preprocess the results before providing it to the reporter(s), can be repeated\n --preprocessor-options Pass extra options to the preprocessor (as JSON string, see --reporter-options example)\n --reporter Select reporter: symbols, compact, codeowners, json, can be repeated (default: symbols)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --no-config-hints Suppress configuration hints\n --no-exit-code Always exit with code zero (0)\n --max-issues Maximum number of issues before non-zero exit code (default: 0)\n -d, --debug Show debug output\n --debug-file-filter Filter for files in debug output (regex as string)\n --performance Measure count and running time of expensive functions and display stats table\n -h, --help Print this help text\n -V, --version Print version\n\n(1) Issue types: files, dependencies, unlisted, unresolved, exports, nsExports, classMembers, types, nsTypes, enumMembers, duplicates\n\nExamples:\n\n$ knip\n$ knip --production\n$ knip --workspace packages/client --include files,dependencies\n$ knip -c ./config/knip.json --reporter compact\n$ knip --reporter codeowners --reporter-options '{\"path\":\".github/CODEOWNERS\"}'\n$ knip --debug --debug-file-filter '(specific|particular)-module'\n\nMore documentation and bug reports: https://github.com/webpro/knip";
|
|
1
|
+
export declare const helpText = "\u2702\uFE0F Find unused files, dependencies and exports in your JavaScript and TypeScript projects\n\nUsage: knip [options]\n\nOptions:\n -c, --config [file] Configuration file path (default: [.]knip.json[c], knip.js, knip.ts or package.json#knip)\n -t, --tsConfig [file] TypeScript configuration path (default: tsconfig.json)\n --production Analyze only production source files (e.g. no tests, devDependencies, exported types)\n --strict Consider only direct dependencies of workspace (not devDependencies, not other workspaces)\n --ignore-internal Ignore exports with tag @internal (JSDoc/TSDoc)\n -W, --workspace [dir] Analyze a single workspace (default: analyze all configured workspaces)\n --directory [dir] Run process from a different directory (default: cwd)\n --no-gitignore Don't use .gitignore\n --include Report only provided issue type(s), can be comma-separated or repeated (1)\n --exclude Exclude provided issue type(s) from report, can be comma-separated or repeated (1)\n --dependencies Shortcut for --include dependencies,unlisted,unresolved\n --exports Shortcut for --include exports,nsExports,classMembers,types,nsTypes,enumMembers,duplicates\n --include-entry-exports Include entry files when reporting unused exports\n -n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)\n --preprocessor Preprocess the results before providing it to the reporter(s), can be repeated\n --preprocessor-options Pass extra options to the preprocessor (as JSON string, see --reporter-options example)\n --reporter Select reporter: symbols, compact, codeowners, json, jsonExt, can be repeated (default: symbols)\n --reporter-options Pass extra options to the reporter (as JSON string, see example)\n --no-config-hints Suppress configuration hints\n --no-exit-code Always exit with code zero (0)\n --max-issues Maximum number of issues before non-zero exit code (default: 0)\n -d, --debug Show debug output\n --debug-file-filter Filter for files in debug output (regex as string)\n --performance Measure count and running time of expensive functions and display stats table\n -h, --help Print this help text\n -V, --version Print version\n\n(1) Issue types: files, dependencies, unlisted, unresolved, exports, nsExports, classMembers, types, nsTypes, enumMembers, duplicates\n\nExamples:\n\n$ knip\n$ knip --production\n$ knip --workspace packages/client --include files,dependencies\n$ knip -c ./config/knip.json --reporter compact\n$ knip --reporter codeowners --reporter-options '{\"path\":\".github/CODEOWNERS\"}'\n$ knip --debug --debug-file-filter '(specific|particular)-module'\n\nMore documentation and bug reports: https://github.com/webpro/knip";
|
|
2
2
|
declare const _default: {
|
|
3
3
|
config: string | undefined;
|
|
4
4
|
debug: boolean | undefined;
|
|
@@ -20,7 +20,7 @@ Options:
|
|
|
20
20
|
-n, --no-progress Don't show dynamic progress updates (automatically enabled in CI environments)
|
|
21
21
|
--preprocessor Preprocess the results before providing it to the reporter(s), can be repeated
|
|
22
22
|
--preprocessor-options Pass extra options to the preprocessor (as JSON string, see --reporter-options example)
|
|
23
|
-
--reporter Select reporter: symbols, compact, codeowners, json, can be repeated (default: symbols)
|
|
23
|
+
--reporter Select reporter: symbols, compact, codeowners, json, jsonExt, can be repeated (default: symbols)
|
|
24
24
|
--reporter-options Pass extra options to the reporter (as JSON string, see example)
|
|
25
25
|
--no-config-hints Suppress configuration hints
|
|
26
26
|
--no-exit-code Always exit with code zero (0)
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "2.
|
|
1
|
+
export declare const version = "2.37.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '2.
|
|
1
|
+
export const version = '2.37.0';
|
package/package.json
CHANGED