@gz-fronted/gz-pc 0.1.3-beta.0 → 0.1.3-beta.2

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.
@@ -11,11 +11,12 @@ var axios__default = /*#__PURE__*/_interopDefault(axios);
11
11
 
12
12
  // src/fetch/client.ts
13
13
 
14
- // src/fetch/debug.ts
14
+ // src/fetch/feedback/debug-store.ts
15
15
  var EMPTY_DEBUG_DRAWER_SNAPSHOT = {
16
16
  activeHostId: void 0,
17
17
  errors: [],
18
- open: false
18
+ open: false,
19
+ selectedErrorId: void 0
19
20
  };
20
21
  var debugErrorSequence = 0;
21
22
  var snapshot = EMPTY_DEBUG_DRAWER_SNAPSHOT;
@@ -30,29 +31,6 @@ var setSnapshot = (nextSnapshot) => {
30
31
  snapshot = nextSnapshot;
31
32
  emitChange();
32
33
  };
33
- var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
34
- var getResponseDebugInfo = (responseData) => {
35
- if (!isRecord(responseData) || !isRecord(responseData.debug)) {
36
- return void 0;
37
- }
38
- return responseData.debug;
39
- };
40
- var isDebugEnabled = () => {
41
- if (typeof window === "undefined") {
42
- return false;
43
- }
44
- try {
45
- if (new URLSearchParams(window.location.search).get("showDebug") === "1") {
46
- return true;
47
- }
48
- } catch (e) {
49
- }
50
- try {
51
- return window.localStorage.getItem("showDebug") === "1";
52
- } catch (e) {
53
- return false;
54
- }
55
- };
56
34
  var subscribeDebugDrawer = (listener) => {
57
35
  listeners.add(listener);
58
36
  return () => listeners.delete(listener);
@@ -76,21 +54,20 @@ var registerDebugDrawerHost = (hostId) => {
76
54
  });
77
55
  };
78
56
  };
79
- var showFetchDebugError = (input) => {
57
+ var appendDebugError = (input) => {
80
58
  if (snapshot.activeHostId === void 0) {
81
59
  return false;
82
60
  }
83
61
  debugErrorSequence += 1;
62
+ const error = {
63
+ ...input,
64
+ id: `${Date.now()}-${debugErrorSequence}`
65
+ };
84
66
  setSnapshot({
85
67
  ...snapshot,
86
- errors: [
87
- ...snapshot.errors,
88
- {
89
- ...input,
90
- id: `${Date.now()}-${debugErrorSequence}`
91
- }
92
- ],
93
- open: true
68
+ errors: [error, ...snapshot.errors],
69
+ open: true,
70
+ selectedErrorId: error.id
94
71
  });
95
72
  return true;
96
73
  };
@@ -100,15 +77,646 @@ var closeDebugDrawer = () => {
100
77
  }
101
78
  };
102
79
  var removeDebugError = (id) => {
80
+ var _a, _b, _c, _d;
81
+ const removedIndex = snapshot.errors.findIndex((error) => error.id === id);
82
+ if (removedIndex === -1) {
83
+ return;
84
+ }
85
+ const errors = snapshot.errors.filter((error) => error.id !== id);
86
+ const selectedErrorId = snapshot.selectedErrorId === id ? (_c = (_a = errors[removedIndex]) == null ? void 0 : _a.id) != null ? _c : (_b = errors[removedIndex - 1]) == null ? void 0 : _b.id : snapshot.selectedErrorId && errors.some((error) => error.id === snapshot.selectedErrorId) ? snapshot.selectedErrorId : (_d = errors[0]) == null ? void 0 : _d.id;
103
87
  setSnapshot({
104
88
  ...snapshot,
105
- errors: snapshot.errors.filter((error) => error.id !== id)
89
+ errors,
90
+ selectedErrorId
106
91
  });
107
92
  };
