@nine-lab/nine-mu 0.1.360 → 0.1.362
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/nine-mu.js +48 -40
- package/dist/nine-mu.js.map +1 -1
- package/dist/nine-mu.umd.js +1 -1
- package/dist/nine-mu.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/exception/ExceptionHook.js +53 -37
package/package.json
CHANGED
|
@@ -9,57 +9,62 @@ export const NineExceptionStyles = {
|
|
|
9
9
|
flexGrow: 1,
|
|
10
10
|
padding: '25px',
|
|
11
11
|
background: '#121314',
|
|
12
|
-
// ⭐ 모든 요소가 완벽한 터미널 정렬을 갖추도록 고정폭 서체를 부모에 강제 주입
|
|
13
12
|
fontFamily: 'Consolas, Monaco, "Courier New", monospace',
|
|
14
13
|
textAlign: 'left',
|
|
15
14
|
boxShadow: '0 4px 12px rgba(0,0,0,0.3)',
|
|
16
|
-
|
|
17
|
-
// 내부 라인들을 인라인 텍스트 흐름처럼 촘촘하게 쌓기 위해 flex 간격 조정
|
|
18
15
|
display: 'flex',
|
|
19
16
|
flexDirection: 'column',
|
|
20
|
-
gap: '10px',
|
|
21
|
-
|
|
17
|
+
gap: '10px',
|
|
18
|
+
// ⭐ 수정: 아까 보기 좋았던 넉넉하고 정돈된 줄간격 비율로 복구
|
|
19
|
+
lineHeight: '1.5'
|
|
22
20
|
},
|
|
21
|
+
// 1. 모든 라인의 display 형식을 'block'으로 맞추고 마진/패딩을 0으로 통일
|
|
23
22
|
systemError: {
|
|
24
|
-
color: '#999',
|
|
23
|
+
color: '#999',
|
|
25
24
|
fontWeight: 'bold',
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
padding: '0'
|
|
25
|
+
margin: '0',
|
|
26
|
+
padding: '0',
|
|
27
|
+
display: 'block'
|
|
30
28
|
},
|
|
29
|
+
// 2. 에러 본문 텍스트도 불필요한 속성을 다 버리고 일반 라인과 똑같이 흐르게 교정
|
|
31
30
|
pre: {
|
|
32
31
|
background: 'transparent',
|
|
33
|
-
color: '#666',
|
|
32
|
+
color: '#666', // aa is not defined는 요청하신 #666 적용
|
|
34
33
|
padding: '0',
|
|
35
|
-
margin: '0',
|
|
34
|
+
margin: '0',
|
|
36
35
|
border: 'none',
|
|
37
36
|
overflowX: 'auto',
|
|
38
37
|
whiteSpace: 'pre-wrap',
|
|
39
|
-
fontFamily: '
|
|
40
|
-
fontSize: '
|
|
38
|
+
fontFamily: 'inherit', // 부모 폰트 그대로 상속
|
|
39
|
+
fontSize: 'inherit', // 부모 크기 그대로 상속
|
|
41
40
|
display: 'block'
|
|
42
41
|
},
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
// 3. 에러 위치 추적 라인
|
|
43
|
+
locationRow: {
|
|
45
44
|
color: '#999',
|
|
46
45
|
margin: '0',
|
|
47
46
|
padding: '0',
|
|
48
|
-
display: '
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
display: 'block',
|
|
48
|
+
fontFamily: 'inherit',
|
|
49
|
+
fontSize: 'inherit'
|
|
50
|
+
},
|
|
51
|
+
// 4. 하단 영역의 flex와 gap을 완전히 제거하여 줄간격 왜곡 원천 차단
|
|
52
|
+
footer: {
|
|
53
|
+
margin: '0',
|
|
54
|
+
padding: '0',
|
|
55
|
+
display: 'block'
|
|
51
56
|
},
|
|
52
57
|
promptRow: {
|
|
53
58
|
margin: '0',
|
|
54
59
|
padding: '0',
|
|
55
60
|
display: 'block',
|
|
56
|
-
color: '#999'
|
|
61
|
+
color: '#999'
|
|
57
62
|
},
|
|
58
63
|
cliLink: {
|
|
59
|
-
color: '#38A169',
|
|
60
|
-
padding: '0
|
|
61
|
-
fontFamily: '
|
|
62
|
-
fontSize: '
|
|
64
|
+
color: '#38A169', // y 링크 터미널 그린
|
|
65
|
+
padding: '0',
|
|
66
|
+
fontFamily: 'inherit',
|
|
67
|
+
fontSize: 'inherit',
|
|
63
68
|
fontWeight: 'bold',
|
|
64
69
|
cursor: 'pointer',
|
|
65
70
|
textDecoration: 'underline',
|
|
@@ -154,17 +159,27 @@ export class NineExceptionHook extends React.Component {
|
|
|
154
159
|
const errorMessage = this.state.error?.message || String(this.state.error);
|
|
155
160
|
const customStyles = this.props.styles || {};
|
|
156
161
|
|
|
157
|
-
// 🔍 React 컴포넌트 스택에서 파일명과 라인 번호
|
|
162
|
+
// 🔍 React 컴포넌트 스택에서 파일명과 라인 번호 추출
|
|
163
|
+
// 🔍 React 컴포넌트 스택에서 파일명과 라인 번호 추출기 (경로 정밀 정제 버전)
|
|
158
164
|
let errorLocation = '';
|
|
159
165
|
if (this.state.errorInfo?.componentStack) {
|
|
160
|
-
// 스택 트레이스 문자열에서 실제 파일 경로가 포함된 첫 줄을 타겟팅합니다.
|
|
161
166
|
const lines = this.state.errorInfo.componentStack.trim().split('\n');
|
|
162
167
|
const targetLine = lines[0] || '';
|
|
163
168
|
|
|
164
|
-
//
|
|
169
|
+
// 1. 기존 방식대로 컴포넌트 이름과 전체 경로를 먼저 매칭합니다.
|
|
165
170
|
const match = targetLine.match(/at\s+(\w+)\s+\((.*)\)/) || targetLine.match(/at\s+(.*)/);
|
|
166
171
|
if (match) {
|
|
167
|
-
|
|
172
|
+
const componentName = match[1];
|
|
173
|
+
let rawPath = match[2] || '';
|
|
174
|
+
|
|
175
|
+
// 2. ⭐ 핵심: 경로에서 'http://localhost:5173/admin' 또는 'http://.../any-path' 파트를 찾아 통째로 날려버립니다.
|
|
176
|
+
if (rawPath.includes('http://') || rawPath.includes('https://')) {
|
|
177
|
+
// URL 객체나 정규식을 이용해 도메인 영역을 지우고 /src 포맷만 남깁니다.
|
|
178
|
+
rawPath = rawPath.replace(/^https?:\/\/[^\/]+/, '');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// 3. 컴포넌트 이름 뒤에 깔끔해진 /src 경로만 붙여줍니다.
|
|
182
|
+
errorLocation = rawPath ? `${componentName} (${rawPath})` : componentName;
|
|
168
183
|
} else {
|
|
169
184
|
errorLocation = targetLine.trim();
|
|
170
185
|
}
|
|
@@ -176,24 +191,24 @@ export class NineExceptionHook extends React.Component {
|
|
|
176
191
|
style: { ...NineExceptionStyles.container, ...customStyles.container, ...this.props.containerStyle }
|
|
177
192
|
},
|
|
178
193
|
|
|
179
|
-
// 1.
|
|
194
|
+
// 1. [SYSTEM] 라인
|
|
180
195
|
React.createElement(
|
|
181
196
|
'div',
|
|
182
197
|
{ style: { ...NineExceptionStyles.systemError, ...customStyles.systemError } },
|
|
183
198
|
'[SYSTEM] COMPONENT RENDER ERROR DETECTED'
|
|
184
199
|
),
|
|
185
200
|
|
|
186
|
-
// 2.
|
|
201
|
+
// 2. aa is not defined 라인
|
|
187
202
|
React.createElement('pre', { style: { ...NineExceptionStyles.pre, ...customStyles.pre } }, errorMessage),
|
|
188
203
|
|
|
189
|
-
//
|
|
204
|
+
// 3. at MemberUsers 라인
|
|
190
205
|
errorLocation && React.createElement(
|
|
191
206
|
'div',
|
|
192
|
-
{ style: {
|
|
207
|
+
{ style: { ...NineExceptionStyles.locationRow, ...customStyles.locationRow } },
|
|
193
208
|
` at ${errorLocation}`
|
|
194
209
|
),
|
|
195
210
|
|
|
196
|
-
// 4. CLI 프롬프트 영역
|
|
211
|
+
// 4. CLI 프롬프트 및 후속 결과 라인 영역
|
|
197
212
|
React.createElement(
|
|
198
213
|
'div',
|
|
199
214
|
{ style: { ...NineExceptionStyles.footer, ...customStyles.footer } },
|
|
@@ -213,17 +228,18 @@ export class NineExceptionHook extends React.Component {
|
|
|
213
228
|
React.createElement('span', null, '/n)?')
|
|
214
229
|
),
|
|
215
230
|
|
|
231
|
+
// display: 'block'과 margin/padding 0을 주어 다른 라인들과 오차 없이 간격을 맞춤
|
|
216
232
|
this.state.reportStatus === 'sending' && React.createElement(
|
|
217
233
|
'div',
|
|
218
|
-
{ style: { color: '#ED8936', margin: '0',
|
|
234
|
+
{ style: { color: '#ED8936', margin: '0', padding: '0', display: 'block' } },
|
|
219
235
|
'>> Connecting to Control Tower... Sending payload.'
|
|
220
236
|
),
|
|
221
237
|
|
|
222
238
|
this.state.reportStatus === 'success' && React.createElement(
|
|
223
239
|
'div',
|
|
224
|
-
{ style: {
|
|
225
|
-
React.createElement('div', { style: { color: '#38A169', fontWeight: 'bold',
|
|
226
|
-
React.createElement('div', { style: { color: '#A0AEC0', fontStyle: 'italic', fontSize: '13px',
|
|
240
|
+
{ style: { margin: '0', padding: '0', display: 'block' } },
|
|
241
|
+
React.createElement('div', { style: { color: '#38A169', fontWeight: 'bold', display: 'block', margin: '0' } }, '>> Transmit complete. Core engine initialized.'),
|
|
242
|
+
React.createElement('div', { style: { color: '#A0AEC0', fontStyle: 'italic', fontSize: '13px', display: 'block', margin: '4px 0 0 0' } }, 'AI가 소스 코드를 재수정하는 동안 잠시만 기다려주세요...')
|
|
227
243
|
)
|
|
228
244
|
)
|
|
229
245
|
);
|