|
3 | 3 |
|
4 | 4 | import { program } from 'commander'; |
5 | 5 | import chalk from 'chalk'; |
| 6 | +import { tools, getDocs, getSourcePath } from '../tools'; |
6 | 7 | import { TidewaveExtractor } from '../index'; |
| 8 | +import { isExtractError, isResolveError } from '../core'; |
| 9 | + |
| 10 | +import { name, version } from '../../package.json'; |
7 | 11 |
|
8 | 12 | // CLI Interface |
9 | 13 | program |
10 | | - .name('tidewave') |
| 14 | + .name(name) |
11 | 15 | .description('Universal documentation and source extraction tool for TypeScript and JavaScript') |
12 | | - .version('0.1.0'); |
| 16 | + .version(version); |
13 | 17 |
|
14 | | -program |
15 | | - .command('docs') |
16 | | - .description('Extract documentation for a symbol') |
17 | | - .argument( |
18 | | - '<module-path>', |
19 | | - 'Module path formats:\n' + |
20 | | - ' - module:symbol - Extract a top-level symbol\n' + |
21 | | - ' - module:Class#method - Extract an instance method\n' + |
22 | | - ' - module:Class.method - Extract a static method\n' + |
23 | | - ' - node:Class#method - Extract a global/builtin instance method\n' + |
24 | | - ' - node:Class.method - Extract a global/builtin static method\n' + |
25 | | - '\n' + |
26 | | - 'Examples:\n' + |
27 | | - ' - src/types.ts:SymbolInfo\n' + |
28 | | - ' - ./utils:parseConfig\n' + |
29 | | - ' - lodash:isEmpty\n' + |
30 | | - ' - react:Component#render\n' + |
31 | | - ' - Math:Math.max', |
32 | | - ) |
33 | | - .option('-c, --config <path>', 'Path to tsconfig.json') |
34 | | - .option('-j, --json', 'Output as JSON') |
35 | | - .action(async (modulePath: string, options) => { |
36 | | - try { |
37 | | - const docs = await TidewaveExtractor.extractDocs(modulePath, { |
38 | | - tsConfigPath: options.config, |
39 | | - }); |
| 18 | +async function handleGetDocs( |
| 19 | + modulePath: string, |
| 20 | + options: { config?: string; json?: boolean }, |
| 21 | +): Promise<void> { |
| 22 | + const docsResult = await getDocs(modulePath, { config: options.config }); |
| 23 | + |
| 24 | + if (isExtractError(docsResult)) { |
| 25 | + console.error(chalk.red(`Error: ${docsResult.error.message}`)); |
| 26 | + process.exit(1); |
| 27 | + } |
| 28 | + |
| 29 | + if (options.json) { |
| 30 | + console.log(JSON.stringify(docsResult, null, 2)); |
| 31 | + } else { |
| 32 | + console.log(TidewaveExtractor.formatOutput(docsResult)); |
| 33 | + } |
| 34 | +} |
40 | 35 |
|
41 | | - if (docs) { |
42 | | - if (options.json) { |
43 | | - console.log(JSON.stringify(docs, null, 2)); |
44 | | - } else { |
45 | | - console.log(TidewaveExtractor.formatOutput(docs)); |
46 | | - } |
47 | | - } else { |
48 | | - process.exit(1); |
49 | | - } |
50 | | - } catch (error) { |
51 | | - console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`)); |
52 | | - process.exit(1); |
53 | | - } |
54 | | - }); |
| 36 | +async function handleGetSourcePath( |
| 37 | + moduleName: string, |
| 38 | + options: { config?: string }, |
| 39 | +): Promise<void> { |
| 40 | + const sourceResult = await getSourcePath(moduleName, { config: options.config }); |
| 41 | + |
| 42 | + if (isResolveError(sourceResult)) { |
| 43 | + console.error(chalk.red(`Error: ${sourceResult.error.message}`)); |
| 44 | + process.exit(1); |
| 45 | + } |
| 46 | + |
| 47 | + console.log(sourceResult.path); |
| 48 | +} |
| 49 | +const { |
| 50 | + docs: { cli: docsCli }, |
| 51 | + source: { cli: sourceCli }, |
| 52 | +} = tools; |
| 53 | + |
| 54 | +program |
| 55 | + .command(docsCli.command) |
| 56 | + .description(docsCli.description) |
| 57 | + .argument(docsCli.argument, docsCli.argumentDescription) |
| 58 | + .option(docsCli.options.config!.flag, docsCli.options.config!.desc) |
| 59 | + .option(docsCli.options.json!.flag, docsCli.options.json!.desc) |
| 60 | + .action(handleGetDocs); |
55 | 61 |
|
56 | 62 | program |
57 | | - .command('source') |
58 | | - .description('Get the source file path for a module') |
59 | | - .argument( |
60 | | - '<module>', |
61 | | - 'Module name to resolve:\n' + |
62 | | - ' - Local files: src/utils, ./types.ts, ../config\n' + |
63 | | - ' - Dependencies: lodash, react, @types/node\n' + |
64 | | - ' - Relative paths: ./src/components/Button', |
65 | | - ) |
66 | | - .option('-c, --config <path>', 'Path to tsconfig.json') |
67 | | - .action(async (moduleName: string, options) => { |
68 | | - try { |
69 | | - const sourcePath = await TidewaveExtractor.getSourcePath(moduleName, { |
70 | | - tsConfigPath: options.config, |
71 | | - }); |
| 63 | + .command(sourceCli.command) |
| 64 | + .description(sourceCli.description) |
| 65 | + .argument(sourceCli.argument, sourceCli.argumentDescription) |
| 66 | + .option(sourceCli.options.config!.flag, sourceCli.options.config!.desc) |
72 | 67 |
|
73 | | - if (sourcePath) { |
74 | | - console.log(sourcePath); |
75 | | - } else { |
76 | | - process.exit(1); |
77 | | - } |
78 | | - } catch (error) { |
79 | | - console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`)); |
80 | | - process.exit(1); |
81 | | - } |
82 | | - }); |
| 68 | + .action(handleGetSourcePath); |
83 | 69 |
|
84 | | -// Entry point |
85 | 70 | program.parse(process.argv); |
0 commit comments