jsdoczoom 0.3.1 → 0.4.5
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/dist/cache.js +97 -0
- package/dist/cli.js +183 -110
- package/dist/drilldown.js +163 -53
- package/dist/file-discovery.js +1 -2
- package/dist/index.js +7 -5
- package/dist/lint.js +30 -12
- package/dist/skill-text.js +7 -6
- package/dist/types.js +4 -0
- package/dist/validate.js +29 -11
- package/package.json +6 -2
- package/types/cache.d.ts +74 -0
- package/types/drilldown.d.ts +5 -3
- package/types/file-discovery.d.ts +14 -0
- package/types/index.d.ts +9 -4
- package/types/lint.d.ts +5 -1
- package/types/skill-text.d.ts +1 -1
- package/types/types.d.ts +9 -0
- package/types/validate.d.ts +6 -1
package/dist/cache.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content-hash-based disk caching layer for expensive operations (TypeScript
|
|
3
|
+
* compilation, ESLint linting, JSDoc parsing). Uses SHA-256 hashing to cache
|
|
4
|
+
* results keyed by file content, enabling near-instantaneous repeated runs
|
|
5
|
+
* when files haven't changed. All cache errors degrade gracefully without
|
|
6
|
+
* propagating to callers.
|
|
7
|
+
*
|
|
8
|
+
* @summary Content-hash-based disk cache with graceful error handling
|
|
9
|
+
*/
|
|
10
|
+
import { createHash } from "node:crypto";
|
|
11
|
+
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
/**
|
|
14
|
+
* Compute a SHA-256 content hash for the given string.
|
|
15
|
+
*
|
|
16
|
+
* @param content - The content to hash
|
|
17
|
+
* @returns Hex-encoded SHA-256 digest
|
|
18
|
+
*/
|
|
19
|
+
export function computeContentHash(content) {
|
|
20
|
+
return createHash("sha256").update(content).digest("hex");
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Ensure the cache directory exists for the given operation mode.
|
|
24
|
+
* Silently swallows all errors (mkdir failures are handled by read/write ops).
|
|
25
|
+
*
|
|
26
|
+
* @param config - Cache configuration
|
|
27
|
+
* @param mode - Operation mode (drilldown, validate, or lint)
|
|
28
|
+
*/
|
|
29
|
+
export async function ensureCacheDir(config, mode) {
|
|
30
|
+
try {
|
|
31
|
+
await mkdir(join(config.directory, mode), { recursive: true });
|
|
32
|
+
} catch {
|
|
33
|
+
// Silently swallow - subsequent reads will miss, writes will fail silently
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Read a cached entry from disk. Returns null on any error (cache miss, ENOENT,
|
|
38
|
+
* corrupted JSON, permission denied, etc.). Never throws.
|
|
39
|
+
*
|
|
40
|
+
* @param config - Cache configuration
|
|
41
|
+
* @param mode - Operation mode namespace
|
|
42
|
+
* @param hash - Content hash key
|
|
43
|
+
* @returns Parsed cached data or null on any error
|
|
44
|
+
*/
|
|
45
|
+
export async function readCacheEntry(config, mode, hash) {
|
|
46
|
+
try {
|
|
47
|
+
const filePath = join(config.directory, mode, `${hash}.json`);
|
|
48
|
+
const content = await readFile(filePath, "utf-8");
|
|
49
|
+
return JSON.parse(content);
|
|
50
|
+
} catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Write a cache entry to disk using atomic write (write to .tmp then rename).
|
|
56
|
+
* Silently swallows all errors (permission denied, disk full, etc.). Never throws.
|
|
57
|
+
*
|
|
58
|
+
* @param config - Cache configuration
|
|
59
|
+
* @param mode - Operation mode namespace
|
|
60
|
+
* @param hash - Content hash key
|
|
61
|
+
* @param data - Data to cache (must be JSON-serializable)
|
|
62
|
+
*/
|
|
63
|
+
export async function writeCacheEntry(config, mode, hash, data) {
|
|
64
|
+
try {
|
|
65
|
+
const filePath = join(config.directory, mode, `${hash}.json`);
|
|
66
|
+
const tmpPath = `${filePath}.tmp`;
|
|
67
|
+
await writeFile(tmpPath, JSON.stringify(data), "utf-8");
|
|
68
|
+
await rename(tmpPath, filePath);
|
|
69
|
+
} catch {
|
|
70
|
+
// Silently swallow - cache write failures should never affect correctness
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Execute a computation with caching. If cache is enabled and entry exists,
|
|
75
|
+
* returns cached result. Otherwise, computes result, stores it (fire-and-forget),
|
|
76
|
+
* and returns it. Degrades gracefully on all cache errors by always computing.
|
|
77
|
+
*
|
|
78
|
+
* @param config - Cache configuration
|
|
79
|
+
* @param mode - Operation mode namespace
|
|
80
|
+
* @param content - File content to hash for cache key
|
|
81
|
+
* @param compute - Function to compute the result on cache miss
|
|
82
|
+
* @returns Cached or computed result
|
|
83
|
+
*/
|
|
84
|
+
export async function processWithCache(config, mode, content, compute) {
|
|
85
|
+
if (!config.enabled) {
|
|
86
|
+
return await compute();
|
|
87
|
+
}
|
|
88
|
+
const hash = computeContentHash(content);
|
|
89
|
+
await ensureCacheDir(config, mode);
|
|
90
|
+
const cached = await readCacheEntry(config, mode, hash);
|
|
91
|
+
if (cached !== null) {
|
|
92
|
+
return cached;
|
|
93
|
+
}
|
|
94
|
+
const result = await compute();
|
|
95
|
+
await writeCacheEntry(config, mode, hash, result);
|
|
96
|
+
return result;
|
|
97
|
+
}
|
package/dist/cli.js
CHANGED
|
@@ -4,11 +4,11 @@ import { dirname, resolve } from "node:path";
|
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { drilldown, drilldownFiles } from "./drilldown.js";
|
|
6
6
|
import { JsdocError } from "./errors.js";
|
|
7
|
-
import { lint } from "./lint.js";
|
|
7
|
+
import { lint, lintFiles } from "./lint.js";
|
|
8
8
|
import { parseSelector } from "./selector.js";
|
|
9
9
|
import { RULE_EXPLANATIONS, SKILL_TEXT } from "./skill-text.js";
|
|
10
|
-
import { VALIDATION_STATUS_PRIORITY } from "./types.js";
|
|
11
|
-
import { validate } from "./validate.js";
|
|
10
|
+
import { DEFAULT_CACHE_DIR, VALIDATION_STATUS_PRIORITY } from "./types.js";
|
|
11
|
+
import { validate, validateFiles } from "./validate.js";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Parses argv flags (--help, --version, --check, --lint, --skill, --pretty,
|
|
@@ -33,6 +33,8 @@ Options:
|
|
|
33
33
|
--pretty Format JSON output with 2-space indent
|
|
34
34
|
--limit N Max results shown (default 500)
|
|
35
35
|
--no-gitignore Include files ignored by .gitignore
|
|
36
|
+
--disable-cache Skip all cache operations
|
|
37
|
+
--cache-directory Override cache directory (default: system temp)
|
|
36
38
|
--explain-rule R Explain a lint rule with examples (e.g. jsdoc/informative-docs)
|
|
37
39
|
|
|
38
40
|
Selector:
|
|
@@ -53,8 +55,10 @@ Output:
|
|
|
53
55
|
selector. Items with "id" (no next_id) are at terminal depth.
|
|
54
56
|
|
|
55
57
|
Barrel gating (glob mode):
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
A barrel's @summary and description reflect the cumulative functionality
|
|
59
|
+
of its directory's children, not the barrel file itself. Barrels with a
|
|
60
|
+
@summary gate sibling files at depths 1-2. At depth 3 the barrel
|
|
61
|
+
disappears and its children appear at depth 1.
|
|
58
62
|
|
|
59
63
|
Modes:
|
|
60
64
|
-c Validate file-level structure (has JSDoc block, @summary, description)
|
|
@@ -76,60 +80,95 @@ Workflow:
|
|
|
76
80
|
{ "items": [{ "id": "src/utils@3", "text": "..." }] }
|
|
77
81
|
# "id" instead of "next_id" means terminal depth — stop here
|
|
78
82
|
`;
|
|
83
|
+
/**
|
|
84
|
+
* Parse a flag that requires a value argument.
|
|
85
|
+
* @returns Updated index after consuming the value
|
|
86
|
+
*/
|
|
87
|
+
function parseValueFlag(args, index) {
|
|
88
|
+
return { value: args[index + 1], nextIndex: index + 1 };
|
|
89
|
+
}
|
|
79
90
|
/**
|
|
80
91
|
* Parse CLI arguments into flags and positional args.
|
|
81
92
|
*/
|
|
82
93
|
function parseArgs(args) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
94
|
+
const parsed = {
|
|
95
|
+
help: false,
|
|
96
|
+
version: false,
|
|
97
|
+
checkMode: false,
|
|
98
|
+
lintMode: false,
|
|
99
|
+
skillMode: false,
|
|
100
|
+
pretty: false,
|
|
101
|
+
limit: 500,
|
|
102
|
+
gitignore: true,
|
|
103
|
+
disableCache: false,
|
|
104
|
+
cacheDirectory: undefined,
|
|
105
|
+
explainRule: undefined,
|
|
106
|
+
selectorArg: undefined,
|
|
107
|
+
};
|
|
93
108
|
for (let i = 0; i < args.length; i++) {
|
|
94
109
|
const arg = args[i];
|
|
110
|
+
// Boolean flags
|
|
95
111
|
if (arg === "-h" || arg === "--help") {
|
|
96
|
-
help = true;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
parsed.help = true;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (arg === "-v" || arg === "--version") {
|
|
116
|
+
parsed.version = true;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (arg === "-c" || arg === "--check") {
|
|
120
|
+
parsed.checkMode = true;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (arg === "-l" || arg === "--lint") {
|
|
124
|
+
parsed.lintMode = true;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (arg === "-s" || arg === "--skill") {
|
|
128
|
+
parsed.skillMode = true;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (arg === "--pretty") {
|
|
132
|
+
parsed.pretty = true;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (arg === "--no-gitignore") {
|
|
136
|
+
parsed.gitignore = false;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (arg === "--disable-cache") {
|
|
140
|
+
parsed.disableCache = true;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
// Value flags
|
|
144
|
+
if (arg === "--limit") {
|
|
145
|
+
const { value, nextIndex } = parseValueFlag(args, i);
|
|
146
|
+
parsed.limit = Number(value);
|
|
147
|
+
i = nextIndex;
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (arg === "--cache-directory") {
|
|
151
|
+
const { value, nextIndex } = parseValueFlag(args, i);
|
|
152
|
+
parsed.cacheDirectory = value;
|
|
153
|
+
i = nextIndex;
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
if (arg === "--explain-rule") {
|
|
157
|
+
const { value, nextIndex } = parseValueFlag(args, i);
|
|
158
|
+
parsed.explainRule = value;
|
|
159
|
+
i = nextIndex;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
// Unknown flag or positional arg
|
|
163
|
+
if (arg.startsWith("-")) {
|
|
116
164
|
throw new JsdocError("INVALID_SELECTOR", `Unrecognized option: ${arg}`);
|
|
117
|
-
}
|
|
118
|
-
|
|
165
|
+
}
|
|
166
|
+
// Positional selector arg
|
|
167
|
+
if (parsed.selectorArg === undefined) {
|
|
168
|
+
parsed.selectorArg = arg;
|
|
119
169
|
}
|
|
120
170
|
}
|
|
121
|
-
return
|
|
122
|
-
help,
|
|
123
|
-
version,
|
|
124
|
-
checkMode,
|
|
125
|
-
lintMode,
|
|
126
|
-
skillMode,
|
|
127
|
-
pretty,
|
|
128
|
-
limit,
|
|
129
|
-
gitignore,
|
|
130
|
-
explainRule,
|
|
131
|
-
selectorArg,
|
|
132
|
-
};
|
|
171
|
+
return parsed;
|
|
133
172
|
}
|
|
134
173
|
/**
|
|
135
174
|
* Resolve stdin file paths to absolute paths.
|
|
@@ -160,20 +199,25 @@ async function processStdin(
|
|
|
160
199
|
pretty,
|
|
161
200
|
limit,
|
|
162
201
|
cwd,
|
|
202
|
+
cacheConfig,
|
|
163
203
|
) {
|
|
164
204
|
const stdinPaths = parseStdinPaths(stdin, cwd);
|
|
165
205
|
const depth =
|
|
166
206
|
selectorArg !== undefined ? extractDepthFromArg(selectorArg) : undefined;
|
|
167
207
|
if (lintMode) {
|
|
168
|
-
const
|
|
169
|
-
const result = await lintFiles(stdinPaths, cwd, limit);
|
|
208
|
+
const result = await lintFiles(stdinPaths, cwd, limit, cacheConfig);
|
|
170
209
|
writeLintResult(result, pretty);
|
|
171
210
|
} else if (checkMode) {
|
|
172
|
-
const
|
|
173
|
-
const result = await validateFiles(stdinPaths, cwd, limit);
|
|
211
|
+
const result = await validateFiles(stdinPaths, cwd, limit, cacheConfig);
|
|
174
212
|
writeValidationResult(result, pretty);
|
|
175
213
|
} else {
|
|
176
|
-
const result = drilldownFiles(
|
|
214
|
+
const result = await drilldownFiles(
|
|
215
|
+
stdinPaths,
|
|
216
|
+
depth,
|
|
217
|
+
cwd,
|
|
218
|
+
limit,
|
|
219
|
+
cacheConfig,
|
|
220
|
+
);
|
|
177
221
|
writeResult(result, pretty);
|
|
178
222
|
}
|
|
179
223
|
}
|
|
@@ -188,18 +232,25 @@ async function processSelector(
|
|
|
188
232
|
limit,
|
|
189
233
|
gitignore,
|
|
190
234
|
cwd,
|
|
235
|
+
cacheConfig,
|
|
191
236
|
) {
|
|
192
237
|
const selector = selectorArg
|
|
193
238
|
? parseSelector(selectorArg)
|
|
194
239
|
: { type: "glob", pattern: "**/*.{ts,tsx}", depth: undefined };
|
|
195
240
|
if (lintMode) {
|
|
196
|
-
const result = await lint(selector, cwd, limit, gitignore);
|
|
241
|
+
const result = await lint(selector, cwd, limit, gitignore, cacheConfig);
|
|
197
242
|
writeLintResult(result, pretty);
|
|
198
243
|
} else if (checkMode) {
|
|
199
|
-
const result = await validate(selector, cwd, limit, gitignore);
|
|
244
|
+
const result = await validate(selector, cwd, limit, gitignore, cacheConfig);
|
|
200
245
|
writeValidationResult(result, pretty);
|
|
201
246
|
} else {
|
|
202
|
-
const result = drilldown(
|
|
247
|
+
const result = await drilldown(
|
|
248
|
+
selector,
|
|
249
|
+
cwd,
|
|
250
|
+
gitignore,
|
|
251
|
+
limit,
|
|
252
|
+
cacheConfig,
|
|
253
|
+
);
|
|
203
254
|
writeResult(result, pretty);
|
|
204
255
|
}
|
|
205
256
|
}
|
|
@@ -208,92 +259,114 @@ async function processSelector(
|
|
|
208
259
|
*/
|
|
209
260
|
function writeError(error) {
|
|
210
261
|
if (error instanceof JsdocError) {
|
|
211
|
-
process.stderr.write(`${JSON.stringify(error.toJSON())}\n`);
|
|
262
|
+
void process.stderr.write(`${JSON.stringify(error.toJSON())}\n`);
|
|
212
263
|
process.exitCode = 1;
|
|
213
264
|
return;
|
|
214
265
|
}
|
|
215
266
|
const message = error instanceof Error ? error.message : String(error);
|
|
216
|
-
process.stderr.write(
|
|
267
|
+
void process.stderr.write(
|
|
217
268
|
`${JSON.stringify({ error: { code: "INTERNAL_ERROR", message } })}\n`,
|
|
218
269
|
);
|
|
219
270
|
process.exitCode = 1;
|
|
220
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Handle --help flag by printing help text.
|
|
274
|
+
*/
|
|
275
|
+
function handleHelp() {
|
|
276
|
+
void process.stdout.write(HELP_TEXT);
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Handle --version flag by reading and printing version from package.json.
|
|
280
|
+
*/
|
|
281
|
+
function handleVersion() {
|
|
282
|
+
const pkgPath = resolve(
|
|
283
|
+
dirname(fileURLToPath(import.meta.url)),
|
|
284
|
+
"..",
|
|
285
|
+
"package.json",
|
|
286
|
+
);
|
|
287
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
288
|
+
void process.stdout.write(`${pkg.version}\n`);
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Handle --skill flag by printing JSDoc writing guidelines.
|
|
292
|
+
*/
|
|
293
|
+
function handleSkill() {
|
|
294
|
+
void process.stdout.write(SKILL_TEXT);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Handle --explain-rule flag by printing rule explanation.
|
|
298
|
+
*/
|
|
299
|
+
function handleExplainRule(ruleName) {
|
|
300
|
+
const explanation = RULE_EXPLANATIONS[ruleName];
|
|
301
|
+
if (explanation) {
|
|
302
|
+
void process.stdout.write(explanation);
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const available = Object.keys(RULE_EXPLANATIONS).join(", ");
|
|
306
|
+
writeError(
|
|
307
|
+
new JsdocError(
|
|
308
|
+
"INVALID_SELECTOR",
|
|
309
|
+
`Unknown rule: ${ruleName}. Available rules: ${available}`,
|
|
310
|
+
),
|
|
311
|
+
);
|
|
312
|
+
}
|
|
221
313
|
/**
|
|
222
314
|
* Main CLI entry point. Exported for testability.
|
|
223
315
|
*/
|
|
224
316
|
export async function main(args, stdin) {
|
|
225
317
|
try {
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
lintMode,
|
|
231
|
-
skillMode,
|
|
232
|
-
pretty,
|
|
233
|
-
limit,
|
|
234
|
-
gitignore,
|
|
235
|
-
explainRule,
|
|
236
|
-
selectorArg,
|
|
237
|
-
} = parseArgs(args);
|
|
238
|
-
if (help) {
|
|
239
|
-
process.stdout.write(HELP_TEXT);
|
|
318
|
+
const parsed = parseArgs(args);
|
|
319
|
+
// Handle early-exit flags
|
|
320
|
+
if (parsed.help) {
|
|
321
|
+
handleHelp();
|
|
240
322
|
return;
|
|
241
323
|
}
|
|
242
|
-
if (version) {
|
|
243
|
-
|
|
244
|
-
dirname(fileURLToPath(import.meta.url)),
|
|
245
|
-
"..",
|
|
246
|
-
"package.json",
|
|
247
|
-
);
|
|
248
|
-
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
249
|
-
process.stdout.write(`${pkg.version}\n`);
|
|
324
|
+
if (parsed.version) {
|
|
325
|
+
handleVersion();
|
|
250
326
|
return;
|
|
251
327
|
}
|
|
252
|
-
if (skillMode) {
|
|
253
|
-
|
|
328
|
+
if (parsed.skillMode) {
|
|
329
|
+
handleSkill();
|
|
254
330
|
return;
|
|
255
331
|
}
|
|
256
|
-
if (explainRule !== undefined) {
|
|
257
|
-
|
|
258
|
-
if (explanation) {
|
|
259
|
-
process.stdout.write(explanation);
|
|
260
|
-
} else {
|
|
261
|
-
const available = Object.keys(RULE_EXPLANATIONS).join(", ");
|
|
262
|
-
writeError(
|
|
263
|
-
new JsdocError(
|
|
264
|
-
"INVALID_SELECTOR",
|
|
265
|
-
`Unknown rule: ${explainRule}. Available rules: ${available}`,
|
|
266
|
-
),
|
|
267
|
-
);
|
|
268
|
-
}
|
|
332
|
+
if (parsed.explainRule !== undefined) {
|
|
333
|
+
handleExplainRule(parsed.explainRule);
|
|
269
334
|
return;
|
|
270
335
|
}
|
|
271
|
-
|
|
336
|
+
// Validate mode combinations
|
|
337
|
+
if (parsed.checkMode && parsed.lintMode) {
|
|
272
338
|
writeError(
|
|
273
339
|
new JsdocError("INVALID_SELECTOR", "Cannot use -c and -l together"),
|
|
274
340
|
);
|
|
275
341
|
return;
|
|
276
342
|
}
|
|
343
|
+
// Build cache config and process files
|
|
344
|
+
const cacheConfig = {
|
|
345
|
+
enabled: !parsed.disableCache,
|
|
346
|
+
directory: parsed.cacheDirectory ?? DEFAULT_CACHE_DIR,
|
|
347
|
+
};
|
|
277
348
|
const cwd = process.cwd();
|
|
278
349
|
if (stdin !== undefined) {
|
|
279
350
|
await processStdin(
|
|
280
351
|
stdin,
|
|
281
|
-
selectorArg,
|
|
282
|
-
checkMode,
|
|
283
|
-
lintMode,
|
|
284
|
-
pretty,
|
|
285
|
-
limit,
|
|
352
|
+
parsed.selectorArg,
|
|
353
|
+
parsed.checkMode,
|
|
354
|
+
parsed.lintMode,
|
|
355
|
+
parsed.pretty,
|
|
356
|
+
parsed.limit,
|
|
286
357
|
cwd,
|
|
358
|
+
cacheConfig,
|
|
287
359
|
);
|
|
288
360
|
} else {
|
|
289
361
|
await processSelector(
|
|
290
|
-
selectorArg,
|
|
291
|
-
checkMode,
|
|
292
|
-
lintMode,
|
|
293
|
-
pretty,
|
|
294
|
-
limit,
|
|
295
|
-
gitignore,
|
|
362
|
+
parsed.selectorArg,
|
|
363
|
+
parsed.checkMode,
|
|
364
|
+
parsed.lintMode,
|
|
365
|
+
parsed.pretty,
|
|
366
|
+
parsed.limit,
|
|
367
|
+
parsed.gitignore,
|
|
296
368
|
cwd,
|
|
369
|
+
cacheConfig,
|
|
297
370
|
);
|
|
298
371
|
}
|
|
299
372
|
} catch (error) {
|
|
@@ -307,7 +380,7 @@ function writeResult(result, pretty) {
|
|
|
307
380
|
const json = pretty
|
|
308
381
|
? JSON.stringify(result, null, 2)
|
|
309
382
|
: JSON.stringify(result);
|
|
310
|
-
process.stdout.write(`${json}\n`);
|
|
383
|
+
void process.stdout.write(`${json}\n`);
|
|
311
384
|
}
|
|
312
385
|
/**
|
|
313
386
|
* Count invalid files across all validation groups.
|
|
@@ -353,7 +426,7 @@ function writeLintResult(result, pretty) {
|
|
|
353
426
|
process.exitCode = 2;
|
|
354
427
|
// Warn if output was truncated
|
|
355
428
|
if (result.summary.filesWithIssues > result.files.length) {
|
|
356
|
-
process.stderr.write(
|
|
429
|
+
void process.stderr.write(
|
|
357
430
|
`Warning: output truncated to ${result.files.length} of ${result.summary.filesWithIssues} files with issues. Use --limit to see more.\n`,
|
|
358
431
|
);
|
|
359
432
|
}
|