@sammons/code-outline-cli 2.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.
Files changed (38) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cli-argument-parser.d.ts +23 -0
  3. package/dist/cli-argument-parser.d.ts.map +1 -0
  4. package/dist/cli-argument-parser.js +176 -0
  5. package/dist/cli-argument-parser.js.map +1 -0
  6. package/dist/cli-orchestrator.d.ts +7 -0
  7. package/dist/cli-orchestrator.d.ts.map +1 -0
  8. package/dist/cli-orchestrator.js +43 -0
  9. package/dist/cli-orchestrator.js.map +1 -0
  10. package/dist/cli-orchestrator.unit.test.d.ts +2 -0
  11. package/dist/cli-orchestrator.unit.test.d.ts.map +1 -0
  12. package/dist/cli-orchestrator.unit.test.js +139 -0
  13. package/dist/cli-orchestrator.unit.test.js.map +1 -0
  14. package/dist/cli-output-handler.d.ts +8 -0
  15. package/dist/cli-output-handler.d.ts.map +1 -0
  16. package/dist/cli-output-handler.js +16 -0
  17. package/dist/cli-output-handler.js.map +1 -0
  18. package/dist/cli.d.ts +3 -0
  19. package/dist/cli.d.ts.map +1 -0
  20. package/dist/cli.integration.test.d.ts +2 -0
  21. package/dist/cli.integration.test.d.ts.map +1 -0
  22. package/dist/cli.integration.test.js +308 -0
  23. package/dist/cli.integration.test.js.map +1 -0
  24. package/dist/cli.js +14 -0
  25. package/dist/cli.js.map +1 -0
  26. package/dist/cli.unit.test.d.ts +2 -0
  27. package/dist/cli.unit.test.d.ts.map +1 -0
  28. package/dist/cli.unit.test.js +349 -0
  29. package/dist/cli.unit.test.js.map +1 -0
  30. package/dist/file-processor.d.ts +16 -0
  31. package/dist/file-processor.d.ts.map +1 -0
  32. package/dist/file-processor.js +56 -0
  33. package/dist/file-processor.js.map +1 -0
  34. package/dist/test.d.ts +25 -0
  35. package/dist/test.d.ts.map +1 -0
  36. package/dist/test.js +41 -0
  37. package/dist/test.js.map +1 -0
  38. package/package.json +43 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Sammons Software LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,23 @@