93
+ var selectDebugError = (id) => {
94
+ if (snapshot.selectedErrorId === id || !snapshot.errors.some((error) => error.id === id)) {
95
+ return;
96
+ }
97
+ setSnapshot({ ...snapshot, selectedErrorId: id });
98
+ };
108
99
  var clearDebugErrors = () => {
109
100
  if (snapshot.errors.length > 0) {
110
- setSnapshot({ ...snapshot, errors: [] });
101
+ setSnapshot({ ...snapshot, errors: [], selectedErrorId: void 0 });
102
+ }
103
+ };
104
+ var feedbackHosts = /* @__PURE__ */ new Map();
105
+ var activeHostId;
106
+ var registerFeedbackHost = (hostId, host) => {
107
+ feedbackHosts.set(hostId, host);
108
+ activeHostId != null ? activeHostId : activeHostId = hostId;
109
+ return () => {
110
+ feedbackHosts.delete(hostId);
111
+ if (activeHostId !== hostId) {
112
+ return;
113
+ }
114
+ const nextHost = feedbackHosts.keys().next();
115
+ activeHostId = nextHost.done ? void 0 : nextHost.value;
116
+ };
117
+ };
118
+ var showFeedbackErrorMessage = (content) => {
119
+ const activeHost = activeHostId === void 0 ? void 0 : feedbackHosts.get(activeHostId);
120
+ if (activeHost) {
121
+ activeHost.showErrorMessage(content);
122
+ return;
123
+ }
124
+ ggUi.message.error(content);
125
+ };
126
+ var showFeedbackSuccessMessage = (content) => {
127
+ const activeHost = activeHostId === void 0 ? void 0 : feedbackHosts.get(activeHostId);
128
+ if (activeHost == null ? void 0 : activeHost.showSuccessMessage) {
129
+ activeHost.showSuccessMessage(content);
130
+ return;
131
+ }
132
+ ggUi.message.success(content);
133
+ };
134
+ var EMPTY_DEBUG_VALUE = "(无)";
135
+ var formatDebugValue = (value) => {
136
+ if (typeof value === "string") {
137
+ return value;
138
+ }
139
+ if (value === void 0 || value === null) {
140
+ return EMPTY_DEBUG_VALUE;
141
+ }
142
+ try {
143
+ const serialized = JSON.stringify(value, null, 2);
144
+ return serialized != null ? serialized : "(无法序列化)";
145
+ } catch (e) {
146
+ return "(无法序列化)";
147
+ }
148
+ };
149
+ var formatCompleteDebugResponse = (error) => error.responseData === void 0 ? void 0 : formatDebugValue(error.responseData);
150
+ var copyDebugText = async (text) => {
151
+ var _a;
152
+ try {
153
+ if (typeof navigator !== "undefined" && ((_a = navigator.clipboard) == null ? void 0 : _a.writeText)) {
154
+ await navigator.clipboard.writeText(text);
155
+ return true;
156
+ }
157
+ } catch (e) {
158
+ }
159
+ if (typeof document === "undefined" || !document.body || typeof document.execCommand !== "function") {
160
+ return false;
161
+ }
162
+ const textarea = document.createElement("textarea");
163
+ textarea.value = text;
164
+ textarea.setAttribute("readonly", "");
165
+ textarea.style.position = "fixed";
166
+ textarea.style.opacity = "0";
167
+ document.body.appendChild(textarea);
168
+ let copied = false;
169
+ try {
170
+ textarea.focus();
171
+ textarea.select();
172
+ copied = document.execCommand("copy");
173
+ } catch (e) {
174
+ copied = false;
175
+ } finally {
176
+ document.body.removeChild(textarea);
111
177
  }
178
+ return copied;
179
+ };
180
+ var codeBlockStyle = {
181
+ background: "var(--gz-color-bg-field, rgba(127, 127, 127, 0.08))",
182
+ border: "0",
183
+ borderRadius: 6,
184
+ boxSizing: "border-box",
185
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
186
+ lineHeight: 1.5,
187
+ margin: 0,
188
+ minHeight: 0,
189
+ overflow: "auto",
190
+ overflowWrap: "anywhere",
191
+ padding: 16,
192
+ whiteSpace: "pre-wrap"
193
+ };
194
+ var methodTagColors = {
195
+ DELETE: "red",
196
+ GET: "green",
197
+ PATCH: "purple",
198
+ POST: "gold",
199
+ PUT: "blue"
200
+ };
201
+ var getHttpMethodTagColor = (method) => {
202
+ const normalizedMethod = method == null ? void 0 : method.toUpperCase();
203
+ return normalizedMethod === void 0 ? void 0 : methodTagColors[normalizedMethod];
204
+ };
205
+ var HttpMethodTag = ({ method }) => {
206
+ var _a;
207
+ const normalizedMethod = (_a = method == null ? void 0 : method.toUpperCase()) != null ? _a : "--";
208
+ const color = getHttpMethodTagColor(method);
209
+ return color ? /* @__PURE__ */ jsxRuntime.jsx(ggUi.Tag, { color, children: normalizedMethod }) : /* @__PURE__ */ jsxRuntime.jsx(ggUi.Tag, { children: normalizedMethod });
210
+ };
211
+ var DebugCodeBlock = ({ onCopy, value }) => {
212
+ const canCopy = value !== void 0 && value !== null;
213
+ return /* @__PURE__ */ jsxRuntime.jsxs(
214
+ "div",
215
+ {
216
+ style: {
217
+ height: "100%",
218
+ minHeight: 0,
219
+ overflow: "auto",
220
+ position: "relative"
221
+ },
222
+ children: [
223
+ canCopy ? /* @__PURE__ */ jsxRuntime.jsx(ggUi.Tooltip, { title: "复制", children: /* @__PURE__ */ jsxRuntime.jsx(
224
+ ggUi.Button,
225
+ {
226
+ "aria-label": "复制",
227
+ size: "middle",
228
+ style: {
229
+ paddingInline: 12,
230
+ position: "absolute",
231
+ right: 8,
232
+ top: 8,
233
+ zIndex: 1
234
+ },
235
+ type: "primary",
236
+ onClick: onCopy,
237
+ children: "复制"
238
+ }
239
+ ) }) : null,
240
+ /* @__PURE__ */ jsxRuntime.jsx(
241
+ "pre",
242
+ {
243
+ style: {
244
+ ...codeBlockStyle,
245
+ paddingRight: canCopy ? 88 : codeBlockStyle.padding
246
+ },
247
+ children: formatDebugValue(value)
248
+ }
249
+ )
250
+ ]
251
+ }
252
+ );
253
+ };
254
+ var DebugErrorListItem = ({ error, index, selected, total }) => {
255
+ var _a, _b;
256
+ const handleRemove = (event) => {
257
+ event.stopPropagation();
258
+ removeDebugError(error.id);
259
+ };
260
+ const handleKeyDown = (event) => {
261
+ if (event.key === "Enter" || event.key === " ") {
262
+ event.preventDefault();
263
+ selectDebugError(error.id);
264
+ }
265
+ };
266
+ return /* @__PURE__ */ jsxRuntime.jsxs(
267
+ "div",
268
+ {
269
+ "aria-selected": selected,
270
+ role: "button",
271
+ tabIndex: 0,
272
+ title: error.url,
273
+ onClick: () => selectDebugError(error.id),
274
+ onKeyDown: handleKeyDown,
275
+ style: {
276
+ background: selected ? "var(--gz-color-bg-field, rgba(127, 127, 127, 0.12))" : "transparent",
277
+ borderRadius: 6,
278
+ cursor: "pointer",
279
+ display: "flex",
280
+ flexDirection: "column",
281
+ gap: 6,
282
+ margin: "0 8px",
283
+ minWidth: 0,
284
+ padding: "10px 8px",
285
+ position: "relative"
286
+ },
287
+ children: [
288
+ /* @__PURE__ */ jsxRuntime.jsx(
289
+ "span",
290
+ {
291
+ "aria-hidden": "true",
292
+ style: {
293
+ background: selected ? "var(--gz-color-primary, var(--gz-color-primary-border, rgba(127, 127, 127, 0.24)))" : "transparent",
294
+ borderRadius: 2,
295
+ bottom: 8,
296
+ left: 0,
297
+ pointerEvents: "none",
298
+ position: "absolute",
299
+ top: 8,
300
+ width: 3
301
+ }
302
+ }
303
+ ),
304
+ /* @__PURE__ */ jsxRuntime.jsxs(
305
+ "div",
306
+ {
307
+ style: {
308
+ alignItems: "center",
309
+ display: "flex",
310
+ gap: 8,
311
+ minWidth: 0
312
+ },
313
+ children: [
314
+ /* @__PURE__ */ jsxRuntime.jsxs(
315
+ "span",
316
+ {
317
+ style: { color: "var(--gz-color-text-secondary)", flex: "0 0 auto" },
318
+ children: [
319
+ "#",
320
+ total - index
321
+ ]
322
+ }
323
+ ),
324
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { flex: "0 0 58px", minWidth: 58 }, children: /* @__PURE__ */ jsxRuntime.jsx(HttpMethodTag, { method: error.method }) }),
325
+ /* @__PURE__ */ jsxRuntime.jsx(
326
+ "span",
327
+ {
328
+ style: {
329
+ display: "block",
330
+ flex: "1 1 auto",
331
+ minWidth: 0,
332
+ overflow: "hidden"
333
+ },
334
+ children: /* @__PURE__ */ jsxRuntime.jsx(ggUi.Tooltip, { title: (_a = error.url) != null ? _a : "--", children: /* @__PURE__ */ jsxRuntime.jsx(
335
+ "code",
336
+ {
337
+ style: {
338
+ color: "var(--gz-color-text-secondary)",
339
+ direction: "rtl",
340
+ display: "block",
341
+ minWidth: 0,
342
+ overflow: "hidden",
343
+ textAlign: "left",
344
+ textOverflow: "ellipsis",
345
+ whiteSpace: "nowrap"
346
+ },
347
+ children: (_b = error.url) != null ? _b : "--"
348
+ }
349
+ ) })
350
+ }
351
+ ),
352
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { flex: "0 0 24px", width: 24 }, children: /* @__PURE__ */ jsxRuntime.jsx(ggUi.Tooltip, { title: "关闭此条", children: /* @__PURE__ */ jsxRuntime.jsx(
353
+ ggUi.Button,
354
+ {
355
+ "aria-label": "关闭此条",
356
+ size: "small",
357
+ style: { padding: 0, width: 24 },
358
+ type: "text",
359
+ onClick: handleRemove,
360
+ children: "×"
361
+ }
362
+ ) }) })
363
+ ]
364
+ }
365
+ ),
366
+ /* @__PURE__ */ jsxRuntime.jsx(
367
+ "div",
368
+ {
369
+ style: {
370
+ display: "-webkit-box",
371
+ overflow: "hidden",
372
+ overflowWrap: "anywhere",
373
+ WebkitBoxOrient: "vertical",
374
+ WebkitLineClamp: 2
375
+ },
376
+ children: error.message
377
+ }
378
+ )
379
+ ]
380
+ }
381
+ );
382
+ };
383
+ var debugTabKeys = ["request", "stackTrace", "mdc"];
384
+ var isDebugTabKey = (value) => debugTabKeys.includes(value);
385
+ var DebugErrorDetails = ({
386
+ error
387
+ }) => {
388
+ var _a, _b;
389
+ const [activeTab, setActiveTab] = react.useState("request");
390
+ const values = {
391
+ mdc: error.debug.mdc,
392
+ request: error.debug.request,
393
+ stackTrace: error.debug.stackTrace
394
+ };
395
+ const handleCopy = async (value) => {
396
+ if (value === void 0 || value === null) {
397
+ return;
398
+ }
399
+ const copied = await copyDebugText(formatDebugValue(value));
400
+ if (copied) {
401
+ showFeedbackSuccessMessage("已复制");
402
+ return;
403
+ }
404
+ showFeedbackErrorMessage("复制失败");
405
+ };
406
+ const handleCopyCompleteResponse = async () => {
407
+ const responseText = formatCompleteDebugResponse(error);
408
+ if (responseText === void 0) {
409
+ return;
410
+ }
411
+ const copied = await copyDebugText(responseText);
412
+ if (copied) {
413
+ showFeedbackSuccessMessage("完整响应信息已复制");
414
+ return;
415
+ }
416
+ showFeedbackErrorMessage("复制失败");
417
+ };
418
+ return /* @__PURE__ */ jsxRuntime.jsxs(
419
+ "div",
420
+ {
421
+ style: {
422
+ display: "flex",
423
+ flexDirection: "column",
424
+ height: "100%",
425
+ minHeight: 0,
426
+ minWidth: 0
427
+ },
428
+ children: [
429
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: "0 0 auto", marginBottom: 16, minWidth: 0 }, children: [
430
+ /* @__PURE__ */ jsxRuntime.jsxs(
431
+ "div",
432
+ {
433
+ style: {
434
+ alignItems: "flex-start",
435
+ display: "flex",
436
+ gap: 8,
437
+ minWidth: 0
438
+ },
439
+ children: [
440
+ /* @__PURE__ */ jsxRuntime.jsx(
441
+ "strong",
442
+ {
443
+ style: {
444
+ display: "block",
445
+ flex: "1 1 auto",
446
+ fontSize: 16,
447
+ minWidth: 0,
448
+ overflowWrap: "anywhere"
449
+ },
450
+ children: error.message
451
+ }
452
+ ),
453
+ error.responseData === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ggUi.Tooltip, { title: "复制完整响应信息", children: /* @__PURE__ */ jsxRuntime.jsx(
454
+ ggUi.Button,
455
+ {
456
+ "aria-label": "复制完整响应信息",
457
+ size: "middle",
458
+ style: { flex: "0 0 auto", paddingInline: 12 },
459
+ type: "primary",
460
+ onClick: () => {
461
+ void handleCopyCompleteResponse();
462
+ },
463
+ children: "复制完整响应"
464
+ }
465
+ ) })
466
+ ]
467
+ }
468
+ ),
469
+ /* @__PURE__ */ jsxRuntime.jsxs(
470
+ "div",
471
+ {
472
+ style: {
473
+ alignItems: "center",
474
+ display: "flex",
475
+ gap: 8,
476
+ marginTop: 8,
477
+ minWidth: 0
478
+ },
479
+ children: [
480
+ /* @__PURE__ */ jsxRuntime.jsx(HttpMethodTag, { method: error.method }),
481
+ /* @__PURE__ */ jsxRuntime.jsx(
482
+ "code",
483
+ {
484
+ style: {
485
+ color: "var(--gz-color-text-secondary)",
486
+ display: "block",
487
+ minWidth: 0,
488
+ overflow: "hidden",
489
+ textOverflow: "ellipsis",
490
+ whiteSpace: "nowrap"
491
+ },
492
+ title: (_a = error.url) != null ? _a : "--",
493
+ children: (_b = error.url) != null ? _b : "--"
494
+ }
495
+ )
496
+ ]
497
+ }
498
+ )
499
+ ] }),
500
+ /* @__PURE__ */ jsxRuntime.jsx(
501
+ ggUi.Tabs,
502
+ {
503
+ activeKey: activeTab,
504
+ items: [
505
+ {
506
+ children: /* @__PURE__ */ jsxRuntime.jsx(
507
+ DebugCodeBlock,
508
+ {
509
+ onCopy: () => {
510
+ void handleCopy(values.request);
511
+ },
512
+ value: values.request
513
+ }
514
+ ),
515
+ key: "request",
516
+ label: "Request"
517
+ },
518
+ {
519
+ children: /* @__PURE__ */ jsxRuntime.jsx(
520
+ DebugCodeBlock,
521
+ {
522
+ onCopy: () => {
523
+ void handleCopy(values.stackTrace);
524
+ },
525
+ value: values.stackTrace
526
+ }
527
+ ),
528
+ key: "stackTrace",
529
+ label: "Stack Trace"
530
+ },
531
+ {
532
+ children: /* @__PURE__ */ jsxRuntime.jsx(
533
+ DebugCodeBlock,
534
+ {
535
+ onCopy: () => {
536
+ void handleCopy(values.mdc);
537
+ },
538
+ value: values.mdc
539
+ }
540
+ ),
541
+ key: "mdc",
542
+ label: "MDC"
543
+ }
544
+ ],
545
+ style: {
546
+ display: "flex",
547
+ flexDirection: "column",
548
+ height: "100%",
549
+ minHeight: 0
550
+ },
551
+ onChange: (key) => {
552
+ if (isDebugTabKey(key)) {
553
+ setActiveTab(key);
554
+ }
555
+ }
556
+ }
557
+ )
558
+ ]
559
+ }
560
+ );
561
+ };
562
+ var DebugErrorDrawer = () => {
563
+ var _a, _b;
564
+ const hostIdRef = react.useRef(void 0);
565
+ (_a = hostIdRef.current) != null ? _a : hostIdRef.current = /* @__PURE__ */ Symbol("gz-debug-feedback-drawer-host");
566
+ const hostId = hostIdRef.current;
567
+ const snapshot3 = react.useSyncExternalStore(
568
+ subscribeDebugDrawer,
569
+ getDebugDrawerSnapshot,
570
+ getDebugDrawerServerSnapshot
571
+ );
572
+ react.useEffect(() => registerDebugDrawerHost(hostId), [hostId]);
573
+ if (snapshot3.activeHostId !== hostId) {
574
+ return null;
575
+ }
576
+ const selectedError = (_b = snapshot3.errors.find((error) => error.id === snapshot3.selectedErrorId)) != null ? _b : snapshot3.errors[0];
577
+ return /* @__PURE__ */ jsxRuntime.jsx(
578
+ ggUi.Drawer,
579
+ {
580
+ open: snapshot3.open,
581
+ placement: "right",
582
+ styles: { body: { overflow: "hidden", padding: 0 } },
583
+ title: `Debug Error (${snapshot3.errors.length})`,
584
+ extra: /* @__PURE__ */ jsxRuntime.jsx(
585
+ ggUi.Button,
586
+ {
587
+ disabled: snapshot3.errors.length === 0,
588
+ size: "middle",
589
+ style: { paddingInline: 12 },
590
+ type: "default",
591
+ onClick: clearDebugErrors,
592
+ children: "清空记录"
593
+ }
594
+ ),
595
+ width: "min(calc(100vw - 32px), clamp(720px, 80vw, 1120px))",
596
+ onClose: closeDebugDrawer,
597
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
598
+ "div",
599
+ {
600
+ style: {
601
+ display: "flex",
602
+ height: "100%",
603
+ minHeight: 0,
604
+ minWidth: 0
605
+ },
606
+ children: [
607
+ /* @__PURE__ */ jsxRuntime.jsx(
608
+ "aside",
609
+ {
610
+ "aria-label": "Debug Error 列表",
611
+ style: {
612
+ borderRight: "1px solid var(--gz-color-border, rgba(127, 127, 127, 0.24))",
613
+ flex: "0 1 clamp(220px, 24vw, 320px)",
614
+ minHeight: 0,
615
+ overflowY: "auto",
616
+ padding: "6px 0",
617
+ width: "clamp(220px, 24vw, 320px)"
618
+ },
619
+ children: snapshot3.errors.length > 0 ? snapshot3.errors.map((error, index) => /* @__PURE__ */ jsxRuntime.jsx(
620
+ DebugErrorListItem,
621
+ {
622
+ error,
623
+ index,
624
+ selected: error.id === (selectedError == null ? void 0 : selectedError.id),
625
+ total: snapshot3.errors.length
626
+ },
627
+ error.id
628
+ )) : /* @__PURE__ */ jsxRuntime.jsx(
629
+ "div",
630
+ {
631
+ style: {
632
+ color: "var(--gz-color-text-secondary)",
633
+ padding: 16,
634
+ textAlign: "center"
635
+ },
636
+ children: "暂无 Debug Error"
637
+ }
638
+ )
639
+ }
640
+ ),
641
+ /* @__PURE__ */ jsxRuntime.jsx(
642
+ "main",
643
+ {
644
+ "aria-label": "Debug Error 详情",
645
+ style: {
646
+ flex: "1 1 auto",
647
+ minHeight: 0,
648
+ minWidth: 0,
649
+ overflow: "hidden",
650
+ padding: 20
651
+ },
652
+ children: selectedError ? /* @__PURE__ */ jsxRuntime.jsx(DebugErrorDetails, { error: selectedError }, selectedError.id) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "var(--gz-color-text-secondary)" }, children: "暂无 Debug Error" })
653
+ }
654
+ )
655
+ ]
656
+ }
657
+ )
658
+ }
659
+ );
660
+ };
661
+ DebugErrorDrawer.displayName = "DebugErrorDrawer";
662
+ var DebugErrorDrawer_default = DebugErrorDrawer;
663
+ var GzDebugFeedbackProvider = ({ children }) => {
664
+ var _a;
665
+ const hostIdRef = react.useRef(void 0);
666
+ (_a = hostIdRef.current) != null ? _a : hostIdRef.current = /* @__PURE__ */ Symbol("gz-debug-feedback-host");
667
+ const hostId = hostIdRef.current;
668
+ const [messageApi, messageContextHolder] = ggUi.message.useMessage();
669
+ const showErrorMessage = react.useCallback(
670
+ (content) => {
671
+ void messageApi.error(content);
672
+ },
673
+ [messageApi]
674
+ );
675
+ const showSuccessMessage = react.useCallback(
676
+ (content) => {
677
+ void messageApi.success(content);
678
+ },
679
+ [messageApi]
680
+ );
681
+ react.useEffect(
682
+ () => registerFeedbackHost(hostId, { showErrorMessage, showSuccessMessage }),
683
+ [hostId, showErrorMessage, showSuccessMessage]
684
+ );
685
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
686
+ messageContextHolder,
687
+ /* @__PURE__ */ jsxRuntime.jsx(DebugErrorDrawer_default, {}),
688
+ children
689
+ ] });
690
+ };
691
+ GzDebugFeedbackProvider.displayName = "GzDebugFeedbackProvider";
692
+ var GzDebugFeedbackProvider_default = GzDebugFeedbackProvider;
693
+
694
+ // src/fetch/feedback/report-debug-error.ts
695
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
696
+ var getDebugInfo = (value) => isRecord(value) ? value : void 0;
697
+ var getResponseDebugInfo = (responseData) => isRecord(responseData) ? getDebugInfo(responseData.debug) : void 0;
698
+ var isDebugEnabled = () => {
699
+ if (typeof window === "undefined") {
700
+ return false;
701
+ }
702
+ try {
703
+ if (new URLSearchParams(window.location.search).get("showDebug") === "1") {
704
+ return true;
705
+ }
706
+ } catch (e) {
707
+ }
708
+ try {
709
+ return window.localStorage.getItem("showDebug") === "1";
710
+ } catch (e) {
711
+ return false;
712
+ }
713
+ };
714
+ var reportDebugError = (input) => {
715
+ const debug = getDebugInfo(input.debug);
716
+ if (debug === void 0 || !isDebugEnabled()) {
717
+ return false;
718
+ }
719
+ return appendDebugError({ ...input, debug });
112
720
  };
