@kongyo2/ts-comment-scanner 0.0.0 → 1.0.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 +97 -17
- package/dist/args.d.ts +15 -1
- package/dist/args.d.ts.map +1 -1
- package/dist/args.js +146 -6
- package/dist/args.js.map +1 -1
- package/dist/directives.d.ts +12 -0
- package/dist/directives.d.ts.map +1 -0
- package/dist/directives.js +133 -0
- package/dist/directives.js.map +1 -0
- package/dist/files.d.ts +12 -0
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +84 -20
- package/dist/files.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/remove.d.ts +38 -0
- package/dist/remove.d.ts.map +1 -0
- package/dist/remove.js +223 -0
- package/dist/remove.js.map +1 -0
- package/dist/report.d.ts +8 -0
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +46 -12
- package/dist/report.js.map +1 -1
- package/dist/run.d.ts +1 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +156 -20
- package/dist/run.js.map +1 -1
- package/dist/scanner.d.ts.map +1 -1
- package/dist/scanner.js +31 -7
- package/dist/scanner.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -2
package/dist/run.js
CHANGED
|
@@ -1,42 +1,178 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { parseArgs, UsageError } from "./args.js";
|
|
3
|
+
import { collectFiles, isJsxFile, mapLimit, scanPaths, FILE_CONCURRENCY } from "./files.js";
|
|
4
|
+
import { removeComments } from "./remove.js";
|
|
5
|
+
import { count, formatGitHub, formatJson, formatText } from "./report.js";
|
|
4
6
|
import { getVersion } from "./version.js";
|
|
5
7
|
export const HELP_TEXT = `Usage: ts-comment-scanner [options] [paths...]
|
|
6
8
|
|
|
7
|
-
Detect and
|
|
9
|
+
Detect, report and clean up comments across a TypeScript project.
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
--
|
|
11
|
-
|
|
12
|
-
-h, --help Show this help
|
|
11
|
+
Output:
|
|
12
|
+
--format <fmt> Output format: text, json or github (default: text)
|
|
13
|
+
--json Shorthand for --format json
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
Filtering:
|
|
16
|
+
--ignore <glob> Skip files/directories matching the glob (repeatable)
|
|
17
|
+
--ext <list> Comma-separated extensions to scan (default: .ts,.tsx,.mts,.cts)
|
|
18
|
+
--skip-directives Hide compiler/linter directives (@ts-ignore, eslint-disable, ...)
|
|
19
|
+
--only-directives Report only compiler/linter directives
|
|
20
|
+
|
|
21
|
+
CI:
|
|
22
|
+
--fail-on-comment Exit with code 1 when any comment is reported
|
|
23
|
+
|
|
24
|
+
Removal:
|
|
25
|
+
--remove Delete the reported comments from the files (in place)
|
|
26
|
+
--dry-run With --remove: show what would be removed, change nothing
|
|
27
|
+
--remove-directives With --remove: also delete directive comments
|
|
28
|
+
--remove-legal With --remove: also delete license/legal comments
|
|
29
|
+
|
|
30
|
+
General:
|
|
31
|
+
-h, --help Show this help
|
|
32
|
+
-v, --version Print the version number
|
|
33
|
+
|
|
34
|
+
Paths default to the current directory. Directories are scanned recursively,
|
|
35
|
+
skipping node_modules and .git. Removal keeps directives and license headers
|
|
36
|
+
unless explicitly requested, so builds and linters keep working.
|
|
37
|
+
|
|
38
|
+
Exit codes: 0 success, 1 comments reported with --fail-on-comment, 2 error.
|
|
16
39
|
|
|
17
40
|
Examples:
|
|
18
41
|
ts-comment-scanner src
|
|
19
|
-
ts-comment-scanner --
|
|
42
|
+
ts-comment-scanner --format github --fail-on-comment src
|
|
43
|
+
ts-comment-scanner --ignore "**/*.test.ts" --skip-directives src
|
|
44
|
+
ts-comment-scanner --remove --dry-run src
|
|
20
45
|
`;
|
|
21
46
|
export async function run(argv, io) {
|
|
22
|
-
|
|
23
|
-
if (
|
|
47
|
+
// Help always wins, even on an otherwise-invalid command line.
|
|
48
|
+
if (wantsHelp(argv)) {
|
|
24
49
|
io.out(HELP_TEXT);
|
|
25
50
|
return 0;
|
|
26
51
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
52
|
+
let options;
|
|
53
|
+
try {
|
|
54
|
+
options = parseArgs(argv);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
if (error instanceof UsageError) {
|
|
58
|
+
io.err(`ts-comment-scanner: ${error.message}\nTry 'ts-comment-scanner --help' for usage.\n`);
|
|
59
|
+
return 2;
|
|
60
|
+
}
|
|
61
|
+
throw error;
|
|
30
62
|
}
|
|
31
63
|
try {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
64
|
+
if (options.version) {
|
|
65
|
+
io.out(`${await getVersion()}\n`);
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
const collectOptions = {
|
|
69
|
+
ignore: options.ignore,
|
|
70
|
+
...(options.extensions === undefined ? {} : { extensions: options.extensions }),
|
|
71
|
+
};
|
|
72
|
+
if (options.remove) {
|
|
73
|
+
return await runRemove(options, collectOptions, io);
|
|
74
|
+
}
|
|
75
|
+
const results = filterDirectives(await scanPaths(options.paths, collectOptions), options.directives);
|
|
76
|
+
io.out(`${render(results, options.format)}\n`);
|
|
77
|
+
const total = results.reduce((sum, result) => sum + result.comments.length, 0);
|
|
78
|
+
return options.failOnComment && total > 0 ? 1 : 0;
|
|
35
79
|
}
|
|
36
80
|
catch (error) {
|
|
37
81
|
const message = error instanceof Error ? error.message : String(error);
|
|
38
82
|
io.err(`ts-comment-scanner: ${message}\n`);
|
|
39
|
-
return
|
|
83
|
+
return 2;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** True when -h/--help appears before any `--` separator. */
|
|
87
|
+
function wantsHelp(argv) {
|
|
88
|
+
for (const arg of argv) {
|
|
89
|
+
if (arg === "--")
|
|
90
|
+
return false;
|
|
91
|
+
if (arg === "-h" || arg === "--help")
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
function render(results, format) {
|
|
97
|
+
if (format === "json")
|
|
98
|
+
return formatJson(results);
|
|
99
|
+
if (format === "github")
|
|
100
|
+
return formatGitHub(results);
|
|
101
|
+
return formatText(results);
|
|
102
|
+
}
|
|
103
|
+
function inScope(comment, mode) {
|
|
104
|
+
if (mode === "skip")
|
|
105
|
+
return comment.directive === undefined;
|
|
106
|
+
if (mode === "only")
|
|
107
|
+
return comment.directive !== undefined;
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
function filterDirectives(results, mode) {
|
|
111
|
+
if (mode === "include")
|
|
112
|
+
return results;
|
|
113
|
+
return results.map((result) => ({
|
|
114
|
+
file: result.file,
|
|
115
|
+
comments: result.comments.filter((comment) => inScope(comment, mode)),
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
async function runRemove(options, collectOptions, io) {
|
|
119
|
+
const files = await collectFiles(options.paths, collectOptions);
|
|
120
|
+
const outcomes = await mapLimit(files, FILE_CONCURRENCY, async (file) => {
|
|
121
|
+
try {
|
|
122
|
+
const source = await readFile(file, "utf8");
|
|
123
|
+
const result = removeComments(source, {
|
|
124
|
+
jsx: isJsxFile(file),
|
|
125
|
+
removeDirectives: options.removeDirectives,
|
|
126
|
+
removeLegal: options.removeLegal,
|
|
127
|
+
shouldRemove: (comment) => inScope(comment, options.directives),
|
|
128
|
+
});
|
|
129
|
+
if (result.changed && !options.dryRun) {
|
|
130
|
+
await writeFile(file, result.code, "utf8");
|
|
131
|
+
}
|
|
132
|
+
return { file, removed: result.removed, kept: result.kept };
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
136
|
+
return { file, failure: `${file}: ${message}` };
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
const removals = [];
|
|
140
|
+
const failures = [];
|
|
141
|
+
for (const outcome of outcomes) {
|
|
142
|
+
if ("failure" in outcome) {
|
|
143
|
+
failures.push(outcome.failure);
|
|
144
|
+
}
|
|
145
|
+
else if (outcome.removed.length > 0 || outcome.kept.length > 0) {
|
|
146
|
+
removals.push(outcome);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
io.out(`${renderRemoval(removals, options)}\n`);
|
|
150
|
+
for (const failure of failures) {
|
|
151
|
+
io.err(`ts-comment-scanner: ${failure}\n`);
|
|
152
|
+
}
|
|
153
|
+
return failures.length > 0 ? 2 : 0;
|
|
154
|
+
}
|
|
155
|
+
function renderRemoval(removals, options) {
|
|
156
|
+
const totalRemoved = removals.reduce((sum, entry) => sum + entry.removed.length, 0);
|
|
157
|
+
const totalKept = removals.reduce((sum, entry) => sum + entry.kept.length, 0);
|
|
158
|
+
const changedFiles = removals.filter((entry) => entry.removed.length > 0);
|
|
159
|
+
const keptNote = totalKept > 0 ? ` Kept ${count(totalKept, "protected comment")}.` : "";
|
|
160
|
+
if (options.format === "json") {
|
|
161
|
+
return JSON.stringify({
|
|
162
|
+
summary: { files: changedFiles.length, removed: totalRemoved, kept: totalKept, dryRun: options.dryRun },
|
|
163
|
+
files: removals,
|
|
164
|
+
}, null, 2);
|
|
165
|
+
}
|
|
166
|
+
if (totalRemoved === 0) {
|
|
167
|
+
return `No removable comments found.${keptNote}`;
|
|
40
168
|
}
|
|
169
|
+
const verb = options.dryRun ? "would remove" : "removed";
|
|
170
|
+
const lines = changedFiles.map((entry) => {
|
|
171
|
+
const kept = entry.kept.length > 0 ? ` (kept ${entry.kept.length})` : "";
|
|
172
|
+
return `${entry.file}: ${verb} ${entry.removed.length}${kept}`;
|
|
173
|
+
});
|
|
174
|
+
const sentenceVerb = verb.charAt(0).toUpperCase() + verb.slice(1);
|
|
175
|
+
lines.push("", `${sentenceVerb} ${count(totalRemoved, "comment")} across ${count(changedFiles.length, "file")}.${keptNote}`);
|
|
176
|
+
return lines.join("\n");
|
|
41
177
|
}
|
|
42
178
|
//# sourceMappingURL=run.js.map
|
package/dist/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
|
package/dist/scanner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAe,MAAM,YAAY,CAAC;AAEvD,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,EAAE,CA4EjF"}
|
package/dist/scanner.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
|
+
import { detectDirective } from "./directives.js";
|
|
2
3
|
export function scanComments(source, options = {}) {
|
|
3
|
-
const
|
|
4
|
-
const
|
|
4
|
+
const jsx = options.jsx === true;
|
|
5
|
+
const fileName = jsx ? "module.tsx" : "module.ts";
|
|
6
|
+
const scriptKind = jsx ? ts.ScriptKind.TSX : ts.ScriptKind.TS;
|
|
7
|
+
const sourceFile = ts.createSourceFile(fileName, source, ts.ScriptTarget.Latest, true, scriptKind);
|
|
5
8
|
const jsxTextSpans = [];
|
|
6
9
|
const ranges = [];
|
|
7
10
|
const seen = new Set();
|
|
@@ -16,7 +19,10 @@ export function scanComments(source, options = {}) {
|
|
|
16
19
|
}
|
|
17
20
|
};
|
|
18
21
|
const visit = (node) => {
|
|
19
|
-
|
|
22
|
+
// JSDoc nodes start inside the comment text itself; descending into them
|
|
23
|
+
// would hide the comment (e.g. a trailing JSDoc attached to the
|
|
24
|
+
// end-of-file token). Treat them as trivia like any other comment.
|
|
25
|
+
const children = node.getChildren(sourceFile).filter((child) => !ts.isJSDoc(child));
|
|
20
26
|
if (children.length === 0) {
|
|
21
27
|
if (node.kind === ts.SyntaxKind.JsxText) {
|
|
22
28
|
jsxTextSpans.push([node.getFullStart(), node.getEnd()]);
|
|
@@ -31,19 +37,37 @@ export function scanComments(source, options = {}) {
|
|
|
31
37
|
};
|
|
32
38
|
visit(sourceFile);
|
|
33
39
|
const insideJsxText = (pos) => jsxTextSpans.some(([start, end]) => pos >= start && pos < end);
|
|
40
|
+
// File-wide pragmas (check pragmas, triple-slash directives, docblock
|
|
41
|
+
// test-environment pragmas, Deno's *-ignore-file forms) only count before
|
|
42
|
+
// the first token; anywhere later the tools treat them as ordinary text.
|
|
43
|
+
const firstTokenStart = sourceFile.getStart(sourceFile);
|
|
44
|
+
const isHeaderOnlyDirective = (directive) => directive === "@ts-nocheck" ||
|
|
45
|
+
directive === "@ts-check" ||
|
|
46
|
+
directive === "@jest-environment" ||
|
|
47
|
+
directive === "@vitest-environment" ||
|
|
48
|
+
directive.endsWith("-ignore-file") ||
|
|
49
|
+
directive.startsWith("triple-slash-");
|
|
50
|
+
const isActiveDirective = (directive, pos) => !isHeaderOnlyDirective(directive) || pos < firstTokenStart;
|
|
34
51
|
return ranges
|
|
35
52
|
.filter((range) => !insideJsxText(range.pos))
|
|
36
53
|
.sort((a, b) => a.pos - b.pos)
|
|
37
54
|
.map((range) => {
|
|
38
55
|
const kind = range.kind === ts.SyntaxKind.SingleLineCommentTrivia ? "line" : "block";
|
|
39
|
-
const
|
|
56
|
+
const text = source.slice(range.pos, range.end);
|
|
57
|
+
const startPosition = sourceFile.getLineAndCharacterOfPosition(range.pos);
|
|
58
|
+
const endPosition = sourceFile.getLineAndCharacterOfPosition(range.end);
|
|
59
|
+
const detected = detectDirective(kind, text);
|
|
60
|
+
const directive = detected !== undefined && isActiveDirective(detected, range.pos) ? detected : undefined;
|
|
40
61
|
return {
|
|
41
62
|
kind,
|
|
42
|
-
text
|
|
63
|
+
text,
|
|
43
64
|
start: range.pos,
|
|
44
65
|
end: range.end,
|
|
45
|
-
line:
|
|
46
|
-
column:
|
|
66
|
+
line: startPosition.line + 1,
|
|
67
|
+
column: startPosition.character + 1,
|
|
68
|
+
endLine: endPosition.line + 1,
|
|
69
|
+
endColumn: endPosition.character + 1,
|
|
70
|
+
...(directive === undefined ? {} : { directive }),
|
|
47
71
|
};
|
|
48
72
|
});
|
|
49
73
|
}
|
package/dist/scanner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -6,6 +6,10 @@ export interface Comment {
|
|
|
6
6
|
end: number;
|
|
7
7
|
line: number;
|
|
8
8
|
column: number;
|
|
9
|
+
endLine: number;
|
|
10
|
+
endColumn: number;
|
|
11
|
+
/** Canonical name of the compiler/linter directive this comment represents, if any. */
|
|
12
|
+
directive?: string;
|
|
9
13
|
}
|
|
10
14
|
export interface FileScanResult {
|
|
11
15
|
file: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3C,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3C,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kongyo2/ts-comment-scanner",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "CLI to detect and
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI to detect, report and safely remove comments across a TypeScript project.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
7
7
|
"comments",
|
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
"scanner",
|
|
11
11
|
"ast",
|
|
12
12
|
"code-analysis",
|
|
13
|
+
"comment-removal",
|
|
14
|
+
"code-cleanup",
|
|
15
|
+
"github-actions",
|
|
13
16
|
"kongyo2"
|
|
14
17
|
],
|
|
15
18
|
"license": "MIT",
|
|
@@ -57,10 +60,12 @@
|
|
|
57
60
|
"access": "public"
|
|
58
61
|
},
|
|
59
62
|
"dependencies": {
|
|
63
|
+
"picomatch": "^4.0.4",
|
|
60
64
|
"typescript": "^6.0.3"
|
|
61
65
|
},
|
|
62
66
|
"devDependencies": {
|
|
63
67
|
"@types/node": "^25.9.3",
|
|
68
|
+
"@types/picomatch": "^4.0.3",
|
|
64
69
|
"oxlint": "^1.70.0",
|
|
65
70
|
"prettier": "^3.8.4",
|
|
66
71
|
"vitest": "^4.1.9"
|