@happyvertical/smrt-scanner 0.37.2 → 0.37.3
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/chunks/scanner-Caea1XyJ.js +1819 -0
- package/dist/chunks/scanner-Caea1XyJ.js.map +1 -0
- package/dist/cli.js +139 -150
- package/dist/cli.js.map +1 -1
- package/dist/index.js +135 -156
- package/dist/index.js.map +1 -1
- package/dist/types.js +0 -2
- package/package.json +7 -7
- package/dist/chunks/scanner-KKnhqxsr.js +0 -2204
- package/dist/chunks/scanner-KKnhqxsr.js.map +0 -1
- package/dist/types.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,62 +1,61 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { n as ManifestAdapter, t as OxcScanner } from "./chunks/scanner-Caea1XyJ.js";
|
|
2
3
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
3
|
-
import {
|
|
4
|
+
import { dirname, resolve } from "node:path";
|
|
4
5
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
|
|
6
|
+
//#region src/cli.ts
|
|
6
7
|
function parseArgs(args) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
return options;
|
|
8
|
+
const options = {
|
|
9
|
+
directory: process.cwd(),
|
|
10
|
+
json: true,
|
|
11
|
+
stats: false,
|
|
12
|
+
benchmark: false,
|
|
13
|
+
help: false,
|
|
14
|
+
version: false
|
|
15
|
+
};
|
|
16
|
+
let i = 0;
|
|
17
|
+
while (i < args.length) {
|
|
18
|
+
const arg = args[i];
|
|
19
|
+
switch (arg) {
|
|
20
|
+
case "-o":
|
|
21
|
+
case "--output":
|
|
22
|
+
options.output = args[++i];
|
|
23
|
+
break;
|
|
24
|
+
case "-i":
|
|
25
|
+
case "--include":
|
|
26
|
+
options.include = args[++i]?.split(",").map((s) => s.trim());
|
|
27
|
+
break;
|
|
28
|
+
case "-e":
|
|
29
|
+
case "--exclude":
|
|
30
|
+
options.exclude = args[++i]?.split(",").map((s) => s.trim());
|
|
31
|
+
break;
|
|
32
|
+
case "--json":
|
|
33
|
+
options.json = true;
|
|
34
|
+
break;
|
|
35
|
+
case "--stats":
|
|
36
|
+
options.stats = true;
|
|
37
|
+
break;
|
|
38
|
+
case "--benchmark":
|
|
39
|
+
options.benchmark = true;
|
|
40
|
+
break;
|
|
41
|
+
case "-h":
|
|
42
|
+
case "--help":
|
|
43
|
+
options.help = true;
|
|
44
|
+
break;
|
|
45
|
+
case "-v":
|
|
46
|
+
case "--version":
|
|
47
|
+
options.version = true;
|
|
48
|
+
break;
|
|
49
|
+
default:
|
|
50
|
+
if (!arg.startsWith("-")) options.directory = resolve(arg);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
i++;
|
|
54
|
+
}
|
|
55
|
+
return options;
|
|
57
56
|
}
|
|
58
57
|
function showHelp() {
|
|
59
|
-
|
|
58
|
+
console.log(`
|
|
60
59
|
smrt-scan - High-performance TypeScript scanner for SMRT manifest generation
|
|
61
60
|
|
|
62
61
|
Usage:
|
|
@@ -81,111 +80,101 @@ Examples:
|
|
|
81
80
|
`);
|
|
82
81
|
}
|
|
83
82
|
function showVersion() {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
83
|
+
try {
|
|
84
|
+
const pkgPath = resolve(dirname(fileURLToPath(import.meta.url)), "../package.json");
|
|
85
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
86
|
+
console.log(`smrt-scan v${pkg.version}`);
|
|
87
|
+
} catch {
|
|
88
|
+
console.log("smrt-scan v0.0.0");
|
|
89
|
+
}
|
|
92
90
|
}
|
|
93
91
|
async function runBenchmark(directory) {
|
|
94
|
-
|
|
92
|
+
console.log(`
|
|
95
93
|
Benchmarking OXC scanner on: ${directory}
|
|
96
94
|
`);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
95
|
+
const iterations = 5;
|
|
96
|
+
const times = [];
|
|
97
|
+
for (let i = 0; i < iterations; i++) {
|
|
98
|
+
const scanner = new OxcScanner({ cwd: directory });
|
|
99
|
+
const start = performance.now();
|
|
100
|
+
await scanner.scan();
|
|
101
|
+
const end = performance.now();
|
|
102
|
+
times.push(end - start);
|
|
103
|
+
process.stdout.write(` Run ${i + 1}: ${(end - start).toFixed(2)}ms
|
|
106
104
|
`);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
105
|
+
}
|
|
106
|
+
const avg = times.reduce((a, b) => a + b, 0) / times.length;
|
|
107
|
+
const min = Math.min(...times);
|
|
108
|
+
const max = Math.max(...times);
|
|
109
|
+
console.log(`
|
|
112
110
|
Results:`);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
console.log(` Average: ${avg.toFixed(2)}ms`);
|
|
112
|
+
console.log(` Min: ${min.toFixed(2)}ms`);
|
|
113
|
+
console.log(` Max: ${max.toFixed(2)}ms`);
|
|
116
114
|
}
|
|
117
115
|
async function main() {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
});
|
|
176
|
-
const output = JSON.stringify(manifest, null, 2);
|
|
177
|
-
if (options.output) {
|
|
178
|
-
writeFileSync(options.output, output, "utf-8");
|
|
179
|
-
console.error(`Manifest written to: ${options.output}`);
|
|
180
|
-
console.error(` Classes: ${resolved.length}`);
|
|
181
|
-
console.error(` Time: ${results.totalParseTimeMs.toFixed(2)}ms`);
|
|
182
|
-
} else {
|
|
183
|
-
console.log(output);
|
|
184
|
-
}
|
|
185
|
-
process.exit(results.errors.length > 0 ? 1 : 0);
|
|
116
|
+
const options = parseArgs(process.argv.slice(2));
|
|
117
|
+
if (options.help) {
|
|
118
|
+
showHelp();
|
|
119
|
+
process.exit(0);
|
|
120
|
+
}
|
|
121
|
+
if (options.version) {
|
|
122
|
+
showVersion();
|
|
123
|
+
process.exit(0);
|
|
124
|
+
}
|
|
125
|
+
if (options.benchmark) {
|
|
126
|
+
await runBenchmark(options.directory);
|
|
127
|
+
process.exit(0);
|
|
128
|
+
}
|
|
129
|
+
const scanner = new OxcScanner({
|
|
130
|
+
cwd: options.directory,
|
|
131
|
+
include: options.include,
|
|
132
|
+
exclude: options.exclude
|
|
133
|
+
});
|
|
134
|
+
const { results, resolved } = await scanner.scanAndResolve();
|
|
135
|
+
if (results.errors.length > 0) {
|
|
136
|
+
console.error("Scan errors:");
|
|
137
|
+
for (const error of results.errors) console.error(` ${error.filePath}:${error.line || "?"}: ${error.message}`);
|
|
138
|
+
}
|
|
139
|
+
if (options.stats) {
|
|
140
|
+
const stats = scanner.getStats();
|
|
141
|
+
console.log("Scan Statistics:");
|
|
142
|
+
console.log(` Files scanned: ${stats.fileCount}`);
|
|
143
|
+
console.log(` Total classes: ${stats.totalClasses}`);
|
|
144
|
+
console.log(` SMRT classes: ${stats.smrtClasses}`);
|
|
145
|
+
console.log(` STI classes: ${stats.stiClasses}`);
|
|
146
|
+
console.log(` Max inheritance: ${stats.maxInheritanceDepth}`);
|
|
147
|
+
console.log(` Parse time: ${stats.parseTimeMs.toFixed(2)}ms`);
|
|
148
|
+
process.exit(results.errors.length > 0 ? 1 : 0);
|
|
149
|
+
}
|
|
150
|
+
let packageName;
|
|
151
|
+
let packageVersion;
|
|
152
|
+
try {
|
|
153
|
+
const pkgContent = readFileSync(resolve(options.directory, "package.json"), "utf-8");
|
|
154
|
+
const packageJson = JSON.parse(pkgContent);
|
|
155
|
+
packageName = packageJson.name || void 0;
|
|
156
|
+
packageVersion = packageJson.version || void 0;
|
|
157
|
+
} catch {
|
|
158
|
+
console.error("Warning: package.json not found. Qualified names will not be generated.");
|
|
159
|
+
}
|
|
160
|
+
const manifest = new ManifestAdapter().toManifest(resolved, {
|
|
161
|
+
packageName,
|
|
162
|
+
packageVersion,
|
|
163
|
+
typeAliases: results.typeAliases
|
|
164
|
+
});
|
|
165
|
+
const output = JSON.stringify(manifest, null, 2);
|
|
166
|
+
if (options.output) {
|
|
167
|
+
writeFileSync(options.output, output, "utf-8");
|
|
168
|
+
console.error(`Manifest written to: ${options.output}`);
|
|
169
|
+
console.error(` Classes: ${resolved.length}`);
|
|
170
|
+
console.error(` Time: ${results.totalParseTimeMs.toFixed(2)}ms`);
|
|
171
|
+
} else console.log(output);
|
|
172
|
+
process.exit(results.errors.length > 0 ? 1 : 0);
|
|
186
173
|
}
|
|
187
174
|
main().catch((error) => {
|
|
188
|
-
|
|
189
|
-
|
|
175
|
+
console.error("Error:", error.message);
|
|
176
|
+
process.exit(1);
|
|
190
177
|
});
|
|
191
|
-
//#
|
|
178
|
+
//#endregion
|
|
179
|
+
|
|
180
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * smrt-scan CLI\n *\n * High-performance TypeScript scanner for SMRT manifest generation.\n *\n * Usage:\n * smrt-scan [options] [directory]\n *\n * Options:\n * -o, --output <file> Output manifest file (default: stdout)\n * -i, --include <glob> Include patterns (comma-separated)\n * -e, --exclude <glob> Exclude patterns (comma-separated)\n * --json Output as JSON (default)\n * --stats Output scan statistics\n * --benchmark Run performance benchmark\n * -h, --help Show help\n * -v, --version Show version\n */\n\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { ManifestAdapter } from './manifest-adapter.js';\nimport { OxcScanner } from './scanner.js';\n\ninterface CLIOptions {\n directory: string;\n output?: string;\n include?: string[];\n exclude?: string[];\n json: boolean;\n stats: boolean;\n benchmark: boolean;\n help: boolean;\n version: boolean;\n}\n\nfunction parseArgs(args: string[]): CLIOptions {\n const options: CLIOptions = {\n directory: process.cwd(),\n json: true,\n stats: false,\n benchmark: false,\n help: false,\n version: false,\n };\n\n let i = 0;\n while (i < args.length) {\n const arg = args[i];\n\n switch (arg) {\n case '-o':\n case '--output':\n options.output = args[++i];\n break;\n\n case '-i':\n case '--include':\n options.include = args[++i]?.split(',').map((s) => s.trim());\n break;\n\n case '-e':\n case '--exclude':\n options.exclude = args[++i]?.split(',').map((s) => s.trim());\n break;\n\n case '--json':\n options.json = true;\n break;\n\n case '--stats':\n options.stats = true;\n break;\n\n case '--benchmark':\n options.benchmark = true;\n break;\n\n case '-h':\n case '--help':\n options.help = true;\n break;\n\n case '-v':\n case '--version':\n options.version = true;\n break;\n\n default:\n // Assume it's the directory if it doesn't start with -\n if (!arg.startsWith('-')) {\n options.directory = resolve(arg);\n }\n break;\n }\n\n i++;\n }\n\n return options;\n}\n\nfunction showHelp(): void {\n console.log(`\nsmrt-scan - High-performance TypeScript scanner for SMRT manifest generation\n\nUsage:\n smrt-scan [options] [directory]\n\nOptions:\n -o, --output <file> Output manifest file (default: stdout)\n -i, --include <glob> Include patterns (comma-separated)\n -e, --exclude <glob> Exclude patterns (comma-separated)\n --json Output as JSON (default)\n --stats Output scan statistics only\n --benchmark Run performance benchmark\n -h, --help Show this help message\n -v, --version Show version\n\nExamples:\n smrt-scan # Scan current directory\n smrt-scan src/ # Scan src/ directory\n smrt-scan -o manifest.json # Output to file\n smrt-scan --stats # Show scan statistics\n smrt-scan -i \"src/**/*.ts\" -e \"**/*.test.ts\"\n`);\n}\n\nfunction showVersion(): void {\n // Read version from package.json using ESM-compatible approach\n try {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const pkgPath = resolve(__dirname, '../package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n console.log(`smrt-scan v${pkg.version}`);\n } catch {\n console.log('smrt-scan v0.0.0');\n }\n}\n\nasync function runBenchmark(directory: string): Promise<void> {\n console.log(`\\nBenchmarking OXC scanner on: ${directory}\\n`);\n\n const iterations = 5;\n const times: number[] = [];\n\n for (let i = 0; i < iterations; i++) {\n const scanner = new OxcScanner({ cwd: directory });\n const start = performance.now();\n await scanner.scan();\n const end = performance.now();\n times.push(end - start);\n process.stdout.write(` Run ${i + 1}: ${(end - start).toFixed(2)}ms\\n`);\n }\n\n const avg = times.reduce((a, b) => a + b, 0) / times.length;\n const min = Math.min(...times);\n const max = Math.max(...times);\n\n console.log(`\\nResults:`);\n console.log(` Average: ${avg.toFixed(2)}ms`);\n console.log(` Min: ${min.toFixed(2)}ms`);\n console.log(` Max: ${max.toFixed(2)}ms`);\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n const options = parseArgs(args);\n\n if (options.help) {\n showHelp();\n process.exit(0);\n }\n\n if (options.version) {\n showVersion();\n process.exit(0);\n }\n\n if (options.benchmark) {\n await runBenchmark(options.directory);\n process.exit(0);\n }\n\n // Create scanner\n const scanner = new OxcScanner({\n cwd: options.directory,\n include: options.include,\n exclude: options.exclude,\n });\n\n // Scan and resolve\n const { results, resolved } = await scanner.scanAndResolve();\n\n // Check for errors\n if (results.errors.length > 0) {\n console.error('Scan errors:');\n for (const error of results.errors) {\n console.error(\n ` ${error.filePath}:${error.line || '?'}: ${error.message}`,\n );\n }\n }\n\n // Output stats only\n if (options.stats) {\n const stats = scanner.getStats();\n console.log('Scan Statistics:');\n console.log(` Files scanned: ${stats.fileCount}`);\n console.log(` Total classes: ${stats.totalClasses}`);\n console.log(` SMRT classes: ${stats.smrtClasses}`);\n console.log(` STI classes: ${stats.stiClasses}`);\n console.log(` Max inheritance: ${stats.maxInheritanceDepth}`);\n console.log(` Parse time: ${stats.parseTimeMs.toFixed(2)}ms`);\n process.exit(results.errors.length > 0 ? 1 : 0);\n }\n\n // Read package.json for metadata (Issue #713 - namespace isolation)\n let packageName: string | undefined;\n let packageVersion: string | undefined;\n try {\n const pkgPath = resolve(options.directory, 'package.json');\n const pkgContent = readFileSync(pkgPath, 'utf-8');\n const packageJson = JSON.parse(pkgContent);\n packageName = packageJson.name || undefined;\n packageVersion = packageJson.version || undefined;\n } catch {\n // package.json not found or invalid - continue without packageName\n console.error(\n 'Warning: package.json not found. Qualified names will not be generated.',\n );\n }\n\n // Generate manifest with packageName for qualified names (Issue #713)\n const adapter = new ManifestAdapter();\n const manifest = adapter.toManifest(resolved, {\n packageName,\n packageVersion,\n typeAliases: results.typeAliases,\n });\n\n const output = JSON.stringify(manifest, null, 2);\n\n // Write output\n if (options.output) {\n writeFileSync(options.output, output, 'utf-8');\n console.error(`Manifest written to: ${options.output}`);\n console.error(` Classes: ${resolved.length}`);\n console.error(` Time: ${results.totalParseTimeMs.toFixed(2)}ms`);\n } else {\n console.log(output);\n }\n\n process.exit(results.errors.length > 0 ? 1 : 0);\n}\n\nmain().catch((error) => {\n console.error('Error:', error.message);\n process.exit(1);\n});\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * smrt-scan CLI\n *\n * High-performance TypeScript scanner for SMRT manifest generation.\n *\n * Usage:\n * smrt-scan [options] [directory]\n *\n * Options:\n * -o, --output <file> Output manifest file (default: stdout)\n * -i, --include <glob> Include patterns (comma-separated)\n * -e, --exclude <glob> Exclude patterns (comma-separated)\n * --json Output as JSON (default)\n * --stats Output scan statistics\n * --benchmark Run performance benchmark\n * -h, --help Show help\n * -v, --version Show version\n */\n\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { ManifestAdapter } from './manifest-adapter.js';\nimport { OxcScanner } from './scanner.js';\n\ninterface CLIOptions {\n directory: string;\n output?: string;\n include?: string[];\n exclude?: string[];\n json: boolean;\n stats: boolean;\n benchmark: boolean;\n help: boolean;\n version: boolean;\n}\n\nfunction parseArgs(args: string[]): CLIOptions {\n const options: CLIOptions = {\n directory: process.cwd(),\n json: true,\n stats: false,\n benchmark: false,\n help: false,\n version: false,\n };\n\n let i = 0;\n while (i < args.length) {\n const arg = args[i];\n\n switch (arg) {\n case '-o':\n case '--output':\n options.output = args[++i];\n break;\n\n case '-i':\n case '--include':\n options.include = args[++i]?.split(',').map((s) => s.trim());\n break;\n\n case '-e':\n case '--exclude':\n options.exclude = args[++i]?.split(',').map((s) => s.trim());\n break;\n\n case '--json':\n options.json = true;\n break;\n\n case '--stats':\n options.stats = true;\n break;\n\n case '--benchmark':\n options.benchmark = true;\n break;\n\n case '-h':\n case '--help':\n options.help = true;\n break;\n\n case '-v':\n case '--version':\n options.version = true;\n break;\n\n default:\n // Assume it's the directory if it doesn't start with -\n if (!arg.startsWith('-')) {\n options.directory = resolve(arg);\n }\n break;\n }\n\n i++;\n }\n\n return options;\n}\n\nfunction showHelp(): void {\n console.log(`\nsmrt-scan - High-performance TypeScript scanner for SMRT manifest generation\n\nUsage:\n smrt-scan [options] [directory]\n\nOptions:\n -o, --output <file> Output manifest file (default: stdout)\n -i, --include <glob> Include patterns (comma-separated)\n -e, --exclude <glob> Exclude patterns (comma-separated)\n --json Output as JSON (default)\n --stats Output scan statistics only\n --benchmark Run performance benchmark\n -h, --help Show this help message\n -v, --version Show version\n\nExamples:\n smrt-scan # Scan current directory\n smrt-scan src/ # Scan src/ directory\n smrt-scan -o manifest.json # Output to file\n smrt-scan --stats # Show scan statistics\n smrt-scan -i \"src/**/*.ts\" -e \"**/*.test.ts\"\n`);\n}\n\nfunction showVersion(): void {\n // Read version from package.json using ESM-compatible approach\n try {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const pkgPath = resolve(__dirname, '../package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n console.log(`smrt-scan v${pkg.version}`);\n } catch {\n console.log('smrt-scan v0.0.0');\n }\n}\n\nasync function runBenchmark(directory: string): Promise<void> {\n console.log(`\\nBenchmarking OXC scanner on: ${directory}\\n`);\n\n const iterations = 5;\n const times: number[] = [];\n\n for (let i = 0; i < iterations; i++) {\n const scanner = new OxcScanner({ cwd: directory });\n const start = performance.now();\n await scanner.scan();\n const end = performance.now();\n times.push(end - start);\n process.stdout.write(` Run ${i + 1}: ${(end - start).toFixed(2)}ms\\n`);\n }\n\n const avg = times.reduce((a, b) => a + b, 0) / times.length;\n const min = Math.min(...times);\n const max = Math.max(...times);\n\n console.log(`\\nResults:`);\n console.log(` Average: ${avg.toFixed(2)}ms`);\n console.log(` Min: ${min.toFixed(2)}ms`);\n console.log(` Max: ${max.toFixed(2)}ms`);\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n const options = parseArgs(args);\n\n if (options.help) {\n showHelp();\n process.exit(0);\n }\n\n if (options.version) {\n showVersion();\n process.exit(0);\n }\n\n if (options.benchmark) {\n await runBenchmark(options.directory);\n process.exit(0);\n }\n\n // Create scanner\n const scanner = new OxcScanner({\n cwd: options.directory,\n include: options.include,\n exclude: options.exclude,\n });\n\n // Scan and resolve\n const { results, resolved } = await scanner.scanAndResolve();\n\n // Check for errors\n if (results.errors.length > 0) {\n console.error('Scan errors:');\n for (const error of results.errors) {\n console.error(\n ` ${error.filePath}:${error.line || '?'}: ${error.message}`,\n );\n }\n }\n\n // Output stats only\n if (options.stats) {\n const stats = scanner.getStats();\n console.log('Scan Statistics:');\n console.log(` Files scanned: ${stats.fileCount}`);\n console.log(` Total classes: ${stats.totalClasses}`);\n console.log(` SMRT classes: ${stats.smrtClasses}`);\n console.log(` STI classes: ${stats.stiClasses}`);\n console.log(` Max inheritance: ${stats.maxInheritanceDepth}`);\n console.log(` Parse time: ${stats.parseTimeMs.toFixed(2)}ms`);\n process.exit(results.errors.length > 0 ? 1 : 0);\n }\n\n // Read package.json for metadata (Issue #713 - namespace isolation)\n let packageName: string | undefined;\n let packageVersion: string | undefined;\n try {\n const pkgPath = resolve(options.directory, 'package.json');\n const pkgContent = readFileSync(pkgPath, 'utf-8');\n const packageJson = JSON.parse(pkgContent);\n packageName = packageJson.name || undefined;\n packageVersion = packageJson.version || undefined;\n } catch {\n // package.json not found or invalid - continue without packageName\n console.error(\n 'Warning: package.json not found. Qualified names will not be generated.',\n );\n }\n\n // Generate manifest with packageName for qualified names (Issue #713)\n const adapter = new ManifestAdapter();\n const manifest = adapter.toManifest(resolved, {\n packageName,\n packageVersion,\n typeAliases: results.typeAliases,\n });\n\n const output = JSON.stringify(manifest, null, 2);\n\n // Write output\n if (options.output) {\n writeFileSync(options.output, output, 'utf-8');\n console.error(`Manifest written to: ${options.output}`);\n console.error(` Classes: ${resolved.length}`);\n console.error(` Time: ${results.totalParseTimeMs.toFixed(2)}ms`);\n } else {\n console.log(output);\n }\n\n process.exit(results.errors.length > 0 ? 1 : 0);\n}\n\nmain().catch((error) => {\n console.error('Error:', error.message);\n process.exit(1);\n});\n"],"mappings":"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"}
|