archrisk-engine 1.0.1 → 1.0.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/i18n/locales.d.ts +160 -0
- package/dist/i18n/locales.js +227 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -0
- package/dist/jsAnalyzer.d.ts +8 -0
- package/dist/jsAnalyzer.js +129 -0
- package/dist/repoAnalyzer.d.ts +5 -11
- package/dist/repoAnalyzer.js +57 -138
- package/package.json +1 -1
- package/src/i18n/locales.ts +225 -0
- package/src/index.ts +2 -0
- package/src/jsAnalyzer.ts +143 -0
- package/src/repoAnalyzer.ts +62 -148
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
export declare const LOCALES: {
|
|
2
|
+
en: {
|
|
3
|
+
'RR-SEC-001': {
|
|
4
|
+
title: string;
|
|
5
|
+
category: string;
|
|
6
|
+
standard: string;
|
|
7
|
+
impact: string;
|
|
8
|
+
action: string;
|
|
9
|
+
reference: string;
|
|
10
|
+
whenItMatters: string;
|
|
11
|
+
};
|
|
12
|
+
'RR-TEST-001': {
|
|
13
|
+
title: string;
|
|
14
|
+
category: string;
|
|
15
|
+
evidence: string;
|
|
16
|
+
standard: string;
|
|
17
|
+
impact: string;
|
|
18
|
+
action: string;
|
|
19
|
+
reference: string;
|
|
20
|
+
whenItMatters: string;
|
|
21
|
+
};
|
|
22
|
+
'RR-CI-001': {
|
|
23
|
+
title: string;
|
|
24
|
+
category: string;
|
|
25
|
+
evidence: string;
|
|
26
|
+
standard: string;
|
|
27
|
+
impact: string;
|
|
28
|
+
action: string;
|
|
29
|
+
reference: string;
|
|
30
|
+
whenItMatters: string;
|
|
31
|
+
};
|
|
32
|
+
'RR-OPS-001': {
|
|
33
|
+
title: string;
|
|
34
|
+
category: string;
|
|
35
|
+
standard: string;
|
|
36
|
+
impact: string;
|
|
37
|
+
action: string;
|
|
38
|
+
reference: string;
|
|
39
|
+
whenItMatters: string;
|
|
40
|
+
};
|
|
41
|
+
'RR-LOG-001': {
|
|
42
|
+
title: string;
|
|
43
|
+
category: string;
|
|
44
|
+
evidence: string;
|
|
45
|
+
standard: string;
|
|
46
|
+
impact: string;
|
|
47
|
+
action: string;
|
|
48
|
+
reference: string;
|
|
49
|
+
whenItMatters: string;
|
|
50
|
+
};
|
|
51
|
+
'RR-DEP-001': {
|
|
52
|
+
title: string;
|
|
53
|
+
category: string;
|
|
54
|
+
standard: string;
|
|
55
|
+
impact: string;
|
|
56
|
+
action: string;
|
|
57
|
+
reference: string;
|
|
58
|
+
whenItMatters: string;
|
|
59
|
+
};
|
|
60
|
+
'RR-LINT-001': {
|
|
61
|
+
title: string;
|
|
62
|
+
category: string;
|
|
63
|
+
standard: string;
|
|
64
|
+
impact: string;
|
|
65
|
+
action: string;
|
|
66
|
+
reference: string;
|
|
67
|
+
whenItMatters: string;
|
|
68
|
+
};
|
|
69
|
+
DEFAULT: {
|
|
70
|
+
title: string;
|
|
71
|
+
category: string;
|
|
72
|
+
standard: string;
|
|
73
|
+
impact: string;
|
|
74
|
+
action: string;
|
|
75
|
+
reference: string;
|
|
76
|
+
whenItMatters: string;
|
|
77
|
+
};
|
|
78
|
+
DISCLOSURE: string;
|
|
79
|
+
CTA: string;
|
|
80
|
+
};
|
|
81
|
+
ko: {
|
|
82
|
+
'RR-SEC-001': {
|
|
83
|
+
title: string;
|
|
84
|
+
category: string;
|
|
85
|
+
standard: string;
|
|
86
|
+
impact: string;
|
|
87
|
+
action: string;
|
|
88
|
+
reference: string;
|
|
89
|
+
whenItMatters: string;
|
|
90
|
+
};
|
|
91
|
+
'RR-TEST-001': {
|
|
92
|
+
title: string;
|
|
93
|
+
category: string;
|
|
94
|
+
evidence: string;
|
|
95
|
+
standard: string;
|
|
96
|
+
impact: string;
|
|
97
|
+
action: string;
|
|
98
|
+
reference: string;
|
|
99
|
+
whenItMatters: string;
|
|
100
|
+
};
|
|
101
|
+
'RR-CI-001': {
|
|
102
|
+
title: string;
|
|
103
|
+
category: string;
|
|
104
|
+
evidence: string;
|
|
105
|
+
standard: string;
|
|
106
|
+
impact: string;
|
|
107
|
+
action: string;
|
|
108
|
+
reference: string;
|
|
109
|
+
whenItMatters: string;
|
|
110
|
+
};
|
|
111
|
+
'RR-OPS-001': {
|
|
112
|
+
title: string;
|
|
113
|
+
category: string;
|
|
114
|
+
standard: string;
|
|
115
|
+
impact: string;
|
|
116
|
+
action: string;
|
|
117
|
+
reference: string;
|
|
118
|
+
whenItMatters: string;
|
|
119
|
+
};
|
|
120
|
+
'RR-LOG-001': {
|
|
121
|
+
title: string;
|
|
122
|
+
category: string;
|
|
123
|
+
evidence: string;
|
|
124
|
+
standard: string;
|
|
125
|
+
impact: string;
|
|
126
|
+
action: string;
|
|
127
|
+
reference: string;
|
|
128
|
+
whenItMatters: string;
|
|
129
|
+
};
|
|
130
|
+
'RR-DEP-001': {
|
|
131
|
+
title: string;
|
|
132
|
+
category: string;
|
|
133
|
+
standard: string;
|
|
134
|
+
impact: string;
|
|
135
|
+
action: string;
|
|
136
|
+
reference: string;
|
|
137
|
+
whenItMatters: string;
|
|
138
|
+
};
|
|
139
|
+
'RR-LINT-001': {
|
|
140
|
+
title: string;
|
|
141
|
+
category: string;
|
|
142
|
+
standard: string;
|
|
143
|
+
impact: string;
|
|
144
|
+
action: string;
|
|
145
|
+
reference: string;
|
|
146
|
+
whenItMatters: string;
|
|
147
|
+
};
|
|
148
|
+
DEFAULT: {
|
|
149
|
+
title: string;
|
|
150
|
+
category: string;
|
|
151
|
+
standard: string;
|
|
152
|
+
impact: string;
|
|
153
|
+
action: string;
|
|
154
|
+
reference: string;
|
|
155
|
+
whenItMatters: string;
|
|
156
|
+
};
|
|
157
|
+
DISCLOSURE: string;
|
|
158
|
+
CTA: string;
|
|
159
|
+
};
|
|
160
|
+
};
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LOCALES = void 0;
|
|
4
|
+
exports.LOCALES = {
|
|
5
|
+
en: {
|
|
6
|
+
'RR-SEC-001': {
|
|
7
|
+
title: "Security Vulnerability Detected",
|
|
8
|
+
category: 'Security',
|
|
9
|
+
standard: "OWASP Top 10 A03:2021 – Injection",
|
|
10
|
+
impact: "Potential for unauthorized access or data leakage through injection attacks.",
|
|
11
|
+
action: `
|
|
12
|
+
# Action: Isolate and use Environment Variables
|
|
13
|
+
subprocess.run(..., shell=False) # Recommended
|
|
14
|
+
# Or use .env file
|
|
15
|
+
import os
|
|
16
|
+
SECRET = os.getenv('MY_SECRET')
|
|
17
|
+
`,
|
|
18
|
+
reference: "https://docs.python.org/3/library/subprocess.html#security-considerations",
|
|
19
|
+
whenItMatters: "Immediately upon deployment, as scanners can detect this."
|
|
20
|
+
},
|
|
21
|
+
'RR-TEST-001': {
|
|
22
|
+
title: "Missing Automated Tests",
|
|
23
|
+
category: 'Service Interruption',
|
|
24
|
+
evidence: "No tests/ directory or pytest/unittest configuration found.",
|
|
25
|
+
standard: "pytest Framework Documentation",
|
|
26
|
+
impact: "Unable to verify if validation logic breaks existing features. High risk of regression.",
|
|
27
|
+
action: `
|
|
28
|
+
# Action: Create tests/test_smoke.py
|
|
29
|
+
def test_health_check():
|
|
30
|
+
assert True # Basic sanity check
|
|
31
|
+
`,
|
|
32
|
+
reference: "https://docs.pytest.org/",
|
|
33
|
+
whenItMatters: "When team size > 2 or deployment frequency increases."
|
|
34
|
+
},
|
|
35
|
+
'RR-CI-001': {
|
|
36
|
+
title: "Missing CI Pipeline",
|
|
37
|
+
category: 'Service Interruption',
|
|
38
|
+
evidence: "No GitHub Actions (.github/workflows/*.yml) or CI configuration found.",
|
|
39
|
+
standard: "GitHub Actions Documentation",
|
|
40
|
+
impact: "Manual deployments are prone to human error and lack consistency.",
|
|
41
|
+
action: `
|
|
42
|
+
# Action: Create .github/workflows/ci.yml
|
|
43
|
+
name: CI
|
|
44
|
+
on: [push]
|
|
45
|
+
jobs:
|
|
46
|
+
test:
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
steps:
|
|
49
|
+
- uses: actions/checkout@v3
|
|
50
|
+
- run: npm test
|
|
51
|
+
`,
|
|
52
|
+
reference: "https://docs.github.com/en/actions",
|
|
53
|
+
whenItMatters: "When deploying more than twice a week."
|
|
54
|
+
},
|
|
55
|
+
'RR-OPS-001': {
|
|
56
|
+
title: "Project Hygiene Check Failed",
|
|
57
|
+
category: 'Service Interruption',
|
|
58
|
+
standard: "12-Factor App / Docker Documentation",
|
|
59
|
+
impact: "Inconsistency between dev and prod environments (\"It works on my machine\").",
|
|
60
|
+
action: `
|
|
61
|
+
# Checklist to Fix:
|
|
62
|
+
1. Create 'Dockerfile'
|
|
63
|
+
2. Create '.gitignore' (use gitignore.io)
|
|
64
|
+
3. Create 'requirements.txt' or 'package.json'
|
|
65
|
+
4. Create '.env.example'
|
|
66
|
+
`,
|
|
67
|
+
reference: "https://12factor.net/",
|
|
68
|
+
whenItMatters: "Onboarding new members or migrating servers."
|
|
69
|
+
},
|
|
70
|
+
'RR-LOG-001': {
|
|
71
|
+
title: "Insufficient Logging",
|
|
72
|
+
category: 'Maintenance',
|
|
73
|
+
evidence: "No logging configuration (logging, loguru) found in codebase.",
|
|
74
|
+
standard: "Python Logging Cookbook",
|
|
75
|
+
impact: "Zero visibility into runtime errors, making debugging impossible during outages.",
|
|
76
|
+
action: `
|
|
77
|
+
# Action: Python Logging Setup
|
|
78
|
+
import logging
|
|
79
|
+
logging.basicConfig(level=logging.INFO)
|
|
80
|
+
logger = logging.getLogger(__name__)
|
|
81
|
+
logger.info("Server started")
|
|
82
|
+
`,
|
|
83
|
+
reference: "https://docs.python.org/3/howto/logging-cookbook.html",
|
|
84
|
+
whenItMatters: "When a 500 error occurs in production."
|
|
85
|
+
},
|
|
86
|
+
'RR-DEP-001': {
|
|
87
|
+
title: "Structural Dependency Issue",
|
|
88
|
+
category: 'Scalability',
|
|
89
|
+
standard: "Clean Architecture: Dependency Rule",
|
|
90
|
+
impact: "High coupling between modules makes maintenance difficult and increases side effects.",
|
|
91
|
+
action: "Refactor to decouple modules or extract common logic.",
|
|
92
|
+
reference: "https://refactoring.guru/design-patterns",
|
|
93
|
+
whenItMatters: "As the codebase grows, refactoring costs explode."
|
|
94
|
+
},
|
|
95
|
+
'RR-LINT-001': {
|
|
96
|
+
title: "God Module Detected",
|
|
97
|
+
category: 'Maintenance',
|
|
98
|
+
standard: "Clean Code: Functions",
|
|
99
|
+
impact: "Single file has too many responsibilities, making changes risky.",
|
|
100
|
+
action: "Split file based on responsibilities (Separation of Concerns).",
|
|
101
|
+
reference: "https://pypi.org/project/flake8/",
|
|
102
|
+
whenItMatters: "When every feature addition causes a regression bug."
|
|
103
|
+
},
|
|
104
|
+
'DEFAULT': {
|
|
105
|
+
title: "Other Potential Risks",
|
|
106
|
+
category: 'Maintenance',
|
|
107
|
+
standard: "General Coding Best Practices",
|
|
108
|
+
impact: "Potential bugs or maintenance debt.",
|
|
109
|
+
action: "Review and consider refactoring.",
|
|
110
|
+
reference: "#",
|
|
111
|
+
whenItMatters: "When code quality starts to degrade."
|
|
112
|
+
},
|
|
113
|
+
'DISCLOSURE': "Pre-deploy audit complete. Detected risks may cause service interruptions or data loss in production.",
|
|
114
|
+
'CTA': "Automate this ritual. Install the GitHub App to manage Release Readiness continuously."
|
|
115
|
+
},
|
|
116
|
+
ko: {
|
|
117
|
+
'RR-SEC-001': {
|
|
118
|
+
title: "보안 취약점 위험 (Security Vulnerability)",
|
|
119
|
+
category: 'Security',
|
|
120
|
+
standard: "OWASP Top 10 A03:2021 – Injection",
|
|
121
|
+
impact: "외부 공격자가 시스템 권한을 탈취하거나 민감 정보를 유출할 수 있는 조건이 형성됩니다.",
|
|
122
|
+
action: `
|
|
123
|
+
# Action: 격리 및 환경변수 사용
|
|
124
|
+
subprocess.run(..., shell=False) # 권장
|
|
125
|
+
# 또는 .env 파일 사용
|
|
126
|
+
import os
|
|
127
|
+
SECRET = os.getenv('MY_SECRET')
|
|
128
|
+
`,
|
|
129
|
+
reference: "https://docs.python.org/3/library/subprocess.html#security-considerations",
|
|
130
|
+
whenItMatters: "배포 즉시 자동화된 스캐너나 공격자에 의해 탐지될 수 있습니다."
|
|
131
|
+
},
|
|
132
|
+
'RR-TEST-001': {
|
|
133
|
+
title: "자동화 테스트 부재 (Missing Automated Tests)",
|
|
134
|
+
category: 'Service Interruption',
|
|
135
|
+
evidence: "tests/ 디렉토리 또는 pytest/unittest 관련 설정을 찾을 수 없습니다.",
|
|
136
|
+
standard: "pytest Framework Documentation",
|
|
137
|
+
impact: "코드 변경 시 기존 기능이 파괴되었는지 확인할 방법이 없어, 배포 후 장애 발생 확률이 높아집니다.",
|
|
138
|
+
action: `
|
|
139
|
+
# Action: Create tests/test_smoke.py
|
|
140
|
+
def test_health_check():
|
|
141
|
+
assert True # Basic sanity check
|
|
142
|
+
`,
|
|
143
|
+
reference: "https://docs.pytest.org/",
|
|
144
|
+
whenItMatters: "팀원이 2명 이상으로 늘어나거나 배포 주기가 빨라질 때."
|
|
145
|
+
},
|
|
146
|
+
'RR-CI-001': {
|
|
147
|
+
title: "배포 자동화 파이프라인 부재 (Missing CI Pipeline)",
|
|
148
|
+
category: 'Service Interruption',
|
|
149
|
+
evidence: "GitHub Actions (.github/workflows/*.yml) 또는 CI 설정 파일이 없습니다.",
|
|
150
|
+
standard: "GitHub Actions Documentation",
|
|
151
|
+
impact: "사람의 수동 배포 과정에서 실수가 발생할 수 있으며, 일관된 배포 상태를 보장할 수 없습니다.",
|
|
152
|
+
action: `
|
|
153
|
+
# Action: Create .github/workflows/ci.yml
|
|
154
|
+
name: CI
|
|
155
|
+
on: [push]
|
|
156
|
+
jobs:
|
|
157
|
+
test:
|
|
158
|
+
runs-on: ubuntu-latest
|
|
159
|
+
steps:
|
|
160
|
+
- uses: actions/checkout@v3
|
|
161
|
+
- run: npm test
|
|
162
|
+
`,
|
|
163
|
+
reference: "https://docs.github.com/en/actions",
|
|
164
|
+
whenItMatters: "배포 빈도가 주 2회 이상으로 증가할 때."
|
|
165
|
+
},
|
|
166
|
+
'RR-OPS-001': {
|
|
167
|
+
title: "운영 기본 위생 체크 실패 (Project Hygiene)",
|
|
168
|
+
category: 'Service Interruption',
|
|
169
|
+
standard: "12-Factor App / Docker Documentation",
|
|
170
|
+
impact: "개발 환경과 운영 환경의 불일치로 인해 '내 컴퓨터에서는 되는데 서버에서는 안 되는' 문제가 발생합니다.",
|
|
171
|
+
action: `
|
|
172
|
+
# Checklist to Fix:
|
|
173
|
+
1. Create 'Dockerfile'
|
|
174
|
+
2. Create '.gitignore' (use gitignore.io)
|
|
175
|
+
3. Create 'requirements.txt' or 'package.json'
|
|
176
|
+
4. Create '.env.example'
|
|
177
|
+
`,
|
|
178
|
+
reference: "https://12factor.net/",
|
|
179
|
+
whenItMatters: "신규 입사자 온보딩 또는 서버 이관 시."
|
|
180
|
+
},
|
|
181
|
+
'RR-LOG-001': {
|
|
182
|
+
title: "로깅 설정 미흡 (Insufficient Logging)",
|
|
183
|
+
category: 'Maintenance',
|
|
184
|
+
evidence: "코드 내에서 로깅 설정(logging, loguru 등)이 발견되지 않았습니다.",
|
|
185
|
+
standard: "Python Logging Cookbook",
|
|
186
|
+
impact: "장애 발생 시 원인을 추적할 수 있는 데이터가 없어 해결 시간이 길어집니다.",
|
|
187
|
+
action: `
|
|
188
|
+
# Action: Python Logging Setup
|
|
189
|
+
import logging
|
|
190
|
+
logging.basicConfig(level=logging.INFO)
|
|
191
|
+
logger = logging.getLogger(__name__)
|
|
192
|
+
logger.info("Server started")
|
|
193
|
+
`,
|
|
194
|
+
reference: "https://docs.python.org/3/howto/logging-cookbook.html",
|
|
195
|
+
whenItMatters: "운영 중 알 수 없는 500 에러가 발생했을 때."
|
|
196
|
+
},
|
|
197
|
+
'RR-DEP-001': {
|
|
198
|
+
title: "구조적 의존성 결함 (Structural Dependency Issue)",
|
|
199
|
+
category: 'Scalability',
|
|
200
|
+
standard: "Clean Architecture: Dependency Rule",
|
|
201
|
+
impact: "모듈 간 결합도가 높아져 유지보수가 어려워지고, 사이드 이펙트가 발생하기 쉽습니다.",
|
|
202
|
+
action: "상호 참조하는 모듈을 분리하거나 공통 모듈로 추출하세요.",
|
|
203
|
+
reference: "https://refactoring.guru/design-patterns",
|
|
204
|
+
whenItMatters: "프로젝트 규모가 커질수록 리팩토링 비용이 기하급수적으로 증가합니다."
|
|
205
|
+
},
|
|
206
|
+
'RR-LINT-001': {
|
|
207
|
+
title: "거대 모듈 감지 (God Module)",
|
|
208
|
+
category: 'Maintenance',
|
|
209
|
+
standard: "Clean Code: Functions",
|
|
210
|
+
impact: "단일 파일의 책임이 과도하여 변경 시 영향 범위를 예측하기 어렵습니다.",
|
|
211
|
+
action: "책임에 따라 파일을 분리하세요 (Separation of Concerns).",
|
|
212
|
+
reference: "https://pypi.org/project/flake8/",
|
|
213
|
+
whenItMatters: "기능 추가 시마다 버그가 발생할 때."
|
|
214
|
+
},
|
|
215
|
+
'DEFAULT': {
|
|
216
|
+
title: "기타 잠재적 리스크 (Other Potential Risks)",
|
|
217
|
+
category: 'Maintenance',
|
|
218
|
+
standard: "General Coding Best Practices",
|
|
219
|
+
impact: "잠재적인 버그나 유지보수 어려움이 있을 수 있습니다.",
|
|
220
|
+
action: "해당 코드를 리뷰하고 리팩토링을 고려하세요.",
|
|
221
|
+
reference: "#",
|
|
222
|
+
whenItMatters: "지속적인 코드 품질 저하가 우려될 때."
|
|
223
|
+
},
|
|
224
|
+
'DISCLOSURE': "배포 전 감사가 완료되었습니다. 발견된 리스크들은 실제 운영 환경에서 예기치 못한 서비스 중단이나 데이터 손실을 야기할 수 있는 항목들입니다.",
|
|
225
|
+
'CTA': "배포 루틴 자동화를 위해 GitHub App을 설치하고 지속적인 배포 준비도(Release Readiness)를 관리하세요。"
|
|
226
|
+
}
|
|
227
|
+
};
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -14,8 +14,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.LOCALES = void 0;
|
|
17
18
|
__exportStar(require("./analyzer.js"), exports);
|
|
18
19
|
__exportStar(require("./aiDiagnosis.js"), exports);
|
|
19
20
|
__exportStar(require("./archScanner.js"), exports);
|
|
20
21
|
__exportStar(require("./repoAnalyzer.js"), exports);
|
|
21
22
|
__exportStar(require("./deepAnalysis.js"), exports);
|
|
23
|
+
__exportStar(require("./jsAnalyzer.js"), exports);
|
|
24
|
+
var locales_js_1 = require("./i18n/locales.js");
|
|
25
|
+
Object.defineProperty(exports, "LOCALES", { enumerable: true, get: function () { return locales_js_1.LOCALES; } });
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AnalysisResult } from './analyzer.js';
|
|
2
|
+
/**
|
|
3
|
+
* [The Eye] JS/TS Analysis Engine
|
|
4
|
+
*
|
|
5
|
+
* RegEx-based static analysis for JavaScript/TypeScript files.
|
|
6
|
+
* MVP: Focused on 8 specific credibility rules.
|
|
7
|
+
*/
|
|
8
|
+
export declare function analyzeJsTsCode(code: string, fileName: string): Promise<AnalysisResult>;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.analyzeJsTsCode = analyzeJsTsCode;
|
|
4
|
+
/**
|
|
5
|
+
* [The Eye] JS/TS Analysis Engine
|
|
6
|
+
*
|
|
7
|
+
* RegEx-based static analysis for JavaScript/TypeScript files.
|
|
8
|
+
* MVP: Focused on 8 specific credibility rules.
|
|
9
|
+
*/
|
|
10
|
+
async function analyzeJsTsCode(code, fileName) {
|
|
11
|
+
// 1. Architecture Health Scan (God Module / Large File)
|
|
12
|
+
const lines = code.split('\n');
|
|
13
|
+
if (lines.length > 800) {
|
|
14
|
+
return {
|
|
15
|
+
hasError: true,
|
|
16
|
+
error: `Large File Risk: ${lines.length} lines. Maintanability risk.`,
|
|
17
|
+
line: 1,
|
|
18
|
+
type: 'ProductionRisk',
|
|
19
|
+
file: fileName
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
// 2. Risk Scan (Security & Production Readiness)
|
|
23
|
+
const riskResult = scanForJsRisks(code, fileName, lines);
|
|
24
|
+
if (riskResult.hasError) {
|
|
25
|
+
return riskResult;
|
|
26
|
+
}
|
|
27
|
+
return { hasError: false };
|
|
28
|
+
}
|
|
29
|
+
function scanForJsRisks(code, fileName, lines) {
|
|
30
|
+
const risks = [
|
|
31
|
+
// Critical (🔴) - Security
|
|
32
|
+
{
|
|
33
|
+
pattern: /eval\s*\(|new\s+Function\s*\(/,
|
|
34
|
+
type: 'SecurityRisk',
|
|
35
|
+
message: '[Security] Dynamic code execution detected (eval/new Function). This is a severe security risk.'
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
pattern: /child_process\.(exec|execSync)\s*\(/,
|
|
39
|
+
type: 'SecurityRisk',
|
|
40
|
+
message: '[Security] Shell command execution detected. Ensure inputs are sanitized or use spawn without shell.'
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
pattern: /spawn\s*\(.*,\s*\{.*shell:\s*true/s, // Multi-line match attempt with DOTALL flag simulated or just simple check
|
|
44
|
+
type: 'SecurityRisk',
|
|
45
|
+
message: '[Security] spawn with { shell: true } detected. This enables shell command injection.'
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
pattern: /(?:api[._-]?key|password|secret|token)\s*[:=]\s*['"][a-zA-Z0-9_-]{10,}['"]/i,
|
|
49
|
+
type: 'SecurityRisk',
|
|
50
|
+
message: '[Security] Hardcoded secret detected. Use environment variables.'
|
|
51
|
+
},
|
|
52
|
+
// Warning (🟡) - Production Readiness
|
|
53
|
+
{
|
|
54
|
+
condition: (l) => /(axios(\.[a-z]+)?|fetch|http\.(get|request))\s*\(/.test(l) && !/timeout/.test(l),
|
|
55
|
+
type: 'ProductionRisk',
|
|
56
|
+
message: '[Reliability] HTTP call missing explicit timeout. This can cause cascading failures.'
|
|
57
|
+
},
|
|
58
|
+
// Heuristic: App listen but no global error handler (simplified: check for generic app.use((err... pattern)
|
|
59
|
+
{
|
|
60
|
+
condition: (c) => c.includes('app.listen') && !/app\.use\s*\(\s*\(\s*err/.test(c),
|
|
61
|
+
type: 'ProductionRisk',
|
|
62
|
+
message: '[Reliability] Express app detected but Global Error Handler missing. Unhandled errors may crash the server.'
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
pattern: /console\.log\s*\(/,
|
|
66
|
+
type: 'ProductionRisk',
|
|
67
|
+
message: '[Observability] console.log used in production code. Use a structured logger (winston/pino).'
|
|
68
|
+
}
|
|
69
|
+
];
|
|
70
|
+
// Line-based checks
|
|
71
|
+
for (let i = 0; i < lines.length; i++) {
|
|
72
|
+
const line = lines[i];
|
|
73
|
+
for (const risk of risks) {
|
|
74
|
+
// Pattern check
|
|
75
|
+
if (risk.pattern && risk.pattern.test(line)) {
|
|
76
|
+
// Skip comments for simple cases
|
|
77
|
+
if (line.trim().startsWith('//') || line.trim().startsWith('*'))
|
|
78
|
+
continue;
|
|
79
|
+
return {
|
|
80
|
+
hasError: true,
|
|
81
|
+
error: risk.message,
|
|
82
|
+
line: i + 1,
|
|
83
|
+
type: risk.type,
|
|
84
|
+
file: fileName
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// Line-based Condition check (special case for timeout)
|
|
88
|
+
// We distinguish global vs line condition by context?
|
|
89
|
+
// The 'app.listen' check is clearly global (checks whole code).
|
|
90
|
+
// The 'timeout' check is clearly line based (checks 'l').
|
|
91
|
+
// Let's rely on the message content to know if it is line-based for MVP simplicity
|
|
92
|
+
if (risk.condition && risk.message.includes('HTTP missing timeout') && risk.condition(line)) {
|
|
93
|
+
if (line.trim().startsWith('//') || line.trim().startsWith('*'))
|
|
94
|
+
continue;
|
|
95
|
+
return {
|
|
96
|
+
hasError: true,
|
|
97
|
+
error: risk.message,
|
|
98
|
+
line: i + 1,
|
|
99
|
+
type: risk.type,
|
|
100
|
+
file: fileName
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// File-based checks (Global patterns)
|
|
106
|
+
for (const risk of risks) {
|
|
107
|
+
// Global Condition check
|
|
108
|
+
if (risk.condition && !risk.message.includes('HTTP missing timeout') && risk.condition(code)) {
|
|
109
|
+
return {
|
|
110
|
+
hasError: true,
|
|
111
|
+
error: risk.message,
|
|
112
|
+
line: 0,
|
|
113
|
+
type: risk.type,
|
|
114
|
+
file: fileName
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
// Multi-line regex checks
|
|
118
|
+
if (risk.pattern && risk.pattern.flags.includes('s') && risk.pattern.test(code)) {
|
|
119
|
+
return {
|
|
120
|
+
hasError: true,
|
|
121
|
+
error: risk.message,
|
|
122
|
+
line: 0,
|
|
123
|
+
type: risk.type,
|
|
124
|
+
file: fileName
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return { hasError: false };
|
|
129
|
+
}
|
package/dist/repoAnalyzer.d.ts
CHANGED
|
@@ -25,16 +25,7 @@ export interface RepoAnalysisResult {
|
|
|
25
25
|
disclosure?: string;
|
|
26
26
|
cta?: string;
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
* CEO-ready "Business Translation" for technical risks
|
|
30
|
-
*/
|
|
31
|
-
/**
|
|
32
|
-
* 3-Tier Business Audit Translation
|
|
33
|
-
*/
|
|
34
|
-
/**
|
|
35
|
-
* 3-Tier Business Audit Translation with Standard IDs
|
|
36
|
-
*/
|
|
37
|
-
export declare function getAuditDetails(id: string, type: string, issue: string): {
|
|
28
|
+
export declare function getAuditDetails(id: string, type: string, issue: string, lang?: 'en' | 'ko'): {
|
|
38
29
|
id: string;
|
|
39
30
|
title: string;
|
|
40
31
|
category: RepoAnalysisResult['findings'][0]['category'];
|
|
@@ -45,4 +36,7 @@ export declare function getAuditDetails(id: string, type: string, issue: string)
|
|
|
45
36
|
reference: string;
|
|
46
37
|
whenItMatters: string;
|
|
47
38
|
};
|
|
48
|
-
export declare function analyzeRepository(repoPath: string,
|
|
39
|
+
export declare function analyzeRepository(repoPath: string, options?: {
|
|
40
|
+
lang?: 'en' | 'ko';
|
|
41
|
+
resultsDir?: string;
|
|
42
|
+
}): Promise<RepoAnalysisResult>;
|