113
721
  var GzFetchError = class extends Error {
114
722
  constructor(message3, options) {
@@ -171,28 +779,6 @@ function toGzFetchError(error) {
171
779
  originalError: error
172
780
  });
173
781
  }
174
- var feedbackHosts = /* @__PURE__ */ new Map();
175
- var activeHostId;
176
- var registerFeedbackHost = (hostId, host) => {
177
- feedbackHosts.set(hostId, host);
178
- activeHostId != null ? activeHostId : activeHostId = hostId;
179
- return () => {
180
- feedbackHosts.delete(hostId);
181
- if (activeHostId !== hostId) {
182
- return;
183
- }
184
- const nextHost = feedbackHosts.keys().next();
185
- activeHostId = nextHost.done ? void 0 : nextHost.value;
186
- };
187
- };
188
- var showFetchErrorMessage = (content) => {
189
- const activeHost = activeHostId === void 0 ? void 0 : feedbackHosts.get(activeHostId);
190
- if (activeHost) {
191
- activeHost.showErrorMessage(content);
192
- return;
193
- }
194
- ggUi.message.error(content);
195
- };
196
782
 
197
783
  // src/fetch/middleware.ts
198
784
  async function runRequestMiddlewares(initialConfig, middlewares) {
@@ -385,15 +971,15 @@ function createGzFetch(options = {}) {
385
971
  await runErrorMiddlewares(error, { config: currentConfig }, middlewares);
386
972
  const shouldShowError = (_a2 = currentConfig.showErrorMessage) != null ? _a2 : showInstanceErrorMessage;
387
973
  if (shouldShowError && error.type !== "CANCELED_ERROR" && !shouldHandleUnauthorized) {
388
- const debugInfo = error.type === "HTTP_ERROR" && error.status !== 401 && isDebugEnabled() ? getResponseDebugInfo(error.responseData) : void 0;
389
- const didShowDebugError = debugInfo === void 0 ? false : showFetchDebugError({
390
- debug: debugInfo,
974
+ const didShowDebugError = error.type === "HTTP_ERROR" && error.status !== 401 ? reportDebugError({
975
+ debug: getResponseDebugInfo(error.responseData),
391
976
  message: error.message,
392
977
  method: currentConfig.method,
978
+ responseData: error.responseData,
393
979
  url: currentConfig.url
394
- });
980
+ }) : false;
395
981
  if (!didShowDebugError) {
396
- showFetchErrorMessage(error.message);
982
+ showFeedbackErrorMessage(error.message);
397
983
  }
398
984
  }
399
985
  throw error;
@@ -429,122 +1015,7 @@ async function gzFetch(config) {
429
1015
  }
430
1016
  return defaultClient(config);
431
1017
  }
432
- var EMPTY_DEBUG_VALUE = "(无)";
433
- var formatDebugValue = (value) => {
434
- if (typeof value === "string") {
435
- return value;
436
- }
437
- if (value === void 0 || value === null) {
438
- return EMPTY_DEBUG_VALUE;
439
- }
440
- try {
441
- const serialized = JSON.stringify(value, null, 2);
442
- return serialized != null ? serialized : "(无法序列化)";
443
- } catch (e) {
444
- return "(无法序列化)";
445
- }
446
- };
447
- var codeStyle = {
448
- background: "rgba(127, 127, 127, 0.08)",
449
- borderRadius: 6,
450
- margin: "8px 0 0",
451
- overflowWrap: "anywhere",
452
- overflowX: "auto",
453
- padding: 12,
454
- whiteSpace: "pre-wrap"
455
- };
456
- var DebugSection = ({
457
- title,
458
- value
459
- }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: 16 }, children: [
460
- /* @__PURE__ */ jsxRuntime.jsx("strong", { children: title }),
461
- /* @__PURE__ */ jsxRuntime.jsx("pre", { style: codeStyle, children: formatDebugValue(value) })
462
- ] });
463
- var DebugError = ({ error }) => /* @__PURE__ */ jsxRuntime.jsxs(
464
- "section",
465
- {
466
- style: {
467
- border: "1px solid rgba(127, 127, 127, 0.24)",
468
- borderRadius: 8,
469
- padding: 16
470
- },
471
- children: [
472
- /* @__PURE__ */ jsxRuntime.jsxs(
473
- "div",
474
- {
475
- style: {
476
- alignItems: "flex-start",
477
- display: "flex",
478
- gap: 12,
479
- justifyContent: "space-between"
480
- },
481
- children: [
482
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { minWidth: 0 }, children: [
483
- /* @__PURE__ */ jsxRuntime.jsx("strong", { children: error.message }),
484
- error.method && error.url ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 6, overflowWrap: "anywhere" }, children: /* @__PURE__ */ jsxRuntime.jsxs("code", { children: [
485
- error.method,
486
- " ",
487
- error.url
488
- ] }) }) : null
489
- ] }),
490
- /* @__PURE__ */ jsxRuntime.jsx(
491
- ggUi.Button,
492
- {
493
- danger: true,
494
- size: "small",
495
- type: "text",
496
- onClick: () => removeDebugError(error.id),
497
- children: "删除"
498
- }
499
- )
500
- ]
501
- }
502
- ),
503
- /* @__PURE__ */ jsxRuntime.jsx(DebugSection, { title: "Request", value: error.debug.request }),
504
- /* @__PURE__ */ jsxRuntime.jsx(DebugSection, { title: "Stack Trace", value: error.debug.stackTrace }),
505
- /* @__PURE__ */ jsxRuntime.jsx(DebugSection, { title: "MDC", value: error.debug.mdc })
506
- ]
507
- }
508
- );
509
- var GzFetchDebugDrawer = () => {
510
- var _a;
511
- const hostIdRef = react.useRef(void 0);
512
- (_a = hostIdRef.current) != null ? _a : hostIdRef.current = /* @__PURE__ */ Symbol("gz-fetch-debug-drawer-host");
513
- const hostId = hostIdRef.current;
514
- const snapshot3 = react.useSyncExternalStore(
515
- subscribeDebugDrawer,
516
- getDebugDrawerSnapshot,
517
- getDebugDrawerServerSnapshot
518
- );
519
- react.useEffect(() => registerDebugDrawerHost(hostId), [hostId]);
520
- if (snapshot3.activeHostId !== hostId) {
521
- return null;
522
- }
523
- return /* @__PURE__ */ jsxRuntime.jsx(
524
- ggUi.Drawer,
525
- {
526
- extra: /* @__PURE__ */ jsxRuntime.jsx(
527
- ggUi.Button,
528
- {
529
- disabled: snapshot3.errors.length === 0,
530
- size: "small",
531
- onClick: clearDebugErrors,
532
- children: "全部清除"
533
- }
534
- ),
535
- open: snapshot3.open,
536
- placement: "right",
537
- styles: { body: { overflowY: "auto" } },
538
- title: `Debug Error (${snapshot3.errors.length})`,
539
- width: "min(760px, 100vw)",
540
- onClose: closeDebugDrawer,
541
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "grid", gap: 16 }, children: snapshot3.errors.map((error) => /* @__PURE__ */ jsxRuntime.jsx(DebugError, { error }, error.id)) })
542
- }
543
- );
544
- };
545
- GzFetchDebugDrawer.displayName = "GzFetchDebugDrawer";
546
- var GzFetchDebugDrawer_default = GzFetchDebugDrawer;
547
- var GzFetchUnauthorizedModal = () => {
1018
+ var GzFetchUnauthorizedModalContent = () => {
548
1019
  var _a, _b, _c;
549
1020
  const hostIdRef = react.useRef(void 0);
550
1021
  (_a = hostIdRef.current) != null ? _a : hostIdRef.current = /* @__PURE__ */ Symbol("gz-fetch-unauthorized-modal-host");
@@ -579,34 +1050,19 @@ var GzFetchUnauthorizedModal = () => {
579
1050
  }
580
1051
  );
581
1052
  };
