@cc-monitoring/proxy-core 0.1.5 → 0.1.7

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.
Files changed (445) hide show
  1. package/dist/docs/404.html +22 -0
  2. package/dist/docs/assets/app.BxFOH0P1.js +1 -0
  3. package/dist/docs/assets/chunks/@localSearchIndexroot.Cuu7C9vz.js +1 -0
  4. package/dist/docs/assets/chunks/VPLocalSearchBox.CYDhNgXW.js +9 -0
  5. package/dist/docs/assets/chunks/abnfDiagram-VRR7QNED.RG1C5NpS.js +1 -0
  6. package/dist/docs/assets/chunks/arc.C9NMazfV.js +1 -0
  7. package/dist/docs/assets/chunks/architectureDiagram-ZJ3FMSHR.u2IZtOa6.js +36 -0
  8. package/dist/docs/assets/chunks/blockDiagram-677ZJIJ3.DdHVir7t.js +132 -0
  9. package/dist/docs/assets/chunks/c4Diagram-LMCZKHZV.gSbgoaJo.js +10 -0
  10. package/dist/docs/assets/chunks/channel.Cc6zpfFP.js +1 -0
  11. package/dist/docs/assets/chunks/chunk-2Q5K7J3B.HRSdtksv.js +1 -0
  12. package/dist/docs/assets/chunks/chunk-32BRIVSS.BYzKapof.js +1 -0
  13. package/dist/docs/assets/chunks/chunk-5VM5RSS4.c3oeF0uS.js +15 -0
  14. package/dist/docs/assets/chunks/chunk-EX3LRPZG.Cz5AKl7t.js +231 -0
  15. package/dist/docs/assets/chunks/chunk-JWPE2WC7.DtJxsA7-.js +1 -0
  16. package/dist/docs/assets/chunks/chunk-MOJQB5TN.h5kO0Dtu.js +88 -0
  17. package/dist/docs/assets/chunks/chunk-RYQCIY6F.Ch_NfMTR.js +1 -0
  18. package/dist/docs/assets/chunks/chunk-V7JOEXUC.CHrHyPoW.js +206 -0
  19. package/dist/docs/assets/chunks/chunk-VR4S4FIN.DG8DIrH3.js +1 -0
  20. package/dist/docs/assets/chunks/chunk-XXDRQBXY.CSXBN12Y.js +1 -0
  21. package/dist/docs/assets/chunks/classDiagram-OUVF2IWQ.DV5B4KLJ.js +1 -0
  22. package/dist/docs/assets/chunks/classDiagram-v2-EOCWNBFH.DV5B4KLJ.js +1 -0
  23. package/dist/docs/assets/chunks/cose-bilkent-JH36ORCC.BeFuOTgi.js +1 -0
  24. package/dist/docs/assets/chunks/cynefin-VYW2F7L2.DaXIfh7Y.js +178 -0
  25. package/dist/docs/assets/chunks/cynefinDiagram-TSTJHNR4.BrJcHEEe.js +62 -0
  26. package/dist/docs/assets/chunks/cytoscape.esm.CUqq0XTU.js +331 -0
  27. package/dist/docs/assets/chunks/dagre-VKFMJZFB.D4vaA23X.js +4 -0
  28. package/dist/docs/assets/chunks/defaultLocale.DX6XiGOO.js +1 -0
  29. package/dist/docs/assets/chunks/diagram-FQU43EPY.uwRFLKRx.js +3 -0
  30. package/dist/docs/assets/chunks/diagram-G47NLZAW.Byfc9d0H.js +24 -0
  31. package/dist/docs/assets/chunks/diagram-NH7WQ7WH.CxjBEGZX.js +24 -0
  32. package/dist/docs/assets/chunks/diagram-OA4YK3LP.CU1jGXMi.js +30 -0
  33. package/dist/docs/assets/chunks/diagram-WEI45ONY.yXgVkURA.js +41 -0
  34. package/dist/docs/assets/chunks/ebnfDiagram-CCIWWBDH.UucqGQ_d.js +1 -0
  35. package/dist/docs/assets/chunks/erDiagram-Q63AITRT.C6qmOrvh.js +85 -0
  36. package/dist/docs/assets/chunks/flowDiagram-23GEKE2U.BZLu-WUl.js +156 -0
  37. package/dist/docs/assets/chunks/framework.D_Xv2a7c.js +19 -0
  38. package/dist/docs/assets/chunks/ganttDiagram-NO4QXBWP.DUzsw4Yr.js +292 -0
  39. package/dist/docs/assets/chunks/gitGraphDiagram-IHSO6WYX.BqLfYTI7.js +106 -0
  40. package/dist/docs/assets/chunks/graph.C2PyVmSI.js +1 -0
  41. package/dist/docs/assets/chunks/infoDiagram-FWYZ7A6U.CiKWveW9.js +2 -0
  42. package/dist/docs/assets/chunks/init.Gi6I4Gst.js +1 -0
  43. package/dist/docs/assets/chunks/ishikawaDiagram-FXEZZL3T.jerUXEXA.js +70 -0
  44. package/dist/docs/assets/chunks/journeyDiagram-5HDEW3XC.Cqzvo6I_.js +139 -0
  45. package/dist/docs/assets/chunks/kanban-definition-HUTT4EX6.BzJ4OPe5.js +89 -0
  46. package/dist/docs/assets/chunks/katex.C5jXJg4s.js +257 -0
  47. package/dist/docs/assets/chunks/layout.BG3qr61M.js +1 -0
  48. package/dist/docs/assets/chunks/linear.hFjgYGMN.js +1 -0
  49. package/dist/docs/assets/chunks/map.DwDi8XlU.js +1 -0
  50. package/dist/docs/assets/chunks/mermaid-client.D3gEaJ5e.js +2 -0
  51. package/dist/docs/assets/chunks/mermaid.core.CEHdFh45.js +314 -0
  52. package/dist/docs/assets/chunks/mindmap-definition-LN4V7U3C.ChC5FJW6.js +96 -0
  53. package/dist/docs/assets/chunks/ordinal.BYWQX77i.js +1 -0
  54. package/dist/docs/assets/chunks/pegDiagram-2B236MQR.ClnjsRYs.js +1 -0
  55. package/dist/docs/assets/chunks/pieDiagram-ENE6RG2P.Bb0MqerK.js +39 -0
  56. package/dist/docs/assets/chunks/quadrantDiagram-ABIIQ3AL.Do6HK_yb.js +7 -0
  57. package/dist/docs/assets/chunks/railroadDiagram-RFXS5EU6.D35m6hQn.js +1 -0
  58. package/dist/docs/assets/chunks/requirementDiagram-TGXJPOKE.DMtjRYUg.js +84 -0
  59. package/dist/docs/assets/chunks/sankeyDiagram-HTMAVEWB.dfXDu62B.js +40 -0
  60. package/dist/docs/assets/chunks/sequenceDiagram-DBY2YBRQ.CLZ0rZTY.js +162 -0
  61. package/dist/docs/assets/chunks/sizeCapture-X5ZJPWSS.DWvGYLUT.js +1 -0
  62. package/dist/docs/assets/chunks/stateDiagram-2N3HPSRC.DY8sDkI0.js +1 -0
  63. package/dist/docs/assets/chunks/stateDiagram-v2-6OUMAXLB.B9v-Vq5L.js +1 -0
  64. package/dist/docs/assets/chunks/swimlanes-5IMT3BWC.Dy9SffeT.js +2 -0
  65. package/dist/docs/assets/chunks/swimlanesDiagram-G3AALYLV.Kb9LnCTH.js +8 -0
  66. package/dist/docs/assets/chunks/theme.BLEczZWC.js +2 -0
  67. package/dist/docs/assets/chunks/timeline-definition-FHXFAJF6.CH6uzgIu.js +120 -0
  68. package/dist/docs/assets/chunks/vennDiagram-L72KCM5P.7EBCJmyP.js +34 -0
  69. package/dist/docs/assets/chunks/wardleyDiagram-EHGQE667.DPHAQssL.js +78 -0
  70. package/dist/docs/assets/chunks/xychartDiagram-FW5EYKEG.aKgxZVbK.js +7 -0
  71. package/dist/docs/assets/index.md.p9floL_p.js +1 -0
  72. package/dist/docs/assets/index.md.p9floL_p.lean.js +1 -0
  73. package/dist/docs/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
  74. package/dist/docs/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
  75. package/dist/docs/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
  76. package/dist/docs/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
  77. package/dist/docs/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
  78. package/dist/docs/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
  79. package/dist/docs/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
  80. package/dist/docs/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
  81. package/dist/docs/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
  82. package/dist/docs/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
  83. package/dist/docs/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
  84. package/dist/docs/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
  85. package/dist/docs/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
  86. package/dist/docs/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
  87. package/dist/docs/assets/overview.md.BKVdLT3o.js +70 -0
  88. package/dist/docs/assets/overview.md.BKVdLT3o.lean.js +1 -0
  89. package/dist/docs/assets/packages-utils.md.CvgYp5Ll.js +31 -0
  90. package/dist/docs/assets/packages-utils.md.CvgYp5Ll.lean.js +1 -0
  91. package/dist/docs/assets/proxy-admin_env-and-build.md.xkeQNYS3.js +40 -0
  92. package/dist/docs/assets/proxy-admin_env-and-build.md.xkeQNYS3.lean.js +1 -0
  93. package/dist/docs/assets/proxy-admin_index.md.DBLI0n0G.js +38 -0
  94. package/dist/docs/assets/proxy-admin_index.md.DBLI0n0G.lean.js +1 -0
  95. package/dist/docs/assets/proxy-admin_layout-and-menu.md.BKGcu49p.js +48 -0
  96. package/dist/docs/assets/proxy-admin_layout-and-menu.md.BKGcu49p.lean.js +1 -0
  97. package/dist/docs/assets/proxy-admin_pages.md.m_fGvvOH.js +51 -0
  98. package/dist/docs/assets/proxy-admin_pages.md.m_fGvvOH.lean.js +1 -0
  99. package/dist/docs/assets/proxy-admin_routing-and-auth.md.DZsdFese.js +106 -0
  100. package/dist/docs/assets/proxy-admin_routing-and-auth.md.DZsdFese.lean.js +1 -0
  101. package/dist/docs/assets/proxy-admin_services-and-mock.md.sdNPcf25.js +66 -0
  102. package/dist/docs/assets/proxy-admin_services-and-mock.md.sdNPcf25.lean.js +1 -0
  103. package/dist/docs/assets/proxy-cli_api-layer.md.GfdbtEUx.js +1 -0
  104. package/dist/docs/assets/proxy-cli_api-layer.md.GfdbtEUx.lean.js +1 -0
  105. package/dist/docs/assets/proxy-cli_app-shell.md.Do18CYhW.js +83 -0
  106. package/dist/docs/assets/proxy-cli_app-shell.md.Do18CYhW.lean.js +1 -0
  107. package/dist/docs/assets/proxy-cli_components-common.md.Dd6Yazvz.js +23 -0
  108. package/dist/docs/assets/proxy-cli_components-common.md.Dd6Yazvz.lean.js +1 -0
  109. package/dist/docs/assets/proxy-cli_components-config.md.B81Y3ta2.js +46 -0
  110. package/dist/docs/assets/proxy-cli_components-config.md.B81Y3ta2.lean.js +1 -0
  111. package/dist/docs/assets/proxy-cli_components-requests.md.vN8IrwL_.js +84 -0
  112. package/dist/docs/assets/proxy-cli_components-requests.md.vN8IrwL_.lean.js +1 -0
  113. package/dist/docs/assets/proxy-cli_components-stats.md.B90esaNa.js +14 -0
  114. package/dist/docs/assets/proxy-cli_components-stats.md.B90esaNa.lean.js +1 -0
  115. package/dist/docs/assets/proxy-cli_components-status.md.C5lAzS2c.js +42 -0
  116. package/dist/docs/assets/proxy-cli_components-status.md.C5lAzS2c.lean.js +1 -0
  117. package/dist/docs/assets/proxy-cli_data-hooks.md.w9Oe1OD3.js +87 -0
  118. package/dist/docs/assets/proxy-cli_data-hooks.md.w9Oe1OD3.lean.js +1 -0
  119. package/dist/docs/assets/proxy-cli_index.md.BA6g8QD-.js +34 -0
  120. package/dist/docs/assets/proxy-cli_index.md.BA6g8QD-.lean.js +1 -0
  121. package/dist/docs/assets/proxy-cli_utils-and-i18n.md.Ch_e-g_o.js +34 -0
  122. package/dist/docs/assets/proxy-cli_utils-and-i18n.md.Ch_e-g_o.lean.js +1 -0
  123. package/dist/docs/assets/proxy-core_chat-api.md.DHihiBxR.js +152 -0
  124. package/dist/docs/assets/proxy-core_chat-api.md.DHihiBxR.lean.js +1 -0
  125. package/dist/docs/assets/proxy-core_cli.md.DCFYX4Bd.js +37 -0
  126. package/dist/docs/assets/proxy-core_cli.md.DCFYX4Bd.lean.js +1 -0
  127. package/dist/docs/assets/proxy-core_config.md.BXSOyxYE.js +83 -0
  128. package/dist/docs/assets/proxy-core_config.md.BXSOyxYE.lean.js +1 -0
  129. package/dist/docs/assets/proxy-core_data-layer.md.Cdomb3Gz.js +85 -0
  130. package/dist/docs/assets/proxy-core_data-layer.md.Cdomb3Gz.lean.js +1 -0
  131. package/dist/docs/assets/proxy-core_entry.md.BZmIcCUM.js +90 -0
  132. package/dist/docs/assets/proxy-core_entry.md.BZmIcCUM.lean.js +1 -0
  133. package/dist/docs/assets/proxy-core_index.md.BM6VV5Qe.js +55 -0
  134. package/dist/docs/assets/proxy-core_index.md.BM6VV5Qe.lean.js +1 -0
  135. package/dist/docs/assets/proxy-core_pm2.md.DUhWEtgn.js +79 -0
  136. package/dist/docs/assets/proxy-core_pm2.md.DUhWEtgn.lean.js +1 -0
  137. package/dist/docs/assets/proxy-core_providers.md.CbDZ6b_7.js +1 -0
  138. package/dist/docs/assets/proxy-core_providers.md.CbDZ6b_7.lean.js +1 -0
  139. package/dist/docs/assets/proxy-core_proxy.md.CzQYmX6X.js +46 -0
  140. package/dist/docs/assets/proxy-core_proxy.md.CzQYmX6X.lean.js +1 -0
  141. package/dist/docs/assets/proxy-core_stats.md.BsM6wuK_.js +42 -0
  142. package/dist/docs/assets/proxy-core_stats.md.BsM6wuK_.lean.js +1 -0
  143. package/dist/docs/assets/proxy-core_tool.md.B6Le1nQr.js +100 -0
  144. package/dist/docs/assets/proxy-core_tool.md.B6Le1nQr.lean.js +1 -0
  145. package/dist/docs/assets/proxy-core_ui-routes.md.Dyqkeoiv.js +27 -0
  146. package/dist/docs/assets/proxy-core_ui-routes.md.Dyqkeoiv.lean.js +1 -0
  147. package/dist/docs/assets/proxy-core_utilities.md.C18pjnkz.js +63 -0
  148. package/dist/docs/assets/proxy-core_utilities.md.C18pjnkz.lean.js +1 -0
  149. package/dist/docs/assets/quickstart.md.Cy_FmXIY.js +38 -0
  150. package/dist/docs/assets/quickstart.md.Cy_FmXIY.lean.js +1 -0
  151. package/dist/docs/assets/request-flow.md.C1fyxdPE.js +146 -0
  152. package/dist/docs/assets/request-flow.md.C1fyxdPE.lean.js +1 -0
  153. package/dist/docs/assets/style.DU_kNMWy.css +1 -0
  154. package/dist/docs/hashmap.json +1 -0
  155. package/dist/docs/index.html +25 -0
  156. package/dist/docs/overview.html +94 -0
  157. package/dist/docs/packages-utils.html +55 -0
  158. package/dist/docs/proxy-admin/env-and-build.html +64 -0
  159. package/dist/docs/proxy-admin/index.html +62 -0
  160. package/dist/docs/proxy-admin/layout-and-menu.html +72 -0
  161. package/dist/docs/proxy-admin/pages.html +75 -0
  162. package/dist/docs/proxy-admin/routing-and-auth.html +130 -0
  163. package/dist/docs/proxy-admin/services-and-mock.html +90 -0
  164. package/dist/docs/proxy-cli/api-layer.html +38 -0
  165. package/dist/docs/proxy-cli/app-shell.html +107 -0
  166. package/dist/docs/proxy-cli/components-common.html +47 -0
  167. package/dist/docs/proxy-cli/components-config.html +70 -0
  168. package/dist/docs/proxy-cli/components-requests.html +108 -0
  169. package/dist/docs/proxy-cli/components-stats.html +38 -0
  170. package/dist/docs/proxy-cli/components-status.html +66 -0
  171. package/dist/docs/proxy-cli/data-hooks.html +111 -0
  172. package/dist/docs/proxy-cli/index.html +58 -0
  173. package/dist/docs/proxy-cli/utils-and-i18n.html +58 -0
  174. package/dist/docs/proxy-core/chat-api.html +176 -0
  175. package/dist/docs/proxy-core/cli.html +61 -0
  176. package/dist/docs/proxy-core/config.html +107 -0
  177. package/dist/docs/proxy-core/data-layer.html +109 -0
  178. package/dist/docs/proxy-core/entry.html +114 -0
  179. package/dist/docs/proxy-core/index.html +79 -0
  180. package/dist/docs/proxy-core/pm2.html +103 -0
  181. package/dist/docs/proxy-core/providers.html +39 -0
  182. package/dist/docs/proxy-core/proxy.html +70 -0
  183. package/dist/docs/proxy-core/stats.html +66 -0
  184. package/dist/docs/proxy-core/tool.html +124 -0
  185. package/dist/docs/proxy-core/ui-routes.html +51 -0
  186. package/dist/docs/proxy-core/utilities.html +87 -0
  187. package/dist/docs/quickstart.html +62 -0
  188. package/dist/docs/request-flow.html +170 -0
  189. package/dist/docs/vp-icons.css +0 -0
  190. package/dist/server/proxy.js +2 -1
  191. package/dist/ui/assets/{1c-KmWe8RWs.js → 1c-DPsrzNHI.js} +1 -1
  192. package/dist/ui/assets/{abnf-BKQ6qIuo.js → abnf-DNkBIQRO.js} +1 -1
  193. package/dist/ui/assets/{abnfDiagram-VRR7QNED-CkRuDPu1.js → abnfDiagram-VRR7QNED-BqvHvzR8.js} +1 -1
  194. package/dist/ui/assets/{accesslog-DD9H5Ktc.js → accesslog-D5NxQ43Q.js} +1 -1
  195. package/dist/ui/assets/{actionscript-CAjf2Qtd.js → actionscript-DLr-LB2m.js} +1 -1
  196. package/dist/ui/assets/{ada-BXkXW16O.js → ada-BRSz3tHX.js} +1 -1
  197. package/dist/ui/assets/{angelscript-BxT7o0Up.js → angelscript-DMtEGgIa.js} +1 -1
  198. package/dist/ui/assets/{apache-C5z_tmVm.js → apache-C4gn4cSd.js} +1 -1
  199. package/dist/ui/assets/{applescript-DdIxl8rr.js → applescript-DoodcTwg.js} +1 -1
  200. package/dist/ui/assets/{arc-hSdFaqKn.js → arc-HmnzaGf9.js} +1 -1
  201. package/dist/ui/assets/{arcade-D5m0roat.js → arcade-RJZZSHSl.js} +1 -1
  202. package/dist/ui/assets/{architectureDiagram-ZJ3FMSHR-DOSHSqzf.js → architectureDiagram-ZJ3FMSHR-BUfDpSIw.js} +1 -1
  203. package/dist/ui/assets/{arduino-FDap8kq-.js → arduino-n6Dpx6Ig.js} +1 -1
  204. package/dist/ui/assets/{armasm-Kzp-Jr1v.js → armasm-DzCVITGB.js} +1 -1
  205. package/dist/ui/assets/{asciidoc-DbGMW3EE.js → asciidoc-CaqMsApq.js} +1 -1
  206. package/dist/ui/assets/{aspectj-CVYMmBCO.js → aspectj-B0kIcV0v.js} +1 -1
  207. package/dist/ui/assets/{autohotkey-9PmBGTPd.js → autohotkey-xUEXewap.js} +1 -1
  208. package/dist/ui/assets/{autoit-B4F86jgh.js → autoit-D3OfN2VX.js} +1 -1
  209. package/dist/ui/assets/{avrasm-CSzv2eHX.js → avrasm-Cbf0F4Kf.js} +1 -1
  210. package/dist/ui/assets/{awk-CjsvYvZE.js → awk-Cc0rWEwe.js} +1 -1
  211. package/dist/ui/assets/{axapta-BVgMoNRY.js → axapta-BKEeoUEe.js} +1 -1
  212. package/dist/ui/assets/{bash-IeBjW3pt.js → bash-D6JH6L3m.js} +1 -1
  213. package/dist/ui/assets/{basic-BTFJfmV1.js → basic-ka6JXc9C.js} +1 -1
  214. package/dist/ui/assets/{blockDiagram-677ZJIJ3-DLw3Bbhf.js → blockDiagram-677ZJIJ3-BHXRSjnM.js} +1 -1
  215. package/dist/ui/assets/{bnf-rCkeRYk0.js → bnf-Bxclk5tZ.js} +1 -1
  216. package/dist/ui/assets/{brainfuck-DBHuB3uZ.js → brainfuck--s_Fd8b9.js} +1 -1
  217. package/dist/ui/assets/{coq-TwFFolHa.js → c-BsgdDna0.js} +1 -1
  218. package/dist/ui/assets/{c-like-CK1xGeX_.js → c-like-CNkOkbqh.js} +1 -1
  219. package/dist/ui/assets/{c4Diagram-LMCZKHZV-cqY51yJw.js → c4Diagram-LMCZKHZV-Bp1uSrW8.js} +1 -1
  220. package/dist/ui/assets/{cal-BxGPpEZK.js → cal-LVlIOy9W.js} +1 -1
  221. package/dist/ui/assets/{capnproto-Bo2fgXF9.js → capnproto-r9DiQ1H8.js} +1 -1
  222. package/dist/ui/assets/{ceylon-C4Bb4pNB.js → ceylon-CTNzyZJX.js} +1 -1
  223. package/dist/ui/assets/channel-_rFUXR2i.js +1 -0
  224. package/dist/ui/assets/{chunk-2Q5K7J3B-CGTiTBmo.js → chunk-2Q5K7J3B-nnLVtUW3.js} +1 -1
  225. package/dist/ui/assets/{chunk-32BRIVSS-DWagYBp9.js → chunk-32BRIVSS-BDNS6igp.js} +1 -1
  226. package/dist/ui/assets/{chunk-5VM5RSS4-BzSBMKJX.js → chunk-5VM5RSS4-D713xBhI.js} +1 -1
  227. package/dist/ui/assets/{chunk-EX3LRPZG-4-aKwCgZ.js → chunk-EX3LRPZG-DExsU6Rd.js} +1 -1
  228. package/dist/ui/assets/{chunk-JWPE2WC7-CPC_cBN0.js → chunk-JWPE2WC7-DcpW5RnW.js} +1 -1
  229. package/dist/ui/assets/{chunk-MOJQB5TN-DrDE4H9w.js → chunk-MOJQB5TN-BQiSZNTn.js} +1 -1
  230. package/dist/ui/assets/{chunk-RYQCIY6F-DkdXe_kU.js → chunk-RYQCIY6F-DfblgZPd.js} +1 -1
  231. package/dist/ui/assets/{chunk-V7JOEXUC-Da6EWcQt.js → chunk-V7JOEXUC-np--VgmN.js} +1 -1
  232. package/dist/ui/assets/{chunk-VR4S4FIN-nP6dstD5.js → chunk-VR4S4FIN-BG0IhjO6.js} +1 -1
  233. package/dist/ui/assets/{chunk-XXDRQBXY-Bi_rRAPA.js → chunk-XXDRQBXY-DHuoh-RB.js} +1 -1
  234. package/dist/ui/assets/classDiagram-OUVF2IWQ-DqgbMzM1.js +1 -0
  235. package/dist/ui/assets/classDiagram-v2-EOCWNBFH-DqgbMzM1.js +1 -0
  236. package/dist/ui/assets/{clean-cc1m9AxK.js → clean-CtVj0-EB.js} +1 -1
  237. package/dist/ui/assets/{clojure-DX5V8QA8.js → clojure-CZwle60-.js} +1 -1
  238. package/dist/ui/assets/{clojure-repl-FzjnVNWQ.js → clojure-repl-DJXWH00I.js} +1 -1
  239. package/dist/ui/assets/{cmake-COZZyrKs.js → cmake-Boxf0e7r.js} +1 -1
  240. package/dist/ui/assets/{coffeescript-DBsnOmC4.js → coffeescript-h85ZW4Gm.js} +1 -1
  241. package/dist/ui/assets/{c-C95V0zHL.js → coq-CVLui3m8.js} +1 -1
  242. package/dist/ui/assets/{cos-Dm5g-IQT.js → cos-CL0igafw.js} +1 -1
  243. package/dist/ui/assets/{cose-bilkent-JH36ORCC-B3-weOQF.js → cose-bilkent-JH36ORCC-CnXyotYB.js} +1 -1
  244. package/dist/ui/assets/{cpp-_RZxQjg7.js → cpp-vite1NvJ.js} +1 -1
  245. package/dist/ui/assets/{crmsh-DGPJ11Gt.js → crmsh-DqT9g0Iq.js} +1 -1
  246. package/dist/ui/assets/{crystal-BOMSPGge.js → crystal-Oans-K8G.js} +1 -1
  247. package/dist/ui/assets/{csharp-DZXiHH72.js → csharp-sCaDAzIB.js} +1 -1
  248. package/dist/ui/assets/{csp-DDSIMUoU.js → csp-rMcp93pK.js} +1 -1
  249. package/dist/ui/assets/{css-Bjye-ZWr.js → css-BwDLHi_h.js} +1 -1
  250. package/dist/ui/assets/{cynefin-VYW2F7L2-Cj5c4L3y.js → cynefin-VYW2F7L2-D8Bmecdd.js} +1 -1
  251. package/dist/ui/assets/{cynefinDiagram-TSTJHNR4-BYsfTeNX.js → cynefinDiagram-TSTJHNR4-BT2YFmPZ.js} +1 -1
  252. package/dist/ui/assets/{d-22pfurOx.js → d-BFgZm0RV.js} +1 -1
  253. package/dist/ui/assets/{dagre-VKFMJZFB-DiEob-by.js → dagre-VKFMJZFB-BeJU73ex.js} +1 -1
  254. package/dist/ui/assets/{dart-Doiu8cDW.js → dart-rIo85iL3.js} +1 -1
  255. package/dist/ui/assets/{delphi-CQ7epp84.js → delphi-Bi2Rfp1o.js} +1 -1
  256. package/dist/ui/assets/{diagram-FQU43EPY-BOPbQcL4.js → diagram-FQU43EPY-CHQiS5Fr.js} +1 -1
  257. package/dist/ui/assets/{diagram-G47NLZAW-C1UWDJTx.js → diagram-G47NLZAW-EVerd4V8.js} +1 -1
  258. package/dist/ui/assets/{diagram-NH7WQ7WH-CYsBqW3J.js → diagram-NH7WQ7WH-DMP0VOAs.js} +1 -1
  259. package/dist/ui/assets/{diagram-OA4YK3LP-Dnag0x_3.js → diagram-OA4YK3LP-CAur5jK9.js} +1 -1
  260. package/dist/ui/assets/{diagram-WEI45ONY-Bo4CsDoj.js → diagram-WEI45ONY-DvmKkPH7.js} +1 -1
  261. package/dist/ui/assets/{diff-Cs6VQQZt.js → diff-CZZCIG00.js} +1 -1
  262. package/dist/ui/assets/{django-Bo3okOrw.js → django-D88PKHy-.js} +1 -1
  263. package/dist/ui/assets/{dns-BpG60eIX.js → dns-DX4hzjUh.js} +1 -1
  264. package/dist/ui/assets/{dockerfile-BWyH8SlV.js → dockerfile-1lgzEXn1.js} +1 -1
  265. package/dist/ui/assets/{dos-DWlNbaB9.js → dos-CwrC1ROy.js} +1 -1
  266. package/dist/ui/assets/{dsconfig-D_8y8YrJ.js → dsconfig-tvVdBv4w.js} +1 -1
  267. package/dist/ui/assets/{dts-Cz4SyMYR.js → dts-DTgQkdRs.js} +1 -1
  268. package/dist/ui/assets/{dust-Cu4qLkeH.js → dust-BbLlyCpf.js} +1 -1
  269. package/dist/ui/assets/{ebnf-CTVHui3r.js → ebnf-D6Dc4oRr.js} +1 -1
  270. package/dist/ui/assets/{ebnfDiagram-CCIWWBDH-epcXQLEj.js → ebnfDiagram-CCIWWBDH-Kvilk1RF.js} +1 -1
  271. package/dist/ui/assets/{elixir-MAlwXhfU.js → elixir-CnMolQVs.js} +1 -1
  272. package/dist/ui/assets/{elm-Bdmwbvef.js → elm-BQ7VQFn7.js} +1 -1
  273. package/dist/ui/assets/{erDiagram-Q63AITRT-Bb60TqAM.js → erDiagram-Q63AITRT-C-S9oHZd.js} +1 -1
  274. package/dist/ui/assets/{erb-Ce9TpP4g.js → erb-B_1g6fXE.js} +1 -1
  275. package/dist/ui/assets/{erlang-CN2GEiqk.js → erlang-3b3ITXJu.js} +1 -1
  276. package/dist/ui/assets/{erlang-repl-D8K4O_cp.js → erlang-repl-Cy6Z3TdH.js} +1 -1
  277. package/dist/ui/assets/{excel-eVZU1r0f.js → excel-DtkATto8.js} +1 -1
  278. package/dist/ui/assets/{fix-BzKerEv0.js → fix-DsEG7TDI.js} +1 -1
  279. package/dist/ui/assets/{flix-B9CE3skV.js → flix-CQ-rKwGO.js} +1 -1
  280. package/dist/ui/assets/{flowDiagram-23GEKE2U-DzMLZIyt.js → flowDiagram-23GEKE2U-EbHDNMCC.js} +1 -1
  281. package/dist/ui/assets/{fortran-B4__3vos.js → fortran-AqzaRCEt.js} +1 -1
  282. package/dist/ui/assets/{fsharp-BJ3-ARHz.js → fsharp-CCzWGasu.js} +1 -1
  283. package/dist/ui/assets/{gams-Cu43oSYT.js → gams-Bqa6CB_r.js} +1 -1
  284. package/dist/ui/assets/{ganttDiagram-NO4QXBWP-D_aAoMRP.js → ganttDiagram-NO4QXBWP-B6jvc6O7.js} +1 -1
  285. package/dist/ui/assets/{gauss-T8vk_TpE.js → gauss-D4Utubeh.js} +1 -1
  286. package/dist/ui/assets/{gcode-9j3BicpZ.js → gcode-By3KwWjb.js} +1 -1
  287. package/dist/ui/assets/{gherkin-Dyh5KFG-.js → gherkin-PXOPjT7Y.js} +1 -1
  288. package/dist/ui/assets/{gitGraphDiagram-IHSO6WYX-CMxCHC-Z.js → gitGraphDiagram-IHSO6WYX-C5l6rHvK.js} +1 -1
  289. package/dist/ui/assets/{glsl-DWWjN4ts.js → glsl-KmmyBk93.js} +1 -1
  290. package/dist/ui/assets/{gml-BcYE-D5A.js → gml-C1Qw_Nrt.js} +1 -1
  291. package/dist/ui/assets/{go-DUnUzOEI.js → go-DaBQtdp1.js} +1 -1
  292. package/dist/ui/assets/{golo-BDoc1QQL.js → golo-D7PDzNpb.js} +1 -1
  293. package/dist/ui/assets/{gradle-B_WRa_bT.js → gradle-nXueCYH-.js} +1 -1
  294. package/dist/ui/assets/{groovy-CgjqFq1e.js → groovy-DFDsQDhl.js} +1 -1
  295. package/dist/ui/assets/{haml-DCqcg7Ti.js → haml-B_zxHzy_.js} +1 -1
  296. package/dist/ui/assets/{handlebars-DSDUQrnw.js → handlebars-BdMY-8KA.js} +1 -1
  297. package/dist/ui/assets/{haskell-DPVnctVi.js → haskell-CftsIPps.js} +1 -1
  298. package/dist/ui/assets/{haxe-BuCGXBa4.js → haxe-BFZb0OIE.js} +1 -1
  299. package/dist/ui/assets/{hsp-BTKpS_u0.js → hsp-EPTuqwtZ.js} +1 -1
  300. package/dist/ui/assets/{htmlbars-Cql3Jvy2.js → htmlbars-B7ZSC-iN.js} +1 -1
  301. package/dist/ui/assets/{http-BB8I9jUh.js → http-BxSd_aa1.js} +1 -1
  302. package/dist/ui/assets/{hy-DG7xkZNz.js → hy-D-rBN9MQ.js} +1 -1
  303. package/dist/ui/assets/index-CWFn1h-J.css +10 -0
  304. package/dist/ui/assets/{index-CfTIGTiY.js → index-DSGZBcd1.js} +166 -171
  305. package/dist/ui/assets/{index-DqIiCkSD.js → index-Dlp8uGHu.js} +3 -3
  306. package/dist/ui/assets/{infoDiagram-FWYZ7A6U-DIzEV-BJ.js → infoDiagram-FWYZ7A6U-BOF_kBqe.js} +1 -1
  307. package/dist/ui/assets/{inform7-BWNpVEkA.js → inform7-OjpbRXZf.js} +1 -1
  308. package/dist/ui/assets/{ini-BMw_C8EP.js → ini-Dc-QApXQ.js} +1 -1
  309. package/dist/ui/assets/{irpf90-Cy42ibFZ.js → irpf90-C4OfYiST.js} +1 -1
  310. package/dist/ui/assets/{isbl-CjFSc0hz.js → isbl-9km6K6Sf.js} +1 -1
  311. package/dist/ui/assets/{ishikawaDiagram-FXEZZL3T-BZcxp5am.js → ishikawaDiagram-FXEZZL3T-BvKSD8LY.js} +1 -1
  312. package/dist/ui/assets/{java-BDxe9dp1.js → java-C2mOf3QX.js} +1 -1
  313. package/dist/ui/assets/{javascript-CgLkkj7h.js → javascript-_i0Q5MkQ.js} +1 -1
  314. package/dist/ui/assets/{jboss-cli-C8biclrb.js → jboss-cli-BS5ipQOv.js} +1 -1
  315. package/dist/ui/assets/{journeyDiagram-5HDEW3XC-BbJu6m6Q.js → journeyDiagram-5HDEW3XC-yKdSl63P.js} +1 -1
  316. package/dist/ui/assets/{json-BjJKhmM6.js → json-Dci0MO4x.js} +1 -1
  317. package/dist/ui/assets/{julia-DvKEpg-R.js → julia-bEqo4nlV.js} +1 -1
  318. package/dist/ui/assets/{julia-repl-BDJWZxkU.js → julia-repl-Co6hf47q.js} +1 -1
  319. package/dist/ui/assets/{kanban-definition-HUTT4EX6-DeIVPlbv.js → kanban-definition-HUTT4EX6-B7BbZCd6.js} +1 -1
  320. package/dist/ui/assets/{kotlin-DCoXcnEb.js → kotlin-krx8WewB.js} +1 -1
  321. package/dist/ui/assets/{lasso-C7m0QmV2.js → lasso-d3ZTv9Tj.js} +1 -1
  322. package/dist/ui/assets/{latex-SHnTG9Eq.js → latex-BNWbHYxK.js} +1 -1
  323. package/dist/ui/assets/{ldif-_6hUnKPV.js → ldif-Bs8eb63L.js} +1 -1
  324. package/dist/ui/assets/{leaf-Co9qxlaF.js → leaf-BTbRDVWB.js} +1 -1
  325. package/dist/ui/assets/{less-CJRDPwNA.js → less-DH5cqJTD.js} +1 -1
  326. package/dist/ui/assets/{lisp-JEHGYbiW.js → lisp-CBUvBYtR.js} +1 -1
  327. package/dist/ui/assets/{livecodeserver-BSYaUj4k.js → livecodeserver-CkM7-E4a.js} +1 -1
  328. package/dist/ui/assets/{livescript-WQMCQeuz.js → livescript-DomXyXUO.js} +1 -1
  329. package/dist/ui/assets/{llvm-DnAHqj5I.js → llvm-e_-ff59-.js} +1 -1
  330. package/dist/ui/assets/{lsl--k-ghYia.js → lsl-BNDsGOmv.js} +1 -1
  331. package/dist/ui/assets/{lua-CXb23hbC.js → lua-_ZmkXwc_.js} +1 -1
  332. package/dist/ui/assets/{makefile-CM7o86yn.js → makefile-BhG7cThe.js} +1 -1
  333. package/dist/ui/assets/{markdown-HB3HvChQ.js → markdown-ClW2SRy6.js} +1 -1
  334. package/dist/ui/assets/{mathematica-9NTuf22N.js → mathematica-kqoCR611.js} +1 -1
  335. package/dist/ui/assets/{matlab-CWv-ik4r.js → matlab-DqawyK3q.js} +1 -1
  336. package/dist/ui/assets/{maxima-CqYiKCrw.js → maxima-B0qzCXe1.js} +1 -1
  337. package/dist/ui/assets/{mel-BbsRpUm5.js → mel-BZaSas3B.js} +1 -1
  338. package/dist/ui/assets/{mercury-Cz2j4HhU.js → mercury-ByD0wyJH.js} +1 -1
  339. package/dist/ui/assets/{mindmap-definition-LN4V7U3C-WyJS8oye.js → mindmap-definition-LN4V7U3C-Ce6QsaH5.js} +1 -1
  340. package/dist/ui/assets/{mipsasm-BqWSRbQV.js → mipsasm-B08lqZSo.js} +1 -1
  341. package/dist/ui/assets/{mizar-JLBfQ6vt.js → mizar-7iaUqWPq.js} +1 -1
  342. package/dist/ui/assets/{mojolicious-D0LbMmyk.js → mojolicious-CbH-d8Wh.js} +1 -1
  343. package/dist/ui/assets/{monkey-DAGL6-JN.js → monkey-D5z6-hFH.js} +1 -1
  344. package/dist/ui/assets/{moonscript-DzbwNSKy.js → moonscript-DuLd7pdm.js} +1 -1
  345. package/dist/ui/assets/{n1ql-dkgKq6Yv.js → n1ql-EbVfQMfD.js} +1 -1
  346. package/dist/ui/assets/{nginx-AUoaDPV4.js → nginx-D-4AxpHP.js} +1 -1
  347. package/dist/ui/assets/{nim-CdqYmVrl.js → nim-wPHQEX5v.js} +1 -1
  348. package/dist/ui/assets/{nix-CxmVjwwo.js → nix-6SVkxAXi.js} +1 -1
  349. package/dist/ui/assets/{node-repl-B1Z3zUAh.js → node-repl-CaFKEOyj.js} +1 -1
  350. package/dist/ui/assets/{nsis-CTAuPWhe.js → nsis-BmqbwVv_.js} +1 -1
  351. package/dist/ui/assets/{objectivec-CvbKeAPz.js → objectivec-BX0R-sI2.js} +1 -1
  352. package/dist/ui/assets/{ocaml-DCiyXKOH.js → ocaml-CyfdrIqo.js} +1 -1
  353. package/dist/ui/assets/{openscad-CPGUwmeR.js → openscad-B5qfaF1E.js} +1 -1
  354. package/dist/ui/assets/{oxygene-CI_bD1Gw.js → oxygene-CmlCgXLr.js} +1 -1
  355. package/dist/ui/assets/{parser3-C91CVs85.js → parser3-DdpPyZkn.js} +1 -1
  356. package/dist/ui/assets/{pegDiagram-2B236MQR-yF8AW7GR.js → pegDiagram-2B236MQR-ByyVqaXh.js} +1 -1
  357. package/dist/ui/assets/{perl-ChxfKl-n.js → perl-D3qc2wEe.js} +1 -1
  358. package/dist/ui/assets/{pf-CKCHkzIA.js → pf-Bv3zza37.js} +1 -1
  359. package/dist/ui/assets/{pgsql-BwOP20uH.js → pgsql-BZIppw1a.js} +1 -1
  360. package/dist/ui/assets/{php-B7Rs2tM5.js → php-D1ScecZC.js} +1 -1
  361. package/dist/ui/assets/{php-template-Cx-Fh4AR.js → php-template-sEqzzKWJ.js} +1 -1
  362. package/dist/ui/assets/{pieDiagram-ENE6RG2P-BS4hnGNX.js → pieDiagram-ENE6RG2P-T1OgWN3l.js} +1 -1
  363. package/dist/ui/assets/{plaintext-U7qkdtgS.js → plaintext-DO7Jy_T2.js} +1 -1
  364. package/dist/ui/assets/{pony-_fGYgePh.js → pony-CTXTp2Tb.js} +1 -1
  365. package/dist/ui/assets/{powershell-CFBTcUce.js → powershell-C9lzZsbj.js} +1 -1
  366. package/dist/ui/assets/{processing-BWHneU0K.js → processing-hzJAP_Li.js} +1 -1
  367. package/dist/ui/assets/{profile-BJ-HxhzS.js → profile-bFiAkh7e.js} +1 -1
  368. package/dist/ui/assets/{prolog-ChHo7n6L.js → prolog-CE0trHSn.js} +1 -1
  369. package/dist/ui/assets/{properties-e_DOYclC.js → properties-MeANnTVc.js} +1 -1
  370. package/dist/ui/assets/{protobuf-5aGSIv7w.js → protobuf-S-rp7SK0.js} +1 -1
  371. package/dist/ui/assets/{puppet-D2vQatzX.js → puppet-B5YT8Ct1.js} +1 -1
  372. package/dist/ui/assets/{purebasic-n6krfaeF.js → purebasic-DO-5HeDl.js} +1 -1
  373. package/dist/ui/assets/{python-CbIo0XxP.js → python-DVGTQbwU.js} +1 -1
  374. package/dist/ui/assets/{python-repl-BpIq9kyr.js → python-repl-CQ4VlKLC.js} +1 -1
  375. package/dist/ui/assets/{q-jntnvcCx.js → q-nS96imov.js} +1 -1
  376. package/dist/ui/assets/{qml-BafQlZNV.js → qml-BkzkCgUU.js} +1 -1
  377. package/dist/ui/assets/{quadrantDiagram-ABIIQ3AL-C3Th8mUJ.js → quadrantDiagram-ABIIQ3AL-BkaCzlXD.js} +1 -1
  378. package/dist/ui/assets/{r-CHgvQFLK.js → r-y4Q5t85r.js} +1 -1
  379. package/dist/ui/assets/{railroadDiagram-RFXS5EU6-CMQkbGJl.js → railroadDiagram-RFXS5EU6-C1lbwk19.js} +1 -1
  380. package/dist/ui/assets/{reasonml-DNwlPD_T.js → reasonml-Bzhzc5Ao.js} +1 -1
  381. package/dist/ui/assets/{requirementDiagram-TGXJPOKE-B70_oR7v.js → requirementDiagram-TGXJPOKE-C8Rw6N2I.js} +1 -1
  382. package/dist/ui/assets/{rib-CX4e9JSF.js → rib-BP3Y9dW3.js} +1 -1
  383. package/dist/ui/assets/{roboconf-ee4qsPGf.js → roboconf-87QE7cIh.js} +1 -1
  384. package/dist/ui/assets/{routeros-BJSwvu2L.js → routeros-BV3nt8wW.js} +1 -1
  385. package/dist/ui/assets/{rsl-BiKdMl_F.js → rsl-DfQf4CW_.js} +1 -1
  386. package/dist/ui/assets/{ruby-CAXTU5LY.js → ruby-DQxFKbgX.js} +1 -1
  387. package/dist/ui/assets/{ruleslanguage-C1kgDGXM.js → ruleslanguage-B8oCm_aw.js} +1 -1
  388. package/dist/ui/assets/{rust-DyEf_GXL.js → rust-DzZgPf9W.js} +1 -1
  389. package/dist/ui/assets/{sankeyDiagram-HTMAVEWB-CvUfseMg.js → sankeyDiagram-HTMAVEWB-Dxiuo8Hz.js} +1 -1
  390. package/dist/ui/assets/{sas-Q1rlUxPH.js → sas-CFh-Rsrv.js} +1 -1
  391. package/dist/ui/assets/{scala-Dg6KNmge.js → scala-3UDyJBiS.js} +1 -1
  392. package/dist/ui/assets/{scheme-D9iooUxI.js → scheme-KaUTge9W.js} +1 -1
  393. package/dist/ui/assets/{scilab-CztEJXJY.js → scilab-CLSBZzuh.js} +1 -1
  394. package/dist/ui/assets/{scss-BMh-JkdE.js → scss-DaEkfHWX.js} +1 -1
  395. package/dist/ui/assets/{sequenceDiagram-DBY2YBRQ-DB0c9kf4.js → sequenceDiagram-DBY2YBRQ-Cv__zR2v.js} +1 -1
  396. package/dist/ui/assets/{shell-DWo6z0MG.js → shell-B0d4cZTk.js} +1 -1
  397. package/dist/ui/assets/{sizeCapture-X5ZJPWSS-BcQlgjfD.js → sizeCapture-X5ZJPWSS-C4nD-ShQ.js} +1 -1
  398. package/dist/ui/assets/{smali-Cijeb6pL.js → smali-CLhfky4R.js} +1 -1
  399. package/dist/ui/assets/{smalltalk-D0lvqa_d.js → smalltalk-B4aaTMO5.js} +1 -1
  400. package/dist/ui/assets/{sml-B-vqWZ3b.js → sml-x4CTxWEZ.js} +1 -1
  401. package/dist/ui/assets/{sqf-BJ-1Q583.js → sqf-G_0vdVVs.js} +1 -1
  402. package/dist/ui/assets/{sql-CMGLxEYV.js → sql-C--WH0Fo.js} +1 -1
  403. package/dist/ui/assets/{sql_more-gsRmbNCH.js → sql_more-B4LrzCtd.js} +1 -1
  404. package/dist/ui/assets/{stan-D1AlTSpf.js → stan-CACDFOA0.js} +1 -1
  405. package/dist/ui/assets/{stata-DnEYviI0.js → stata-BP9M7sZt.js} +1 -1
  406. package/dist/ui/assets/{stateDiagram-2N3HPSRC-BSRgVsHO.js → stateDiagram-2N3HPSRC-z3-31Cr2.js} +1 -1
  407. package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-BKIXFHzO.js +1 -0
  408. package/dist/ui/assets/{step21-DbQV9sMo.js → step21-MAOu4dNb.js} +1 -1
  409. package/dist/ui/assets/{stylus-Cyc7vdUc.js → stylus-CpuP3pvE.js} +1 -1
  410. package/dist/ui/assets/{subunit-16ipyMie.js → subunit-NWzuqFhT.js} +1 -1
  411. package/dist/ui/assets/{swift-DTNnw4qS.js → swift-DuFKNmKv.js} +1 -1
  412. package/dist/ui/assets/{swimlanes-5IMT3BWC-DgOdcc4_.js → swimlanes-5IMT3BWC-E463-rXd.js} +2 -2
  413. package/dist/ui/assets/swimlanesDiagram-G3AALYLV-CkQvBOYs.js +8 -0
  414. package/dist/ui/assets/{taggerscript-DM6pvUWE.js → taggerscript-BDnv2jvg.js} +1 -1
  415. package/dist/ui/assets/{tap-Ch-uyKZq.js → tap-aB2cLXdf.js} +1 -1
  416. package/dist/ui/assets/{tcl-D0T_V5dA.js → tcl-7WepIaIa.js} +1 -1
  417. package/dist/ui/assets/{thrift-D9xJjYw4.js → thrift-BLh6pdjc.js} +1 -1
  418. package/dist/ui/assets/{timeline-definition-FHXFAJF6-BBeDMHxb.js → timeline-definition-FHXFAJF6-FA_RNhFQ.js} +1 -1
  419. package/dist/ui/assets/{tp-kUrCGo9X.js → tp-D1rt5u_j.js} +1 -1
  420. package/dist/ui/assets/{twig-Cgub6rxA.js → twig-DgfeYg4W.js} +1 -1
  421. package/dist/ui/assets/{typescript-BxNP9Ap9.js → typescript-oU560Q8V.js} +1 -1
  422. package/dist/ui/assets/{vala-DF9ZZagU.js → vala-DlXsaz2B.js} +1 -1
  423. package/dist/ui/assets/{vbnet-Cf46ypDg.js → vbnet-BjpxjeMZ.js} +1 -1
  424. package/dist/ui/assets/{vbscript-DNs-QKLH.js → vbscript-DfNdtdO3.js} +1 -1
  425. package/dist/ui/assets/{vbscript-html-DyS6I5L1.js → vbscript-html-D09WPsgK.js} +1 -1
  426. package/dist/ui/assets/{vennDiagram-L72KCM5P-8WpWycE-.js → vennDiagram-L72KCM5P-zaCDWwTs.js} +1 -1
  427. package/dist/ui/assets/{verilog-CF5wC4X-.js → verilog-B9vENtLK.js} +1 -1
  428. package/dist/ui/assets/{vhdl-Dm0jpDMn.js → vhdl-CJLTZOu1.js} +1 -1
  429. package/dist/ui/assets/{vim-nyO2DRAx.js → vim-FuPhupu9.js} +1 -1
  430. package/dist/ui/assets/{wardleyDiagram-EHGQE667-UeIOK-jv.js → wardleyDiagram-EHGQE667-BS8ApwmV.js} +1 -1
  431. package/dist/ui/assets/{x86asm-BNw2-6GG.js → x86asm-kX_Cp6wB.js} +1 -1
  432. package/dist/ui/assets/{xl-D-YHxr6V.js → xl-MuHNmLUj.js} +1 -1
  433. package/dist/ui/assets/{xml-BijAlrow.js → xml-Mbn2z12n.js} +1 -1
  434. package/dist/ui/assets/{xquery-z0wxWBKz.js → xquery-Dy4lt-m-.js} +1 -1
  435. package/dist/ui/assets/{xychartDiagram-FW5EYKEG-BNzHLweN.js → xychartDiagram-FW5EYKEG-DoNZtZus.js} +1 -1
  436. package/dist/ui/assets/{yaml-n5TIQArR.js → yaml-CxxAisfE.js} +1 -1
  437. package/dist/ui/assets/{zephir-DrGhH8jG.js → zephir-WWG8qyld.js} +1 -1
  438. package/dist/ui/index.html +2 -2
  439. package/package.json +2 -2
  440. package/dist/ui/assets/channel-D9Y4iN1l.js +0 -1
  441. package/dist/ui/assets/classDiagram-OUVF2IWQ-C4UVH6RI.js +0 -1
  442. package/dist/ui/assets/classDiagram-v2-EOCWNBFH-C4UVH6RI.js +0 -1
  443. package/dist/ui/assets/index-CK_lJsTu.css +0 -10
  444. package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-BLdfpGJO.js +0 -1
  445. package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DRVnkg3M.js +0 -8
