jsdoczoom 1.2.0 → 1.2.1
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/cli.js +90 -23
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -4,6 +4,7 @@ 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 { discoverFiles } from "./file-discovery.js";
|
|
7
8
|
import { lint, lintFiles } from "./lint.js";
|
|
8
9
|
import { search, searchFiles } from "./search.js";
|
|
9
10
|
import { parseSelector } from "./selector.js";
|
|
@@ -113,6 +114,7 @@ function parseArgs(args) {
|
|
|
113
114
|
cacheDirectory: undefined,
|
|
114
115
|
explainRule: undefined,
|
|
115
116
|
selectorArg: undefined,
|
|
117
|
+
extraArgs: [],
|
|
116
118
|
searchQuery: undefined,
|
|
117
119
|
};
|
|
118
120
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -189,6 +191,8 @@ function parseArgs(args) {
|
|
|
189
191
|
// Positional selector arg
|
|
190
192
|
if (parsed.selectorArg === undefined) {
|
|
191
193
|
parsed.selectorArg = arg;
|
|
194
|
+
} else {
|
|
195
|
+
parsed.extraArgs.push(arg);
|
|
192
196
|
}
|
|
193
197
|
}
|
|
194
198
|
return parsed;
|
|
@@ -212,10 +216,10 @@ function extractDepthFromArg(selectorArg) {
|
|
|
212
216
|
return parsed.depth;
|
|
213
217
|
}
|
|
214
218
|
/**
|
|
215
|
-
* Process
|
|
219
|
+
* Process an explicit list of resolved file paths.
|
|
216
220
|
*/
|
|
217
|
-
async function
|
|
218
|
-
|
|
221
|
+
async function processFileList(
|
|
222
|
+
filePaths,
|
|
219
223
|
selectorArg,
|
|
220
224
|
checkMode,
|
|
221
225
|
lintMode,
|
|
@@ -226,12 +230,11 @@ async function processStdin(
|
|
|
226
230
|
cacheConfig,
|
|
227
231
|
searchQuery,
|
|
228
232
|
) {
|
|
229
|
-
const stdinPaths = parseStdinPaths(stdin, cwd);
|
|
230
233
|
const depth =
|
|
231
234
|
selectorArg !== undefined ? extractDepthFromArg(selectorArg) : undefined;
|
|
232
235
|
if (searchQuery !== undefined) {
|
|
233
236
|
const result = await searchFiles(
|
|
234
|
-
|
|
237
|
+
filePaths,
|
|
235
238
|
searchQuery,
|
|
236
239
|
cwd,
|
|
237
240
|
limit,
|
|
@@ -241,14 +244,14 @@ async function processStdin(
|
|
|
241
244
|
return;
|
|
242
245
|
}
|
|
243
246
|
if (lintMode) {
|
|
244
|
-
const result = await lintFiles(
|
|
247
|
+
const result = await lintFiles(filePaths, cwd, limit, cacheConfig);
|
|
245
248
|
writeLintResult(result, pretty);
|
|
246
249
|
} else if (checkMode) {
|
|
247
|
-
const result = await validateFiles(
|
|
250
|
+
const result = await validateFiles(filePaths, cwd, limit, cacheConfig);
|
|
248
251
|
writeValidationResult(result, pretty);
|
|
249
252
|
} else {
|
|
250
253
|
const result = await drilldownFiles(
|
|
251
|
-
|
|
254
|
+
filePaths,
|
|
252
255
|
depth,
|
|
253
256
|
cwd,
|
|
254
257
|
limit,
|
|
@@ -257,6 +260,35 @@ async function processStdin(
|
|
|
257
260
|
writeDrilldownResult(result, json, pretty);
|
|
258
261
|
}
|
|
259
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* Process stdin mode: file paths piped in.
|
|
265
|
+
*/
|
|
266
|
+
async function processStdin(
|
|
267
|
+
stdin,
|
|
268
|
+
selectorArg,
|
|
269
|
+
checkMode,
|
|
270
|
+
lintMode,
|
|
271
|
+
json,
|
|
272
|
+
pretty,
|
|
273
|
+
limit,
|
|
274
|
+
cwd,
|
|
275
|
+
cacheConfig,
|
|
276
|
+
searchQuery,
|
|
277
|
+
) {
|
|
278
|
+
const stdinPaths = parseStdinPaths(stdin, cwd);
|
|
279
|
+
await processFileList(
|
|
280
|
+
stdinPaths,
|
|
281
|
+
selectorArg,
|
|
282
|
+
checkMode,
|
|
283
|
+
lintMode,
|
|
284
|
+
json,
|
|
285
|
+
pretty,
|
|
286
|
+
limit,
|
|
287
|
+
cwd,
|
|
288
|
+
cacheConfig,
|
|
289
|
+
searchQuery,
|
|
290
|
+
);
|
|
291
|
+
}
|
|
260
292
|
/**
|
|
261
293
|
* Process selector mode: glob or path argument.
|
|
262
294
|
*/
|
|
@@ -305,19 +337,27 @@ async function processSelector(
|
|
|
305
337
|
}
|
|
306
338
|
}
|
|
307
339
|
/**
|
|
308
|
-
* Write an error to stderr as JSON
|
|
340
|
+
* Write an error to stderr as JSON or plain text depending on the json flag.
|
|
309
341
|
*/
|
|
310
|
-
function writeError(error) {
|
|
342
|
+
function writeError(error, json) {
|
|
343
|
+
process.exitCode = 1;
|
|
344
|
+
if (json) {
|
|
345
|
+
if (error instanceof JsdocError) {
|
|
346
|
+
void process.stderr.write(`${JSON.stringify(error.toJSON())}\n`);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
350
|
+
void process.stderr.write(
|
|
351
|
+
`${JSON.stringify({ error: { code: "INTERNAL_ERROR", message } })}\n`,
|
|
352
|
+
);
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
311
355
|
if (error instanceof JsdocError) {
|
|
312
|
-
void process.stderr.write(
|
|
313
|
-
process.exitCode = 1;
|
|
356
|
+
void process.stderr.write(`Error [${error.code}]: ${error.message}\n`);
|
|
314
357
|
return;
|
|
315
358
|
}
|
|
316
359
|
const message = error instanceof Error ? error.message : String(error);
|
|
317
|
-
void process.stderr.write(
|
|
318
|
-
`${JSON.stringify({ error: { code: "INTERNAL_ERROR", message } })}\n`,
|
|
319
|
-
);
|
|
320
|
-
process.exitCode = 1;
|
|
360
|
+
void process.stderr.write(`Error: ${message}\n`);
|
|
321
361
|
}
|
|
322
362
|
/**
|
|
323
363
|
* Handle --help flag by printing help text.
|
|
@@ -346,7 +386,7 @@ function handleSkill() {
|
|
|
346
386
|
/**
|
|
347
387
|
* Handle --explain-rule flag by printing rule explanation.
|
|
348
388
|
*/
|
|
349
|
-
function handleExplainRule(ruleName) {
|
|
389
|
+
function handleExplainRule(ruleName, json) {
|
|
350
390
|
const explanation = RULE_EXPLANATIONS[ruleName];
|
|
351
391
|
if (explanation) {
|
|
352
392
|
void process.stdout.write(explanation);
|
|
@@ -358,13 +398,14 @@ function handleExplainRule(ruleName) {
|
|
|
358
398
|
"INVALID_SELECTOR",
|
|
359
399
|
`Unknown rule: ${ruleName}. Available rules: ${available}`,
|
|
360
400
|
),
|
|
401
|
+
json,
|
|
361
402
|
);
|
|
362
403
|
}
|
|
363
404
|
/**
|
|
364
405
|
* Handle early-exit flags that print output and return without processing files.
|
|
365
406
|
* Returns true if an early-exit flag was handled.
|
|
366
407
|
*/
|
|
367
|
-
async function handleEarlyExitFlags(parsed) {
|
|
408
|
+
async function handleEarlyExitFlags(parsed, json) {
|
|
368
409
|
if (parsed.help) {
|
|
369
410
|
handleHelp();
|
|
370
411
|
return true;
|
|
@@ -378,7 +419,7 @@ async function handleEarlyExitFlags(parsed) {
|
|
|
378
419
|
return true;
|
|
379
420
|
}
|
|
380
421
|
if (parsed.explainRule !== undefined) {
|
|
381
|
-
handleExplainRule(parsed.explainRule);
|
|
422
|
+
handleExplainRule(parsed.explainRule, json);
|
|
382
423
|
return true;
|
|
383
424
|
}
|
|
384
425
|
return false;
|
|
@@ -387,10 +428,11 @@ async function handleEarlyExitFlags(parsed) {
|
|
|
387
428
|
* Validate that mode flags are not used in incompatible combinations.
|
|
388
429
|
* Returns true if validation passed (no conflicts), false if an error was written.
|
|
389
430
|
*/
|
|
390
|
-
function validateModeCombinations(parsed) {
|
|
431
|
+
function validateModeCombinations(parsed, json) {
|
|
391
432
|
if (parsed.checkMode && parsed.lintMode) {
|
|
392
433
|
writeError(
|
|
393
434
|
new JsdocError("INVALID_SELECTOR", "Cannot use -c and -l together"),
|
|
435
|
+
json,
|
|
394
436
|
);
|
|
395
437
|
return false;
|
|
396
438
|
}
|
|
@@ -400,6 +442,7 @@ function validateModeCombinations(parsed) {
|
|
|
400
442
|
) {
|
|
401
443
|
writeError(
|
|
402
444
|
new JsdocError("INVALID_SELECTOR", "Cannot use --search with -c or -l"),
|
|
445
|
+
json,
|
|
403
446
|
);
|
|
404
447
|
return false;
|
|
405
448
|
}
|
|
@@ -409,10 +452,11 @@ function validateModeCombinations(parsed) {
|
|
|
409
452
|
* Main CLI entry point. Exported for testability.
|
|
410
453
|
*/
|
|
411
454
|
export async function main(args, stdin) {
|
|
455
|
+
const json = args.includes("--json");
|
|
412
456
|
try {
|
|
413
457
|
const parsed = parseArgs(args);
|
|
414
|
-
if (await handleEarlyExitFlags(parsed)) return;
|
|
415
|
-
if (!validateModeCombinations(parsed)) return;
|
|
458
|
+
if (await handleEarlyExitFlags(parsed, json)) return;
|
|
459
|
+
if (!validateModeCombinations(parsed, json)) return;
|
|
416
460
|
const cacheConfig = {
|
|
417
461
|
enabled: !parsed.disableCache,
|
|
418
462
|
directory: parsed.cacheDirectory ?? DEFAULT_CACHE_DIR,
|
|
@@ -431,6 +475,29 @@ export async function main(args, stdin) {
|
|
|
431
475
|
cacheConfig,
|
|
432
476
|
parsed.searchQuery,
|
|
433
477
|
);
|
|
478
|
+
} else if (parsed.extraArgs.length > 0) {
|
|
479
|
+
// Multiple positional args (e.g. shell-expanded glob): expand each to
|
|
480
|
+
// .ts/.tsx files via discoverFiles (handles directories recursively)
|
|
481
|
+
const allArgPaths = [
|
|
482
|
+
...(parsed.selectorArg ? [parsed.selectorArg] : []),
|
|
483
|
+
...parsed.extraArgs,
|
|
484
|
+
];
|
|
485
|
+
const fileLists = await Promise.all(
|
|
486
|
+
allArgPaths.map((p) => discoverFiles(p, cwd, parsed.gitignore)),
|
|
487
|
+
);
|
|
488
|
+
const filePaths = [...new Set(fileLists.flat())];
|
|
489
|
+
await processFileList(
|
|
490
|
+
filePaths,
|
|
491
|
+
parsed.selectorArg,
|
|
492
|
+
parsed.checkMode,
|
|
493
|
+
parsed.lintMode,
|
|
494
|
+
parsed.json,
|
|
495
|
+
parsed.pretty,
|
|
496
|
+
parsed.limit,
|
|
497
|
+
cwd,
|
|
498
|
+
cacheConfig,
|
|
499
|
+
parsed.searchQuery,
|
|
500
|
+
);
|
|
434
501
|
} else {
|
|
435
502
|
await processSelector(
|
|
436
503
|
parsed.selectorArg,
|
|
@@ -446,7 +513,7 @@ export async function main(args, stdin) {
|
|
|
446
513
|
);
|
|
447
514
|
}
|
|
448
515
|
} catch (error) {
|
|
449
|
-
writeError(error);
|
|
516
|
+
writeError(error, json);
|
|
450
517
|
}
|
|
451
518
|
}
|
|
452
519
|
/**
|