582
- GzFetchUnauthorizedModal.displayName = "GzFetchUnauthorizedModal";
583
- var GzFetchUnauthorizedModal_default = GzFetchUnauthorizedModal;
584
- var GzFetchFeedbackProvider = ({ children }) => {
585
- var _a;
586
- const hostIdRef = react.useRef(void 0);
587
- (_a = hostIdRef.current) != null ? _a : hostIdRef.current = /* @__PURE__ */ Symbol("gz-fetch-feedback-host");
588
- const hostId = hostIdRef.current;
589
- const [messageApi, messageContextHolder] = ggUi.message.useMessage();
590
- const showErrorMessage = react.useCallback(
591
- (content) => {
592
- void messageApi.error(content);
593
- },
594
- [messageApi]
595
- );
596
- react.useEffect(
597
- () => registerFeedbackHost(hostId, { showErrorMessage }),
598
- [hostId, showErrorMessage]
599
- );
600
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
601
- messageContextHolder,
602
- /* @__PURE__ */ jsxRuntime.jsx(GzFetchDebugDrawer_default, {}),
603
- /* @__PURE__ */ jsxRuntime.jsx(GzFetchUnauthorizedModal_default, {}),
604
- children
605
- ] });
606
- };
1053
+ GzFetchUnauthorizedModalContent.displayName = "GzFetchUnauthorizedModalContent";
1054
+ var GzFetchUnauthorizedModalContent_default = GzFetchUnauthorizedModalContent;
1055
+ var GzFetchFeedbackProvider = ({ children }) => /* @__PURE__ */ jsxRuntime.jsxs(GzDebugFeedbackProvider_default, { children: [
1056
+ /* @__PURE__ */ jsxRuntime.jsx(GzFetchUnauthorizedModalContent_default, {}),
1057
+ children
1058
+ ] });
607
1059
  GzFetchFeedbackProvider.displayName = "GzFetchFeedbackProvider";
608
1060
  var GzFetchFeedbackProvider_default = GzFetchFeedbackProvider;
1061
+ var GzFetchUnauthorizedModal = () => /* @__PURE__ */ jsxRuntime.jsx(GzFetchUnauthorizedModalContent_default, {});
1062
+ GzFetchUnauthorizedModal.displayName = "GzFetchUnauthorizedModal";
1063
+ var GzFetchUnauthorizedModal_default = GzFetchUnauthorizedModal;
609
1064
 
1065
+ exports.GzDebugFeedbackProvider = GzDebugFeedbackProvider_default;
610
1066
  exports.GzFetchError = GzFetchError;
611
1067
  exports.GzFetchFeedbackProvider = GzFetchFeedbackProvider_default;
612
1068
  exports.GzFetchUnauthorizedModal = GzFetchUnauthorizedModal_default;
@@ -614,4 +1070,5 @@ exports.configureGzFetch = configureGzFetch;
614
1070
  exports.createGzFetch = createGzFetch;
615
1071
  exports.getResponseMessage = getResponseMessage;
616
1072
  exports.gzFetch = gzFetch;
1073
+ exports.reportDebugError = reportDebugError;
617
1074
  exports.toGzFetchError = toGzFetchError;