1
+ import type { OutputFormat } from '@code-outline/parser';
2
+ export interface CliOptions {
3
+ format: OutputFormat;
4
+ depth: number;
5
+ namedOnly: boolean;
6
+ help: boolean;
7
+ version: boolean;
8
+ }
9
+ export interface ParsedArgs {
10
+ options: CliOptions;
11
+ pattern: string;
12
+ }
13
+ export declare class CLIArgumentError extends Error {
14
+ constructor(message: string);
15
+ }
16
+ export declare class CLIArgumentParser {
17
+ private safeExtractValue;
18
+ private validateAndThrow;
19
+ printHelp(): void;
20
+ printVersion(): void;
21
+ parse(): ParsedArgs;
22
+ }
23
+ //# sourceMappingURL=cli-argument-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-argument-parser.d.ts","sourceRoot":"","sources":["../src/cli-argument-parser.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIzD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,iBAAiB;IAE5B,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,gBAAgB;IAajB,SAAS,IAAI,IAAI;IA6CjB,YAAY,IAAI,IAAI;IAIpB,KAAK,IAAI,UAAU;CAiH3B"}
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CLIArgumentParser = exports.CLIArgumentError = void 0;
4
+ const node_util_1 = require("node:util");
5
+ const node_path_1 = require("node:path");
6
+ const node_fs_1 = require("node:fs");
7
+ const parser_1 = require("@code-outline/parser");
8
+ const package_json_1 = require("../package.json");
9
+ class CLIArgumentError extends Error {
10
+ constructor(message) {
11
+ super(message);
12
+ this.name = 'CLIArgumentError';
13
+ }
14
+ }
15
+ exports.CLIArgumentError = CLIArgumentError;
16
+ class CLIArgumentParser {
17
+ // Type guard to safely extract unknown values from parseArgs result
18
+ safeExtractValue(value, defaultValue) {
19
+ // Use proper type narrowing instead of type assertions
20
+ if (typeof defaultValue === 'boolean') {
21
+ return typeof value === 'boolean' ? value : defaultValue;
22
+ }
23
+ if (typeof defaultValue === 'string') {
24
+ return typeof value === 'string' ? value : defaultValue;
25
+ }
26
+ // Return default for all other cases
27
+ return defaultValue;
28
+ }
29
+ // Safe validation helper using proper type narrowing
30
+ validateAndThrow(validation, errorPrefix) {
31
+ if (!validation.success || validation.value === undefined) {
32
+ throw new CLIArgumentError(`${errorPrefix}: ${validation.error ?? 'validation failed'}`);
33
+ }
34
+ // TypeScript now knows validation.value is T (not T | undefined)
35
+ return validation.value;
36
+ }
37
+ printHelp() {
38
+ console.log(`
39
+ 🌳 Code Outline CLI - Parse and analyze JavaScript/TypeScript files
40
+
41
+ Usage:
42
+ code-outline <pattern> [options]
43
+
44
+ Arguments:
45
+ <pattern> Glob pattern to match files (e.g., "src/**/*.ts", "*.js")
46
+
47
+ Options:
48
+ -f, --format <type> Output format: ascii, json, or yaml (default: ascii)
49
+ -d, --depth <n> Maximum AST depth to traverse (default: Infinity)
50
+ -a, --all Show all nodes, including unnamed ones
51
+ --named-only Show only named entities (default: true)
52
+ -h, --help Show this help message
53
+ -v, --version Show version number
54
+
55
+ Output Formats:
56
+ ascii Tree-like visualization with color-coded syntax (default)
57
+ json Structured JSON output for programmatic processing
58
+ yaml Human-readable YAML format
59
+
60
+ Examples:
61
+ # Parse all TypeScript files in src directory
62
+ code-outline "src/**/*.ts"
63
+
64
+ # Output JSON with depth limit
65
+ code-outline "*.js" --format json --depth 3
66
+
67
+ # Parse React components with all nodes
68
+ code-outline "src/components/**/*.tsx" --all
69
+
70
+ # Generate YAML report
71
+ code-outline "src/**/*.ts" --format yaml --depth 2
72
+
73
+ Supported Files:
74
+ .js JavaScript files
75
+ .ts TypeScript files
76
+ .tsx TypeScript JSX files
77
+
78
+ For more information, visit: https://github.com/sammons-software-llc/glance-with-tree-sitter
79
+ `);
80
+ }
81
+ printVersion() {
82
+ console.log(package_json_1.version);
83
+ }
84
+ parse() {
85
+ const { values, positionals } = (0, node_util_1.parseArgs)({
86
+ options: {
87
+ format: {
88
+ type: 'string',
89
+ default: 'ascii',
90
+ },
91
+ depth: {
92
+ type: 'string',
93
+ default: 'Infinity',
94
+ },
95
+ 'named-only': {
96
+ type: 'boolean',
97
+ default: true,
98
+ },
99
+ all: {
100
+ type: 'boolean',
101
+ default: false,
102
+ },
103
+ help: {
104
+ type: 'boolean',
105
+ short: 'h',
106
+ default: false,
107
+ },
108
+ version: {
109
+ type: 'boolean',
110
+ short: 'v',
111
+ default: false,
112
+ },
113
+ },
114
+ allowPositionals: true,
115
+ });
116
+ if (values.help) {
117
+ this.printHelp();
118
+ process.exit(0);
119
+ }
120
+ if (values.version) {
121
+ this.printVersion();
122
+ process.exit(0);
123
+ }
124
+ if (positionals.length === 0) {
125
+ throw new CLIArgumentError('No file pattern provided');
126
+ }
127
+ // Safely validate format using type guard
128
+ const formatValidation = (0, parser_1.validateFormat)(values.format);
129
+ const format = this.validateAndThrow(formatValidation, 'Invalid format');
130
+ // Safely validate depth using validator
131
+ const depthValidation = (0, parser_1.validateDepthValue)(values.depth);
132
+ const depth = this.validateAndThrow(depthValidation, 'Invalid depth');
133
+ const namedOnly = values.all
134
+ ? false
135
+ : this.safeExtractValue(values['named-only'], true);
136
+ const pattern = positionals[0];
137
+ // Warn if the pattern doesn't contain glob characters but looks like it should
138
+ if (!pattern.includes('*') &&
139
+ !pattern.includes('?') &&
140
+ !pattern.includes('[')) {
141
+ // Check if it's likely intended to be a glob pattern (directory-like structure)
142
+ const pathSegments = pattern
143
+ .split('/')
144
+ .filter((segment) => segment !== ''); // Remove empty segments from leading/trailing slashes
145
+ const hasMultipleSegments = pathSegments.length >= 3; // At least 3 meaningful segments (like packages/cli/src/file.ts)
146
+ const endsWithCommonExtension = /\.(ts|js|tsx|jsx)$/.test(pattern);
147
+ // Only warn if it's not an absolute path AND not an existing file
148
+ // (relative paths with many segments are likely intended as globs, but existing files should not warn)
149
+ const isAbsolutePath = (0, node_path_1.isAbsolute)(pattern);
150
+ const fileExists = (0, node_fs_1.existsSync)(pattern);
151
+ // Debug: Show the evaluation
152
+ const shouldWarn = hasMultipleSegments &&
153
+ endsWithCommonExtension &&
154
+ !isAbsolutePath &&
155
+ !fileExists;
156
+ if (shouldWarn) {
157
+ console.error(`⚠️ Warning: Pattern "${pattern}" doesn't contain glob characters (* ? []).`);
158
+ console.error(' If you intended to match multiple files, consider using:');
159
+ console.error(` "${pattern.replace(/\.(ts|js|tsx|jsx)$/, '/**/*.$1')}"`);
160
+ console.error(' Remember to quote glob patterns to prevent shell expansion!');
161
+ }
162
+ }
163
+ return {
164
+ options: {
165
+ format,
166
+ depth,
167
+ namedOnly,
168
+ help: false,
169
+ version: false,
170
+ },
171
+ pattern,
172
+ };
173
+ }
174
+ }
175
+ exports.CLIArgumentParser = CLIArgumentParser;
176
+ //# sourceMappingURL=cli-argument-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-argument-parser.js","sourceRoot":"","sources":["../src/cli-argument-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare class CLIOrchestrator {
2
+ private argumentParser;
3
+ private fileProcessor;
4
+ constructor();
5
+ run(): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=cli-orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-orchestrator.d.ts","sourceRoot":"","sources":["../src/cli-orchestrator.ts"],"names":[],"mappings":"AAIA,qBAAa,eAAe;IAC1B,OAAO,CAAC,cAAc,CAAoB;IAC1C,OAAO,CAAC,aAAa,CAAgB;;IAOxB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA+BlC"}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CLIOrchestrator = void 0;
4
+ const cli_argument_parser_js_1 = require("./cli-argument-parser.js");
5
+ const file_processor_js_1 = require("./file-processor.js");
6
+ const cli_output_handler_js_1 = require("./cli-output-handler.js");
7
+ class CLIOrchestrator {
8
+ argumentParser;
9
+ fileProcessor;
10
+ constructor() {
11
+ this.argumentParser = new cli_argument_parser_js_1.CLIArgumentParser();
12
+ this.fileProcessor = new file_processor_js_1.FileProcessor();
13
+ }
14
+ async run() {
15
+ try {
16
+ // Parse and validate arguments
17
+ const { options, pattern } = this.argumentParser.parse();
18
+ // Find matching files
19
+ const files = await this.fileProcessor.findFiles(pattern);
20
+ // Process files in parallel
21
+ const results = await this.fileProcessor.processFiles(files, options.depth, options.namedOnly);
22
+ // Format and output results
23
+ const outputHandler = new cli_output_handler_js_1.CLIOutputHandler(options.format);
24
+ outputHandler.formatAndOutput(results);
25
+ }
26
+ catch (error) {
27
+ if (error instanceof cli_argument_parser_js_1.CLIArgumentError) {
28
+ console.error(`Error: ${error.message}`);
29
+ this.argumentParser.printHelp();
30
+ process.exit(1);
31
+ }
32
+ else if (error instanceof file_processor_js_1.FileProcessorError) {
33
+ console.error(error.message);
34
+ process.exit(1);
35
+ }
36
+ else {
37
+ throw error; // Re-throw unexpected errors
38
+ }
39
+ }
40
+ }
41
+ }
42
+ exports.CLIOrchestrator = CLIOrchestrator;
43
+ //# sourceMappingURL=cli-orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-orchestrator.js","sourceRoot":"","sources":["../src/cli-orchestrator.ts"],"names":[],"mappings":";;;AAAA,qEAA+E;AAC/E,2DAAwE;AACxE,mEAA2D;AAE3D,MAAa,eAAe;IAClB,cAAc,CAAoB;IAClC,aAAa,CAAgB;IAErC;QACE,IAAI,CAAC,cAAc,GAAG,IAAI,0CAAiB,EAAE,CAAC;QAC9C,IAAI,CAAC,aAAa,GAAG,IAAI,iCAAa,EAAE,CAAC;IAC3C,CAAC;IAEM,KAAK,CAAC,GAAG;QACd,IAAI,CAAC;YACH,+BAA+B;YAC/B,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;YAEzD,sBAAsB;YACtB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAE1D,4BAA4B;YAC5B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,CACnD,KAAK,EACL,OAAO,CAAC,KAAK,EACb,OAAO,CAAC,SAAS,CAClB,CAAC;YAEF,4BAA4B;YAC5B,MAAM,aAAa,GAAG,IAAI,wCAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC3D,aAAa,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,IAAI,KAAK,YAAY,yCAAgB,EAAE,CAAC;gBACtC,OAAO,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBACzC,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC;gBAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;iBAAM,IAAI,KAAK,YAAY,sCAAkB,EAAE,CAAC;gBAC/C,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,MAAM,KAAK,CAAC,CAAC,6BAA6B;YAC5C,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAxCD,0CAwCC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli-orchestrator.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-orchestrator.unit.test.d.ts","sourceRoot":"","sources":["../src/cli-orchestrator.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ // Mock the CLI components before importing
5
+ vitest_1.vi.mock('./cli-argument-parser.js', () => ({
6
+ CLIArgumentParser: vitest_1.vi.fn(),
7
+ CLIArgumentError: class extends Error {
8
+ name = 'CLIArgumentError';
9
+ },
10
+ }));
11
+ vitest_1.vi.mock('./file-processor.js', () => ({
12
+ FileProcessor: vitest_1.vi.fn(),
13
+ FileProcessorError: class extends Error {
14
+ name = 'FileProcessorError';
15
+ },
16
+ }));
17
+ vitest_1.vi.mock('./cli-output-handler.js', () => ({
18
+ CLIOutputHandler: vitest_1.vi.fn(),
19
+ }));
20
+ // Mock console methods
21
+ const mockConsoleError = vitest_1.vi
22
+ .spyOn(console, 'error')
23
+ .mockImplementation(() => { });
24
+ // Import after mocking
25
+ const cli_orchestrator_js_1 = require("./cli-orchestrator.js");
26
+ const cli_argument_parser_js_1 = require("./cli-argument-parser.js");
27
+ const file_processor_js_1 = require("./file-processor.js");
28
+ const cli_output_handler_js_1 = require("./cli-output-handler.js");
29
+ (0, vitest_1.describe)('CLIOrchestrator', () => {
30
+ let orchestrator;
31
+ let mockArgumentParser;
32
+ let mockFileProcessor;
33
+ let mockOutputHandler;
34
+ (0, vitest_1.beforeEach)(() => {
35
+ // Create mock instances
36
+ mockArgumentParser = {
37
+ parse: vitest_1.vi.fn(),
38
+ printHelp: vitest_1.vi.fn(),
39
+ };
40
+ mockFileProcessor = {
41
+ findFiles: vitest_1.vi.fn(),
42
+ processFiles: vitest_1.vi.fn(),
43
+ };
44
+ mockOutputHandler = {
45
+ formatAndOutput: vitest_1.vi.fn(),
46
+ };
47
+ // Mock the constructors to return our mocked instances
48
+ vitest_1.vi.mocked(cli_argument_parser_js_1.CLIArgumentParser).mockImplementation(() => mockArgumentParser);
49
+ vitest_1.vi.mocked(file_processor_js_1.FileProcessor).mockImplementation(() => mockFileProcessor);
50
+ vitest_1.vi.mocked(cli_output_handler_js_1.CLIOutputHandler).mockImplementation(() => mockOutputHandler);
51
+ orchestrator = new cli_orchestrator_js_1.CLIOrchestrator();
52
+ vitest_1.vi.clearAllMocks();
53
+ // Mock process.exit
54
+ vitest_1.vi.spyOn(process, 'exit').mockImplementation(() => undefined);
55
+ });
56
+ (0, vitest_1.describe)('run', () => {
57
+ (0, vitest_1.it)('should orchestrate the entire CLI flow successfully', async () => {
58
+ const mockOptions = {
59
+ format: 'json',
60
+ depth: 5,
61
+ namedOnly: true,
62
+ help: false,
63
+ version: false,
64
+ };
65
+ const mockPattern = 'src/**/*.ts';
66
+ const mockFiles = ['/path/file1.ts', '/path/file2.ts'];
67
+ const mockResults = [
68
+ { file: '/path/file1.ts', outline: { type: 'program' } },
69
+ { file: '/path/file2.ts', outline: { type: 'program' } },
70
+ ];
71
+ mockArgumentParser.parse.mockReturnValue({
72
+ options: mockOptions,
73
+ pattern: mockPattern,
74
+ });
75
+ mockFileProcessor.findFiles.mockResolvedValue(mockFiles);
76
+ mockFileProcessor.processFiles.mockResolvedValue(mockResults);
77
+ await orchestrator.run();
78
+ (0, vitest_1.expect)(mockArgumentParser.parse).toHaveBeenCalled();
79
+ (0, vitest_1.expect)(mockFileProcessor.findFiles).toHaveBeenCalledWith(mockPattern);
80
+ (0, vitest_1.expect)(mockFileProcessor.processFiles).toHaveBeenCalledWith(mockFiles, mockOptions.depth, mockOptions.namedOnly);
81
+ (0, vitest_1.expect)(cli_output_handler_js_1.CLIOutputHandler).toHaveBeenCalledWith(mockOptions.format);
82
+ (0, vitest_1.expect)(mockOutputHandler.formatAndOutput).toHaveBeenCalledWith(mockResults);
83
+ });
84
+ (0, vitest_1.it)('should handle CLIArgumentError', async () => {
85
+ mockArgumentParser.parse.mockImplementation(() => {
86
+ throw new cli_argument_parser_js_1.CLIArgumentError('Invalid arguments');
87
+ });
88
+ await orchestrator.run();
89
+ (0, vitest_1.expect)(mockConsoleError).toHaveBeenCalledWith('Error: Invalid arguments');
90
+ (0, vitest_1.expect)(mockArgumentParser.printHelp).toHaveBeenCalled();
91
+ (0, vitest_1.expect)(process.exit).toHaveBeenCalledWith(1);
92
+ });
93
+ (0, vitest_1.it)('should handle FileProcessorError', async () => {
94
+ mockArgumentParser.parse.mockReturnValue({
95
+ options: {
96
+ format: 'json',
97
+ depth: 5,
98
+ namedOnly: true,
99
+ help: false,
100
+ version: false,
101
+ },
102
+ pattern: 'invalid/**/*.js',
103
+ });
104
+ mockFileProcessor.findFiles.mockImplementation(() => {
105
+ throw new file_processor_js_1.FileProcessorError('No files found');
106
+ });
107
+ await orchestrator.run();
108
+ (0, vitest_1.expect)(mockConsoleError).toHaveBeenCalledWith('No files found');
109
+ (0, vitest_1.expect)(process.exit).toHaveBeenCalledWith(1);
110
+ });
111
+ (0, vitest_1.it)('should re-throw unexpected errors', async () => {
112
+ const unexpectedError = new Error('Unexpected error');
113
+ mockArgumentParser.parse.mockImplementation(() => {
114
+ throw unexpectedError;
115
+ });
116
+ await (0, vitest_1.expect)(orchestrator.run()).rejects.toThrow('Unexpected error');
117
+ });
118
+ (0, vitest_1.it)('should handle async file processing errors', async () => {
119
+ mockArgumentParser.parse.mockReturnValue({
120
+ options: {
121
+ format: 'json',
122
+ depth: 5,
123
+ namedOnly: true,
124
+ help: false,
125
+ version: false,
126
+ },
127
+ pattern: 'src/**/*.js',
128
+ });
129
+ mockFileProcessor.findFiles.mockResolvedValue(['/path/file1.js']);
130
+ mockFileProcessor.processFiles.mockImplementation(() => {
131
+ throw new file_processor_js_1.FileProcessorError('Processing failed');
132
+ });
133
+ await orchestrator.run();
134
+ (0, vitest_1.expect)(mockConsoleError).toHaveBeenCalledWith('Processing failed');
135
+ (0, vitest_1.expect)(process.exit).toHaveBeenCalledWith(1);
136
+ });
137
+ });
138
+ });
139
+ //# sourceMappingURL=cli-orchestrator.unit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-orchestrator.unit.test.js","sourceRoot":"","sources":["../src/cli-orchestrator.unit.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { OutputFormat } from '@code-outline/parser';
2
+ import type { ProcessedFile } from './file-processor.js';
3
+ export declare class CLIOutputHandler {
4
+ private formatter;
5
+ constructor(format: OutputFormat);
6
+ formatAndOutput(results: ProcessedFile[]): void;
7
+ }
8
+ //# sourceMappingURL=cli-output-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-output-handler.d.ts","sourceRoot":"","sources":["../src/cli-output-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAY;gBAEjB,MAAM,EAAE,YAAY;IAIzB,eAAe,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI;CAIvD"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CLIOutputHandler = void 0;
4
+ const formatter_1 = require("@code-outline/formatter");
5
+ class CLIOutputHandler {
6
+ formatter;
7
+ constructor(format) {
8
+ this.formatter = new formatter_1.Formatter(format);
9
+ }
10
+ formatAndOutput(results) {
11
+ const output = this.formatter.format(results);
12
+ console.log(output);
13
+ }
14
+ }
15
+ exports.CLIOutputHandler = CLIOutputHandler;
16
+ //# sourceMappingURL=cli-output-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-output-handler.js","sourceRoot":"","sources":["../src/cli-output-handler.ts"],"names":[],"mappings":";;;AACA,uDAAoD;AAGpD,MAAa,gBAAgB;IACnB,SAAS,CAAY;IAE7B,YAAY,MAAoB;QAC9B,IAAI,CAAC,SAAS,GAAG,IAAI,qBAAS,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAEM,eAAe,CAAC,OAAwB;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;CACF;AAXD,4CAWC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli.integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.integration.test.d.ts","sourceRoot":"","sources":["../src/cli.integration.test.ts"],"names":[],"mappings":""}