@@ -0,0 +1,66 @@
1
+ import{_ as i,o as a,c as n,a2 as h}from"./chunks/framework.D_Xv2a7c.js";const g=JSON.parse('{"title":"proxy-admin / 服务层与 Mock","description":"","frontmatter":{},"headers":[],"relativePath":"proxy-admin/services-and-mock.md","filePath":"proxy-admin/services-and-mock.md"}'),t={name:"proxy-admin/services-and-mock.md"};function k(l,s,p,e,r,d){return a(),n("div",null,[...s[0]||(s[0]=[h(`<h1 id="proxy-admin-服务层与-mock" tabindex="-1">proxy-admin / 服务层与 Mock <a class="header-anchor" href="#proxy-admin-服务层与-mock" aria-label="Permalink to &quot;proxy-admin / 服务层与 Mock&quot;">​</a></h1><h2 id="本文档覆盖的源文件" tabindex="-1">本文档覆盖的源文件 <a class="header-anchor" href="#本文档覆盖的源文件" aria-label="Permalink to &quot;本文档覆盖的源文件&quot;">​</a></h2><ul><li><code>apps/proxy-admin/src/services/request.ts</code></li><li><code>apps/proxy-admin/src/services/api.ts</code></li><li><code>apps/proxy-admin/src/mock/index.ts</code></li><li><code>apps/proxy-admin/src/mock/user.ts</code></li><li><code>apps/proxy-admin/src/mock/supplier.ts</code></li><li><code>apps/proxy-admin/src/mock/system.ts</code></li><li><code>apps/proxy-admin/src/utils/index.ts</code></li></ul><h2 id="axios-实例-request-ts" tabindex="-1">axios 实例 <code>request.ts</code> <a class="header-anchor" href="#axios-实例-request-ts" aria-label="Permalink to &quot;axios 实例 \`request.ts\`&quot;">​</a></h2><p><code>apps/proxy-admin/src/services/request.ts</code>:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> instance</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> axios.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">create</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
2
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> baseURL: </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">meta</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.env.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">VITE_API_PREFIX</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ||</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;/api&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
3
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> timeout: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">10000</span></span>
4
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span>
5
+ <span class="line"></span>
6
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> request</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">T</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> any</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">config</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> AxiosRequestConfig</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Promise</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">T</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt; </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=&gt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> instance</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(config) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">as</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> unknown</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> as</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Promise</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">T</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
7
+ <span class="line"></span>
8
+ <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 快捷方法:request.get / post / put / delete</span></span>
9
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">request.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">T</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">url</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">config</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=&gt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> request</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">config, method: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;GET&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, url })</span></span>
10
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">request.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">post</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">T</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">url</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">data</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">config</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=&gt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> request</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">config, method: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;POST&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, url, data })</span></span>
11
+ <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// ...</span></span>
12
+ <span class="line"></span>
13
+ <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 请求拦截:附 token</span></span>
14
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">instance.interceptors.request.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">use</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">config</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
15
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> token</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;token&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
16
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (token) config.headers.Authorization </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> \`Bearer \${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">token</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}\`</span></span>
17
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> config</span></span>
18
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span>
19
+ <span class="line"></span>
20
+ <span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 响应拦截:解包 + 401 处理</span></span>
21
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">instance.interceptors.response.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">use</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
22
+ <span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> response</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> response.data, </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 只返 data</span></span>
23
+ <span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> error</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
24
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (error.response?.status </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">===</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 401</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
25
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> message.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;登录已过期,请重新登录&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
26
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">removeItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;token&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
27
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">removeItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;user&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
28
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> window.location.href </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;/login&#39;</span></span>
29
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">else</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (error.response?.data?.message) {</span></span>
30
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> message.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(error.response.data.message)</span></span>
31
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">else</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
32
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> message.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;请求失败,请稍后重试&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
33
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
34
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> Promise</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">reject</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(error)</span></span>
35
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
36
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><h3 id="特点" tabindex="-1">特点 <a class="header-anchor" href="#特点" aria-label="Permalink to &quot;特点&quot;">​</a></h3><ul><li><strong>baseURL</strong> 来自 <code>VITE_API_PREFIX</code>(默认 <code>/api</code>),与 vite-plugin-mock 的路径匹配</li><li><strong>timeout 10s</strong></li><li><strong>响应拦截自动解包</strong>:<code>response.data</code> 直接返回。调用方拿到的是后端 body 而非 axios <code>{ data, headers, ... }</code> 包装</li><li><strong>401 硬跳转</strong>:<code>window.location.href = &#39;/login&#39;</code> 走完整重载,触发 AuthProvider 重新读 localStorage</li><li><strong>429/500 等其他错误</strong>:<code>message.error</code> 显示 antd 全局提示</li><li><strong>仍然 reject</strong>:调用方的 <code>catch</code> 会执行;但 UI 提示已完成</li></ul><h3 id="类型上的小坑" tabindex="-1">类型上的小坑 <a class="header-anchor" href="#类型上的小坑" aria-label="Permalink to &quot;类型上的小坑&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">return</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> instance</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(config) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">as</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> unknown</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> as</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Promise</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">T</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span></code></pre></div><p>拦截器返回 <code>response.data</code>,但 axios 类型定义仍认为返回 <code>AxiosResponse&lt;T&gt;</code>。用 <code>as unknown as Promise&lt;T&gt;</code> 强转。调用方类型是 <code>Promise&lt;ApiResponse&lt;T&gt;&gt;</code>(业务包装)。</p><h2 id="api-定义-api-ts" tabindex="-1">API 定义 <code>api.ts</code> <a class="header-anchor" href="#api-定义-api-ts" aria-label="Permalink to &quot;API 定义 \`api.ts\`&quot;">​</a></h2><p><code>apps/proxy-admin/src/services/api.ts</code>。定义 9 个 API + 3 组类型:</p><h3 id="通用响应类型" tabindex="-1">通用响应类型 <a class="header-anchor" href="#通用响应类型" aria-label="Permalink to &quot;通用响应类型&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> interface</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> ApiResponse</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">T</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> any</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt; {</span></span>
37
+ <span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> code</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> number</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 0 = 成功,其他 = 错误</span></span>
38
+ <span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> message</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span></span>
39
+ <span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> data</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> T</span></span>
40
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>所有 mock 都返回这个结构。</p><h3 id="认证-api" tabindex="-1">认证 API <a class="header-anchor" href="#认证-api" aria-label="Permalink to &quot;认证 API&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">login</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(params: LoginParams): </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Promise</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ApiResponse</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{ token, user }</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;&gt;</span></span>
41
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">logout</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(): </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Promise</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ApiResponse</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{ success }</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;&gt;</span></span>
42
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getUserInfo</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(): </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Promise</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ApiResponse</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{ user }</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;&gt;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // 未见调用</span></span></code></pre></div><h3 id="用户管理-api" tabindex="-1">用户管理 API <a class="header-anchor" href="#用户管理-api" aria-label="Permalink to &quot;用户管理 API&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getUserList</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(params</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { page?, pageSize? }): </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Promise</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ApiResponse</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{ </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">list</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: UserInfo[], total }</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;&gt;</span></span>
43
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">createUser</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(params: Omit</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">UserInfo, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;id&#39;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">): </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Promise</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ApiResponse</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">UserInfo</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;&gt;</span></span></code></pre></div><h3 id="供应商-api" tabindex="-1">供应商 API <a class="header-anchor" href="#供应商-api" aria-label="Permalink to &quot;供应商 API&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">interface</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Supplier</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">id</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">type</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">status</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;active&#39;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">|</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;inactive&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">config</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Record</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">any</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">createdAt</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
44
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getSupplierList</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(params</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> Promise</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ApiResponse</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{ list, total }</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;&gt;</span></span>
45
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">createSupplier</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(params: Omit</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">Supplier, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;id&#39;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> |</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;createdAt&#39;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">): </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Promise</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ApiResponse</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">Supplier</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;&gt;</span></span></code></pre></div><h3 id="系统设置-api" tabindex="-1">系统设置 API <a class="header-anchor" href="#系统设置-api" aria-label="Permalink to &quot;系统设置 API&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">interface</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> SystemSettings</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">siteName</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">siteDescription</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">maxUploadSize</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">enableRegistration</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
46
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getSystemSettings</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(): </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Promise</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ApiResponse</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">SystemSettings</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;&gt;</span></span>
47
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">saveSystemSettings</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(params: SystemSettings): </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Promise</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ApiResponse</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{ success }</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;&gt;</span></span></code></pre></div><p><strong>注意</strong>:无编辑用户 / 删除用户 / 编辑供应商 / 删除供应商 / 分页 / 搜索接口——UI 里的按钮都没绑 handler。</p><h2 id="mock-数据" tabindex="-1">Mock 数据 <a class="header-anchor" href="#mock-数据" aria-label="Permalink to &quot;Mock 数据&quot;">​</a></h2><p><code>apps/proxy-admin/src/mock/index.ts</code>:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> userMock </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;./user&#39;</span></span>
48
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> supplierMock </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;./supplier&#39;</span></span>
49
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> systemMock </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;./system&#39;</span></span>
50
+ <span class="line"></span>
51
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> [</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">userMock, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">supplierMock, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">systemMock]</span></span></code></pre></div><p><code>vite-plugin-mock</code> 期待默认导出 <code>MockMethod[]</code>。</p><h3 id="user-mock" tabindex="-1">user mock <a class="header-anchor" href="#user-mock" aria-label="Permalink to &quot;user mock&quot;">​</a></h3><p><code>apps/proxy-admin/src/mock/user.ts</code>。3 个 mock 用户 + 3 个 API:</p><ul><li><code>POST /api/login</code>:body <code>{ username, password }</code><ul><li><code>admin</code> / <code>123456</code> → 返回 token(<code>mock-token-&lt;Date.now()&gt;</code>) + <code>mockUsers[0]</code></li><li>其他 → <code>{ code: 401, message: &#39;用户名或密码错误&#39; }</code></li></ul></li><li><code>POST /api/logout</code>:直接返回成功</li><li><code>GET /api/user/info</code>:检查 <code>Authorization: Bearer ...</code> 头,否则 401</li><li><code>GET /api/user/list</code>:读 query <code>page/pageSize</code>,切片返回</li></ul><h3 id="supplier-mock" tabindex="-1">supplier mock <a class="header-anchor" href="#supplier-mock" aria-label="Permalink to &quot;supplier mock&quot;">​</a></h3><p><code>apps/proxy-admin/src/mock/supplier.ts</code>。3 个 mock 供应商(OpenAI / Anthropic / Google Gemini):</p><ul><li><code>GET /api/supplier/list</code>:分页切片</li><li><code>POST /api/supplier</code>:新增,<code>id = length + 1</code>,<code>createdAt = new Date().toISOString()</code></li></ul><p><strong>mock 有状态</strong>:<code>mockSuppliers.push(newSupplier)</code> 修改内存中的数组——同一 Vite 开发会话内新增可见。刷新页面丢失。</p><h3 id="system-mock" tabindex="-1">system mock <a class="header-anchor" href="#system-mock" aria-label="Permalink to &quot;system mock&quot;">​</a></h3><p><code>apps/proxy-admin/src/mock/system.ts</code>:</p><ul><li><code>GET /api/system/settings</code>:返回 <code>mockSettings</code></li><li><code>POST /api/system/settings</code>:<code>Object.assign(mockSettings, body)</code> 就地更新</li></ul><h2 id="工具函数-utils-index-ts" tabindex="-1">工具函数 <code>utils/index.ts</code> <a class="header-anchor" href="#工具函数-utils-index-ts" aria-label="Permalink to &quot;工具函数 \`utils/index.ts\`&quot;">​</a></h2><p><code>apps/proxy-admin/src/utils/index.ts</code>。两个 localStorage 封装:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getLocalStorage</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">T</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> any</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">key</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">defaultValue</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> T</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> T</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> |</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> null</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
52
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> try</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
53
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> value</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(key)</span></span>
54
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (value </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">===</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> null</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> defaultValue </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">??</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> null</span></span>
55
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> JSON</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">parse</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(value) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">as</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> T</span></span>
56
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">catch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (error) {</span></span>
57
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
58
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> defaultValue </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">??</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> null</span></span>
59
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
60
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
61
+ <span class="line"></span>
62
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> setLocalStorage</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">T</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> any</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">key</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">value</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> T</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> void</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
63
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> try</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
64
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localStorage.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">setItem</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(key, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">JSON</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">stringify</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(value))</span></span>
65
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">catch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (error) { console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) }</span></span>
66
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><ul><li>自动 <code>JSON.parse</code> / <code>stringify</code></li><li>异常安全(JSON 损坏、存储配额满等)</li><li>支持默认值</li></ul><p><strong>当前未见调用点</strong>——AuthContext 直接用原生 <code>localStorage</code>。这是预留工具函数。</p><h2 id="后端联调思路-未来" tabindex="-1">后端联调思路(未来) <a class="header-anchor" href="#后端联调思路-未来" aria-label="Permalink to &quot;后端联调思路(未来)&quot;">​</a></h2><p>如果要接入 proxy-core:</p><ol><li><code>.env.local</code> 设 <code>VITE_API_PROXY_TARGET=http://localhost:9527</code></li><li><code>.env</code> 设 <code>VITE_API_PREFIX=/ui/api</code>(与 proxy-core 一致)</li><li>关闭 vite-plugin-mock(<code>vite.config.ts:11</code> 的 <code>enable: true</code> 改成 <code>false</code>)</li><li>后端补齐 <code>/ui/api/user/*</code>、<code>/ui/api/supplier/*</code>、<code>/ui/api/system/settings</code> 端点</li><li>处理 auth:目前 axios 拦截器发 <code>Bearer &lt;mock-token&gt;</code>,proxy-core 期待 <code>config.auth.token</code> 或 <code>UI_AUTH_TOKEN</code> 匹配——需要真实的登录服务而非 mock</li></ol><h2 id="相关" tabindex="-1">相关 <a class="header-anchor" href="#相关" aria-label="Permalink to &quot;相关&quot;">​</a></h2><ul><li>认证 → <a href="./routing-and-auth.html">routing-and-auth.md</a></li><li>环境变量 → <a href="./env-and-build.html">env-and-build.md</a></li></ul>`,49)])])}const o=i(t,[["render",k]]);export{g as __pageData,o as default};
@@ -0,0 +1 @@
1
+ import{_ as i,o as a,c as n,a2 as h}from"./chunks/framework.D_Xv2a7c.js";const g=JSON.parse('{"title":"proxy-admin / 服务层与 Mock","description":"","frontmatter":{},"headers":[],"relativePath":"proxy-admin/services-and-mock.md","filePath":"proxy-admin/services-and-mock.md"}'),t={name:"proxy-admin/services-and-mock.md"};function k(l,s,p,e,r,d){return a(),n("div",null,[...s[0]||(s[0]=[h("",49)])])}const o=i(t,[["render",k]]);export{g as __pageData,o as default};
@@ -0,0 +1 @@
1
+ import{_ as i,o as a,c as t,a2 as e}from"./chunks/framework.D_Xv2a7c.js";const c=JSON.parse('{"title":"proxy-cli / API 层","description":"","frontmatter":{},"headers":[],"relativePath":"proxy-cli/api-layer.md","filePath":"proxy-cli/api-layer.md"}'),h={name:"proxy-cli/api-layer.md"};function n(p,s,l,k,r,d){return a(),t("div",null,[...s[0]||(s[0]=[e('<h1 id="proxy-cli-api-层" tabindex="-1">proxy-cli / API 层 <a class="header-anchor" href="#proxy-cli-api-层" aria-label="Permalink to &quot;proxy-cli / API 层&quot;">​</a></h1><h2 id="本文档覆盖的源文件" tabindex="-1">本文档覆盖的源文件 <a class="header-anchor" href="#本文档覆盖的源文件" aria-label="Permalink to &quot;本文档覆盖的源文件&quot;">​</a></h2><ul><li><code>apps/proxy-cli/src/api/index.ts</code></li><li><code>apps/proxy-cli/src/api/providers.ts</code></li><li><code>apps/proxy-cli/src/api/mcp.ts</code></li></ul><p>前端与 proxy-core 唯一通信手段(除 WebSocket)就是这里的 REST 封装。全部用原生 <code>fetch</code>,无 axios。</p><h2 id="常量" tabindex="-1">常量 <a class="header-anchor" href="#常量" aria-label="Permalink to &quot;常量&quot;">​</a></h2><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> API_BASE</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;/ui/api&#39;</span></span></code></pre></div><p>所有端点都用相对路径 → 依赖 Vite dev proxy 或生产同源。</p><h2 id="api-index-ts-—-主接口" tabindex="-1"><code>api/index.ts</code> — 主接口 <a class="header-anchor" href="#api-index-ts-—-主接口" aria-label="Permalink to &quot;`api/index.ts` — 主接口&quot;">​</a></h2><h3 id="fetchstatus" tabindex="-1"><code>fetchStatus</code> <a class="header-anchor" href="#fetchstatus" aria-label="Permalink to &quot;`fetchStatus`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">GET</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> /</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ui</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">status → StatusApiResponse</span></span></code></pre></div><p>对应后端 <code>ui-route.ts:44-54</code>。</p><h3 id="fetchstatushistory-durationms-3600000" tabindex="-1"><code>fetchStatusHistory(durationMs = 3600000)</code> <a class="header-anchor" href="#fetchstatushistory-durationms-3600000" aria-label="Permalink to &quot;`fetchStatusHistory(durationMs = 3600000)`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">GET</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> /</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ui</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">status</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">history</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">duration</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">ms</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt; → { history: StatusDataPoint[] }</span></span></code></pre></div><p>默认 1 小时窗口。</p><h3 id="fetchconfig" tabindex="-1"><code>fetchConfig</code> <a class="header-anchor" href="#fetchconfig" aria-label="Permalink to &quot;`fetchConfig`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">GET</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> /</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ui</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">config → { config, versions, configPath</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span></code></pre></div><p><code>configPath</code> 是 <code>getConfigPath()</code> 的返回值,供 UI 显示当前用哪份 config。</p><h3 id="saveconfig-config-reload-false" tabindex="-1"><code>saveConfig(config, reload = false)</code> <a class="header-anchor" href="#saveconfig-config-reload-false" aria-label="Permalink to &quot;`saveConfig(config, reload = false)`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">POST</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> /</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ui</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">config</span></span>\n<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Body</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: { </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">configFields, reload }</span></span>\n<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">→ { success, errors</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, reloaded</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, restartingIn</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span></code></pre></div><p>若 <code>reload: true</code> 且 PM2 状态 online,后端会 <code>setTimeout(5000, reloadProcess)</code> 延迟重启。</p><h3 id="fetchrequests-limit-1000" tabindex="-1"><code>fetchRequests(limit = 1000)</code> <a class="header-anchor" href="#fetchrequests-limit-1000" aria-label="Permalink to &quot;`fetchRequests(limit = 1000)`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">GET</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> /</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ui</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">requests</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">limit</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">n</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt; → { requests: RequestSummary[] }</span></span></code></pre></div><h3 id="controlprocess-action" tabindex="-1"><code>controlProcess(action)</code> <a class="header-anchor" href="#controlprocess-action" aria-label="Permalink to &quot;`controlProcess(action)`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">POST</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> /</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ui</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">control</span></span>\n<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Body</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">action</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;start&#39;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> |</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;stop&#39;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> |</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;restart&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>\n<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">→ { success, error</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span></code></pre></div><p><code>restart</code> 后端延迟 1s 重启,同步返回 <code>restartingIn: 1000</code>。</p><h3 id="fetchstats" tabindex="-1"><code>fetchStats</code> <a class="header-anchor" href="#fetchstats" aria-label="Permalink to &quot;`fetchStats`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">GET</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> /</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ui</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">stats → StatsData</span></span></code></pre></div><p>预聚合数据(24h hourly + 30d daily + lastUpdated)。</p><h3 id="fetchtodaystats" tabindex="-1"><code>fetchTodayStats</code> <a class="header-anchor" href="#fetchtodaystats" aria-label="Permalink to &quot;`fetchTodayStats`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">GET</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> /</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ui</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">stats</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">today</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">since</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&lt;</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">local</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> midnight</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> ISO</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt; → TodayStats</span></span></code></pre></div><p>关键实现:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> midnight</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Date</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>\n<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">midnight.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">setHours</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> res</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> fetch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">`${</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">API_BASE</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}/stats/today?since=${</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">encodeURIComponent</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">(</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">midnight</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">toISOString</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">())</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><p><strong>浏览器本地零点</strong> → toISOString 转 UTC 后传给后端。这样「今日」边界随用户时区,与后端预聚合 daily 的硬编码 +8 无关。</p><h3 id="转发导出" tabindex="-1">转发导出 <a class="header-anchor" href="#转发导出" aria-label="Permalink to &quot;转发导出&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { fetchProviders, saveProviders } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;./providers&#39;</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { fetchMcpServers, createMcpServer, updateMcpServer, deleteMcpServer, reconnectMcpServer, fetchMcpTools } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;./mcp&#39;</span></span></code></pre></div><h2 id="api-mcp-ts-—-mcp-server-管理接口" tabindex="-1"><code>api/mcp.ts</code> — MCP Server 管理接口 <a class="header-anchor" href="#api-mcp-ts-—-mcp-server-管理接口" aria-label="Permalink to &quot;`api/mcp.ts` — MCP Server 管理接口&quot;">​</a></h2><h3 id="fetchmcpservers" tabindex="-1"><code>fetchMcpServers</code> <a class="header-anchor" href="#fetchmcpservers" aria-label="Permalink to &quot;`fetchMcpServers`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">GET</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> /</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ui</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">mcp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">servers → { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">servers</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: McpServerWithStatus[] }</span></span></code></pre></div><p>每个 server 包含实时连接状态(connected/disconnected/connecting/not_connected/disabled)和 toolCount。</p><h3 id="createmcpserver-server-mcpserverinput" tabindex="-1"><code>createMcpServer(server: McpServerInput)</code> <a class="header-anchor" href="#createmcpserver-server-mcpserverinput" aria-label="Permalink to &quot;`createMcpServer(server: McpServerInput)`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">POST</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> /</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ui</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">mcp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">servers</span></span>\n<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Body</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">server</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: McpServerInput }</span></span>\n<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">→ { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">success</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: boolean, server</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> McpServerWithStatus, error</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> string }</span></span></code></pre></div><p>认证 required。McpServerInput 含 name, transport_type (stdio/sse/streamable-http), command, args, env, url, headers, enabled。</p><h3 id="updatemcpserver-id-input" tabindex="-1"><code>updateMcpServer(id, input)</code> <a class="header-anchor" href="#updatemcpserver-id-input" aria-label="Permalink to &quot;`updateMcpServer(id, input)`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">PATCH</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> /</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ui</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">mcp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">servers</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:id</span></span>\n<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Body</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: Partial</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">McpServerInput</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&gt;</span></span>\n<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">→ { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">success</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: boolean, server</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> McpServerWithStatus, error</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> string }</span></span></code></pre></div><p>认证 required。更新后触发 mcpManager.reconnectServer。</p><h3 id="deletemcpserver-id" tabindex="-1"><code>deleteMcpServer(id)</code> <a class="header-anchor" href="#deletemcpserver-id" aria-label="Permalink to &quot;`deleteMcpServer(id)`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">DELETE</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> /</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ui</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">mcp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">servers</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:id → { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">success</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: boolean, error</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> string }</span></span></code></pre></div><p>认证 required。先 disconnect 再清 DB。</p><h3 id="reconnectmcpserver-id" tabindex="-1"><code>reconnectMcpServer(id)</code> <a class="header-anchor" href="#reconnectmcpserver-id" aria-label="Permalink to &quot;`reconnectMcpServer(id)`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">POST</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> /</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ui</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">mcp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">servers</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:id</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">reconnect → { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">success</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: boolean, error</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> string }</span></span></code></pre></div><p>认证 required。手动重建连接。</p><h3 id="fetchmcptools" tabindex="-1"><code>fetchMcpTools</code> <a class="header-anchor" href="#fetchmcptools" aria-label="Permalink to &quot;`fetchMcpTools`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">GET</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> /</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ui</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">mcp</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">tools → { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">tools</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: McpTool[] }</span></span></code></pre></div><p>列出所有已发现 MCP tool(name + description + input_schema)。</p><h2 id="api-providers-ts-—-供应商接口" tabindex="-1"><code>api/providers.ts</code> — 供应商接口 <a class="header-anchor" href="#api-providers-ts-—-供应商接口" aria-label="Permalink to &quot;`api/providers.ts` — 供应商接口&quot;">​</a></h2><h3 id="fetchproviders" tabindex="-1"><code>fetchProviders</code> <a class="header-anchor" href="#fetchproviders" aria-label="Permalink to &quot;`fetchProviders`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">GET</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> /</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ui</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">providers → { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">providers</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: Provider[] }</span></span></code></pre></div><p>无认证。</p><h3 id="saveproviders-providers" tabindex="-1"><code>saveProviders(providers)</code> <a class="header-anchor" href="#saveproviders-providers" aria-label="Permalink to &quot;`saveProviders(providers)`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">POST</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> /</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ui</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">api</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">providers</span></span>\n<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Body</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">providers</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: ProviderInput[] }</span></span>\n<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">→ ProviderSaveResult { success, errors</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, error</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span></code></pre></div><p>Destructive 全量替换。写接口,需要 Bearer 认证(但目前前端<strong>未发送 Authorization 头</strong>——只在后端未配置 <code>auth.token</code> 时可用)。</p><h2 id="特点" tabindex="-1">特点 <a class="header-anchor" href="#特点" aria-label="Permalink to &quot;特点&quot;">​</a></h2><ul><li><strong>无统一 wrapper</strong>:每个函数各自 <code>await res.json()</code> 返回,没有拦截器、没有错误转换。调用方自己判断 <code>success / error</code> 字段</li><li><strong>无重试</strong>:网络失败直接 reject</li><li><strong>无 abort signal</strong>:request cancel 未实现(React StrictMode 双渲染时可能产生重复请求,<code>useConfig</code> 里通过 <code>useEffect</code> 空依赖数组避免)</li><li><strong>认证缺失</strong>:<code>saveConfig / saveProviders / controlProcess</code> 都是写接口,但前端不发 <code>Authorization</code> 头。生产环境启用 <code>auth.token</code> 后这些接口会 401。修复方案:加拦截器或在函数签名里传 token 参数</li></ul><h2 id="与-websocket-的分工" tabindex="-1">与 WebSocket 的分工 <a class="header-anchor" href="#与-websocket-的分工" aria-label="Permalink to &quot;与 WebSocket 的分工&quot;">​</a></h2><table tabindex="0"><thead><tr><th>数据</th><th>REST 端点</th><th>WebSocket 消息</th></tr></thead><tbody><tr><td>状态快照</td><td>GET <code>/ui/api/status</code></td><td><code>type=status action=snapshot</code>(每 10s)</td></tr><tr><td>状态历史</td><td>GET <code>/ui/api/status/history</code></td><td>在 <code>status</code> 消息的 <code>data.history</code> 中</td></tr><tr><td>请求摘要</td><td>GET <code>/ui/api/requests</code></td><td><code>type=request action=new</code>(每次新请求推送)</td></tr><tr><td>请求详情</td><td>GET <code>/ui/api/requests/:id</code></td><td>无(懒加载)</td></tr><tr><td>stats 汇总</td><td>GET <code>/ui/api/stats</code></td><td><code>type=stats action=notify</code> → 触发主动 GET</td></tr><tr><td>今日实时</td><td>GET <code>/ui/api/stats/today</code></td><td><code>request</code> 消息到达时主动 GET</td></tr><tr><td>配置</td><td>GET/POST <code>/ui/api/config</code></td><td>无</td></tr><tr><td>供应商</td><td>GET/POST <code>/ui/api/providers</code></td><td>无</td></tr><tr><td>MCP servers</td><td>GET/POST/PATCH/DELETE <code>/ui/api/mcp/servers</code></td><td>无</td></tr><tr><td>MCP tools</td><td>GET <code>/ui/api/mcp/tools</code></td><td>无</td></tr><tr><td>进程控制</td><td>POST <code>/ui/api/control</code></td><td>无</td></tr><tr><td>日志</td><td>无</td><td><code>/ui/api/logs/stream</code> 专用通道</td></tr></tbody></table><p>REST 用于<strong>冷启动 + 请求详情懒加载 + 写操作</strong>;WebSocket 用于<strong>订阅式增量推送</strong>。</p>',66)])])}const E=i(h,[["render",n]]);export{c as __pageData,E as default};
@@ -0,0 +1 @@
1
+ import{_ as i,o as a,c as t,a2 as e}from"./chunks/framework.D_Xv2a7c.js";const c=JSON.parse('{"title":"proxy-cli / API 层","description":"","frontmatter":{},"headers":[],"relativePath":"proxy-cli/api-layer.md","filePath":"proxy-cli/api-layer.md"}'),h={name:"proxy-cli/api-layer.md"};function n(p,s,l,k,r,d){return a(),t("div",null,[...s[0]||(s[0]=[e("",66)])])}const E=i(h,[["render",n]]);export{c as __pageData,E as default};
@@ -0,0 +1,83 @@
1
+ import{_ as i,o as a,c as n,a2 as t}from"./chunks/framework.D_Xv2a7c.js";const o=JSON.parse('{"title":"proxy-cli / 应用外壳","description":"","frontmatter":{},"headers":[],"relativePath":"proxy-cli/app-shell.md","filePath":"proxy-cli/app-shell.md"}'),l={name:"proxy-cli/app-shell.md"};function h(p,s,k,e,E,d){return a(),n("div",null,[...s[0]||(s[0]=[t(`<h1 id="proxy-cli-应用外壳" tabindex="-1">proxy-cli / 应用外壳 <a class="header-anchor" href="#proxy-cli-应用外壳" aria-label="Permalink to &quot;proxy-cli / 应用外壳&quot;">​</a></h1><h2 id="本文档覆盖的源文件" tabindex="-1">本文档覆盖的源文件 <a class="header-anchor" href="#本文档覆盖的源文件" aria-label="Permalink to &quot;本文档覆盖的源文件&quot;">​</a></h2><ul><li><code>apps/proxy-cli/src/main.tsx</code></li><li><code>apps/proxy-cli/src/App.tsx</code></li><li><code>apps/proxy-cli/src/i18n/index.ts</code></li><li><code>apps/proxy-cli/src/i18n/locales/zh/*.json</code></li><li><code>apps/proxy-cli/src/i18n/locales/en/*.json</code></li><li><code>apps/proxy-cli/src/index.css</code></li><li><code>apps/proxy-cli/vite.config.ts</code></li></ul><h2 id="main-tsx-—-挂载入口" tabindex="-1"><code>main.tsx</code> — 挂载入口 <a class="header-anchor" href="#main-tsx-—-挂载入口" aria-label="Permalink to &quot;\`main.tsx\` — 挂载入口&quot;">​</a></h2><p><code>apps/proxy-cli/src/main.tsx:1-19</code>:</p><div class="language-tsx vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ReactDOM </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;react-dom/client&#39;</span></span>
2
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { App } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;./App&#39;</span></span>
3
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;./index.css&#39;</span></span>
4
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;./i18n&#39;</span></span>
5
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> i18n </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;./i18n&#39;</span></span>
6
+ <span class="line"></span>
7
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">document.title </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> i18n.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">t</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;app:title&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
8
+ <span class="line"></span>
9
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> rootElement</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> document.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getElementById</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;root&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
10
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">rootElement) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">throw</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;Could not find root element to mount to&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
11
+ <span class="line"></span>
12
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ReactDOM.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">createRoot</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(rootElement).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">render</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
13
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">React.StrictMode</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
14
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">App</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> /&gt;</span></span>
15
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;/</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">React.StrictMode</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
16
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><ul><li>副作用 import <code>./i18n</code> 完成 i18next 初始化</li><li>同步 <code>document.title = i18n.t(&#39;app:title&#39;)</code>(首次挂载即用当前语言)</li><li>严格模式包裹(开发时双渲染检查副作用)</li><li>无 Provider 树包裹——i18next 用全局单例,无路由(SPA 单页面)</li></ul><h2 id="app-tsx-—-布局" tabindex="-1"><code>App.tsx</code> — 布局 <a class="header-anchor" href="#app-tsx-—-布局" aria-label="Permalink to &quot;\`App.tsx\` — 布局&quot;">​</a></h2><p><code>apps/proxy-cli/src/App.tsx</code>:</p><div class="language-tsx vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> App</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> JSX</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Element</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
17
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">t</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> useTranslation</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;app&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
18
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">versions</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> useConfig</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
19
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">status</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">history</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">requests</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">stats</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">todayStats</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">connectionState</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">loading</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> useWebSocketData</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
20
+ <span class="line"></span>
21
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span></span>
22
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">div</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> className</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;min-h-screen flex flex-col bg-bg-primary text-text-primary&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
23
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">ConnectionBanner</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> connected</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{connectionState </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!==</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;disconnected&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">} /&gt;</span></span>
24
+ <span class="line"></span>
25
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">header</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
26
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">t</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;title&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)} + LanguageSwitcher</span></span>
27
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> 右侧:claudeVersion + projectVersion</span></span>
28
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">header</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
29
+ <span class="line"></span>
30
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">div</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> className</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;px-4 py-2&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
31
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">StatsBarChart</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> stats</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{stats} </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">todayStats</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{todayStats} /&gt;</span></span>
32
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
33
+ <span class="line"></span>
34
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">main</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> className</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;flex-1 flex gap-4 p-4&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
35
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">section</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> className</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;flex-1&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt; &lt;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">RequestHistory</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> requests</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{requests} </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">loading</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{loading} /&gt; &lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">section</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
36
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">section</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> className</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;w-96 flex flex-col gap-4&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
37
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">StatusPanel</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> status</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{{ </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">status, history }} /&gt;</span></span>
38
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">ConfigEditor</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> /&gt;</span></span>
39
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">section</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
40
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">main</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
41
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> &lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">div</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">&gt;</span></span>
42
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> )</span></span>
43
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h3 id="布局网格" tabindex="-1">布局网格 <a class="header-anchor" href="#布局网格" aria-label="Permalink to &quot;布局网格&quot;">​</a></h3><div class="language-mermaid vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">mermaid</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">flowchart TD</span></span>
44
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> BANNER[ConnectionBanner&lt;br/&gt;disconnected 时显示红条 fixed top]</span></span>
45
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> HEADER[Header&lt;br/&gt;标题 + LanguageSwitcher + 版本信息]</span></span>
46
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> STATS[StatsBarChart&lt;br/&gt;TodayStatsCards + 柱状图]</span></span>
47
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> MAIN[Main]</span></span>
48
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> MAIN --&gt; LEFT[flex-1&lt;br/&gt;RequestHistory&lt;br/&gt;session 分组 + Compare]</span></span>
49
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> MAIN --&gt; RIGHT[w-96&lt;br/&gt;StatusPanel&lt;br/&gt;+ ConfigEditor]</span></span>
50
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> BANNER --&gt; HEADER</span></span>
51
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> HEADER --&gt; STATS</span></span>
52
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> STATS --&gt; MAIN</span></span></code></pre></div><h3 id="数据源" tabindex="-1">数据源 <a class="header-anchor" href="#数据源" aria-label="Permalink to &quot;数据源&quot;">​</a></h3><ul><li><code>useConfig()</code> → <code>versions</code>(Claude Code 版本 + 项目版本,一次拉 REST)</li><li><code>useWebSocketData()</code> → 五路状态 + 连接状态 + loading(详见 <a href="./data-hooks.html">data-hooks.md</a>)</li><li><code>status</code> 与 <code>history</code> 分开:<code>status</code> 是快照,<code>history</code> 是滑动窗口,<code>StatusPanel</code> 里用扩展合并显示</li></ul><h2 id="i18n-index-ts-—-多语言初始化" tabindex="-1"><code>i18n/index.ts</code> — 多语言初始化 <a class="header-anchor" href="#i18n-index-ts-—-多语言初始化" aria-label="Permalink to &quot;\`i18n/index.ts\` — 多语言初始化&quot;">​</a></h2><p><code>apps/proxy-cli/src/i18n/index.ts</code>:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">i18n</span></span>
53
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> .</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">use</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(LanguageDetector) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// navigator + localStorage</span></span>
54
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> .</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">use</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(initReactI18next)</span></span>
55
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> .</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">init</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
56
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> resources: {</span></span>
57
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> zh: { common, app, status, log, config, providers },</span></span>
58
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> en: { common, app, status, log, config, providers }</span></span>
59
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
60
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> fallbackLng: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;zh&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
61
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ns: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;common&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;app&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;status&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;log&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;config&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;providers&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
62
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> defaultNS: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;common&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
63
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> interpolation: { escapeValue: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
64
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> detection: {</span></span>
65
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> order: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;localStorage&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;navigator&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
66
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> caches: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;localStorage&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
67
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> lookupLocalStorage: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;i18nextLng&#39;</span></span>
68
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
69
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> })</span></span>
70
+ <span class="line"></span>
71
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">i18n.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">on</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;languageChanged&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { document.title </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> i18n.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">t</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;app:title&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) })</span></span></code></pre></div><h3 id="_6-命名空间" tabindex="-1">6 命名空间 <a class="header-anchor" href="#_6-命名空间" aria-label="Permalink to &quot;6 命名空间&quot;">​</a></h3><ul><li><code>common</code> — 全局标签、按钮文案(默认命名空间)</li><li><code>app</code> — 顶部标题、Token 类别标签、连接状态、请求相关文案</li><li><code>status</code> — 状态面板的图表标题</li><li><code>log</code> — 日志相关(当前 UI 主流程未大量使用)</li><li><code>config</code> — 配置编辑器的字段名与操作</li><li><code>providers</code> — 供应商管理弹窗</li></ul><h3 id="语言侦测" tabindex="-1">语言侦测 <a class="header-anchor" href="#语言侦测" aria-label="Permalink to &quot;语言侦测&quot;">​</a></h3><ul><li>首次访问:localStorage 无 <code>i18nextLng</code> → 用 <code>navigator.language</code></li><li>切换:<code>LanguageSwitcher</code> 调 <code>i18n.changeLanguage(&#39;zh&#39; | &#39;en&#39;)</code>,写 localStorage</li><li>每次切换 emit <code>languageChanged</code> → 同步刷新 <code>document.title</code></li></ul><h2 id="languageswitcher-tsx" tabindex="-1"><code>LanguageSwitcher.tsx</code> <a class="header-anchor" href="#languageswitcher-tsx" aria-label="Permalink to &quot;\`LanguageSwitcher.tsx\`&quot;">​</a></h2><p><code>apps/proxy-cli/src/components/LanguageSwitcher.tsx</code>:</p><div class="language-tsx vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">tsx</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> toggleLanguage</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> () </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
72
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> i18n.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">changeLanguage</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(i18n.language </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">===</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;zh&#39;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ?</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;en&#39;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> :</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;zh&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
73
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>按钮显示当前的<strong>对面</strong>语言(当前中文时显示 <code>EN</code>,反之显示 <code>中</code>)+ <code>Languages</code> 图标。tooltip 是完整语言名。</p><h2 id="index-css-tailwind-4" tabindex="-1"><code>index.css</code> + Tailwind 4 <a class="header-anchor" href="#index-css-tailwind-4" aria-label="Permalink to &quot;\`index.css\` + Tailwind 4&quot;">​</a></h2><p><code>apps/proxy-cli/postcss.config.js</code> 使用 <code>@tailwindcss/postcss</code> 插件。Tailwind 4 直接用 <code>@import &quot;tailwindcss&quot;;</code> 并通过 CSS 变量定义主题色(<code>bg-primary / bg-secondary / bg-card / bg-hover / text-primary / text-muted / border / primary / success / warning / error / accent</code>)。</p><p>App 全屏深色主题(<code>bg-bg-primary text-text-primary</code>)。所有组件的颜色都是「语义命名」而非硬编码色值——支持将来切换主题。</p><h2 id="vite-config-ts" tabindex="-1"><code>vite.config.ts</code> <a class="header-anchor" href="#vite-config-ts" aria-label="Permalink to &quot;\`vite.config.ts\`&quot;">​</a></h2><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineConfig</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
74
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> plugins: [</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">react</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()],</span></span>
75
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> base: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;/ui/&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
76
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> build: { outDir: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;dist&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, sourcemap: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
77
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> server: {</span></span>
78
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> proxy: {</span></span>
79
+ <span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;/ui/api&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: { target: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;http://localhost:3000&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, ws: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
80
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
81
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
82
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> test: { environment: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;jsdom&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, globals: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, setupFiles: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;./src/test/setup.ts&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">] }</span></span>
83
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span></code></pre></div><ul><li><strong><code>base: &#39;/ui/&#39;</code></strong>:所有静态资源前缀 <code>/ui/</code>(生产由 proxy-core <code>@fastify/static</code> 挂在 <code>/ui/</code>)</li><li><strong>dev proxy</strong>:Vite dev server 把 <code>/ui/api/*</code> 反代到 <code>http://localhost:3000</code>(<strong>⚠️ 与 proxy-core 默认端口 9527 不一致</strong>——如果直接跑 <code>pnpm dev:proxy-core</code> 会用 9527,需要手动同步或使用 dev-only 的 port 覆盖)</li><li><strong><code>ws: true</code></strong>:把 WebSocket upgrade 请求也代理</li><li><strong>build.sourcemap: true</strong>:生产也带 sourcemap,便于线上调试</li></ul><p><strong>dev 硬编码 3000</strong>:<code>vite.config.ts:15</code> + <code>hooks/useWebSocketData.ts:88</code> + <code>hooks/useLogs.ts:23</code> 都用 <code>localhost:3000</code>。生产模式用 <code>location.host</code>。</p><h2 id="相关文档" tabindex="-1">相关文档 <a class="header-anchor" href="#相关文档" aria-label="Permalink to &quot;相关文档&quot;">​</a></h2><ul><li>数据 Hook 的实现 → <a href="./data-hooks.html">data-hooks.md</a></li><li>各组件的 UI 结构 → 后续 <code>components-*.md</code></li></ul>`,34)])])}const g=i(l,[["render",h]]);export{o as __pageData,g as default};
@@ -0,0 +1 @@
1
+ import{_ as i,o as a,c as n,a2 as t}from"./chunks/framework.D_Xv2a7c.js";const o=JSON.parse('{"title":"proxy-cli / 应用外壳","description":"","frontmatter":{},"headers":[],"relativePath":"proxy-cli/app-shell.md","filePath":"proxy-cli/app-shell.md"}'),l={name:"proxy-cli/app-shell.md"};function h(p,s,k,e,E,d){return a(),n("div",null,[...s[0]||(s[0]=[t("",34)])])}const g=i(l,[["render",h]]);export{o as __pageData,g as default};