reverse-engine 0.5.0 → 0.5.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.

Potentially problematic release.


This version of reverse-engine might be problematic. Click here for more details.

@@ -3,5 +3,6 @@ export interface AnalyzeOptions {
3
3
  include?: string[];
4
4
  exclude?: string[];
5
5
  framework?: string;
6
+ onProgress?: (current: number, total: number, file: string) => void;
6
7
  }
7
8
  export declare function analyze(sourcePath: string, options?: AnalyzeOptions): Promise<AnalysisResult>;
@@ -35,22 +35,28 @@ export async function analyze(sourcePath, options = {}) {
35
35
  let apiClients = [];
36
36
  let routes = [];
37
37
  // 각 파일 분석
38
- for (const file of files) {
38
+ let errorCount = 0;
39
+ for (let i = 0; i < files.length; i++) {
40
+ const file = files[i];
39
41
  const fullPath = join(sourcePath, file);
40
- const source = await readFile(fullPath, 'utf-8');
42
+ options.onProgress?.(i + 1, files.length, file);
43
+ let source;
44
+ try {
45
+ source = await readFile(fullPath, 'utf-8');
46
+ }
47
+ catch {
48
+ errorCount++;
49
+ continue;
50
+ }
41
51
  const ext = extname(file);
42
52
  try {
43
- const fileComponents = extractComponents(source, file, ext);
44
- const fileFunctions = extractFunctions(source, file, ext);
45
- const fileApiCalls = extractApiCalls(source, file, ext);
46
- const fileRoutes = extractRoutes(source, file, ext);
47
- components.push(...fileComponents);
48
- functions.push(...fileFunctions);
49
- apiClients.push(...fileApiCalls);
50
- routes.push(...fileRoutes);
53
+ components.push(...extractComponents(source, file, ext));
54
+ functions.push(...extractFunctions(source, file, ext));
55
+ apiClients.push(...extractApiCalls(source, file, ext));
56
+ routes.push(...extractRoutes(source, file, ext));
51
57
  }
52
58
  catch {
53
- // 파싱 실패한 파일은 건너뜀
59
+ errorCount++;
54
60
  }
55
61
  }
56
62
  // 역참조 구축
package/dist/cli/index.js CHANGED
@@ -76,6 +76,16 @@ function buildAuth(opts, baseUrl) {
76
76
  }
77
77
  return Object.keys(auth).length > 0 ? auth : undefined;
78
78
  }
79
+ /** 한 줄 진행 표시 (같은 줄 덮어쓰기) */
80
+ function progressLine(current, total, file) {
81
+ const pct = Math.round((current / total) * 100);
82
+ const short = file.length > 50 ? '...' + file.slice(-47) : file;
83
+ const line = ` ${chalk.dim(`[${current}/${total}]`)} ${chalk.dim(`${pct}%`)} ${short}`;
84
+ process.stdout.write(`\r\x1b[K${line}`);
85
+ }
86
+ function clearLine() {
87
+ process.stdout.write('\r\x1b[K');
88
+ }
79
89
  const nativeBin = findNativeBinary();
80
90
  const program = new Command();
81
91
  if (nativeBin) {
@@ -104,7 +114,9 @@ program
104
114
  const result = await analyze(sourcePath, {
105
115
  framework: opts.framework,
106
116
  include: opts.include?.split(','),
117
+ onProgress: progressLine,
107
118
  });
119
+ clearLine();
108
120
  console.log(chalk.green('✓'), '분석 완료!');
109
121
  console.log(` 프레임워크: ${result.framework}`);
110
122
  console.log(` 컴포넌트 ${result.components.length} | 함수 ${result.functions.length} | API ${result.apiClients.length} | 라우트 ${result.routes.length} | 의존성 ${result.dependencies.length}`);
@@ -258,7 +270,8 @@ program
258
270
  runNative(['analyze', sourcePath, '--framework', opts.framework || 'auto']);
259
271
  }
260
272
  else {
261
- const result = await analyze(sourcePath, { framework: opts.framework });
273
+ const result = await analyze(sourcePath, { framework: opts.framework, onProgress: progressLine });
274
+ clearLine();
262
275
  console.log(chalk.green('✓'), `분석: 컴포넌트 ${result.components.length} | 함수 ${result.functions.length} | API ${result.apiClients.length} | 라우트 ${result.routes.length}`);
263
276
  await writeFile(analysisPath, JSON.stringify(result, null, 2));
264
277
  }
@@ -297,7 +310,8 @@ program
297
310
  await mkdir(outputDir, { recursive: true });
298
311
  const analysisPath = join(outputDir, 'analysis.json');
299
312
  console.log(chalk.gray('━'.repeat(50)));
300
- const result = await analyze(sourcePath, {});
313
+ const result = await analyze(sourcePath, { onProgress: progressLine });
314
+ clearLine();
301
315
  console.log(chalk.green('✓'), `분석: 컴포넌트 ${result.components.length} | 함수 ${result.functions.length} | API ${result.apiClients.length} | 라우트 ${result.routes.length}`);
302
316
  await writeFile(analysisPath, JSON.stringify(result, null, 2));
303
317
  const data = JSON.parse(await readFile(analysisPath, 'utf-8'));
@@ -6,7 +6,17 @@ export async function generateReport(data, options = {}) {
6
6
  await mkdir(outputDir, { recursive: true });
7
7
  const outputs = [];
8
8
  if (formats.includes('excel')) {
9
- outputs.push(await generateExcel(data, outputDir));
9
+ try {
10
+ outputs.push(await generateExcel(data, outputDir));
11
+ }
12
+ catch (e) {
13
+ if (e.code === 'EBUSY') {
14
+ console.log(' ⚠ Excel 파일이 열려 있어 덮어쓸 수 없습니다. 파일을 닫고 다시 시도하세요.');
15
+ }
16
+ else {
17
+ throw e;
18
+ }
19
+ }
10
20
  }
11
21
  if (formats.includes('mermaid')) {
12
22
  outputs.push(await generateMermaid(data, outputDir));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reverse-engine",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "웹 서비스 역분석 자동화 도구 - 소스코드 분석, 문서 생성, 테스트 자동화",
5
5
  "keywords": [
6
6
  "reverse-engineering",