@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.
- package/dist/docs/404.html +22 -0
- package/dist/docs/assets/app.BxFOH0P1.js +1 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.Cuu7C9vz.js +1 -0
- package/dist/docs/assets/chunks/VPLocalSearchBox.CYDhNgXW.js +9 -0
- package/dist/docs/assets/chunks/abnfDiagram-VRR7QNED.RG1C5NpS.js +1 -0
- package/dist/docs/assets/chunks/arc.C9NMazfV.js +1 -0
- package/dist/docs/assets/chunks/architectureDiagram-ZJ3FMSHR.u2IZtOa6.js +36 -0
- package/dist/docs/assets/chunks/blockDiagram-677ZJIJ3.DdHVir7t.js +132 -0
- package/dist/docs/assets/chunks/c4Diagram-LMCZKHZV.gSbgoaJo.js +10 -0
- package/dist/docs/assets/chunks/channel.Cc6zpfFP.js +1 -0
- package/dist/docs/assets/chunks/chunk-2Q5K7J3B.HRSdtksv.js +1 -0
- package/dist/docs/assets/chunks/chunk-32BRIVSS.BYzKapof.js +1 -0
- package/dist/docs/assets/chunks/chunk-5VM5RSS4.c3oeF0uS.js +15 -0
- package/dist/docs/assets/chunks/chunk-EX3LRPZG.Cz5AKl7t.js +231 -0
- package/dist/docs/assets/chunks/chunk-JWPE2WC7.DtJxsA7-.js +1 -0
- package/dist/docs/assets/chunks/chunk-MOJQB5TN.h5kO0Dtu.js +88 -0
- package/dist/docs/assets/chunks/chunk-RYQCIY6F.Ch_NfMTR.js +1 -0
- package/dist/docs/assets/chunks/chunk-V7JOEXUC.CHrHyPoW.js +206 -0
- package/dist/docs/assets/chunks/chunk-VR4S4FIN.DG8DIrH3.js +1 -0
- package/dist/docs/assets/chunks/chunk-XXDRQBXY.CSXBN12Y.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-OUVF2IWQ.DV5B4KLJ.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-v2-EOCWNBFH.DV5B4KLJ.js +1 -0
- package/dist/docs/assets/chunks/cose-bilkent-JH36ORCC.BeFuOTgi.js +1 -0
- package/dist/docs/assets/chunks/cynefin-VYW2F7L2.DaXIfh7Y.js +178 -0
- package/dist/docs/assets/chunks/cynefinDiagram-TSTJHNR4.BrJcHEEe.js +62 -0
- package/dist/docs/assets/chunks/cytoscape.esm.CUqq0XTU.js +331 -0
- package/dist/docs/assets/chunks/dagre-VKFMJZFB.D4vaA23X.js +4 -0
- package/dist/docs/assets/chunks/defaultLocale.DX6XiGOO.js +1 -0
- package/dist/docs/assets/chunks/diagram-FQU43EPY.uwRFLKRx.js +3 -0
- package/dist/docs/assets/chunks/diagram-G47NLZAW.Byfc9d0H.js +24 -0
- package/dist/docs/assets/chunks/diagram-NH7WQ7WH.CxjBEGZX.js +24 -0
- package/dist/docs/assets/chunks/diagram-OA4YK3LP.CU1jGXMi.js +30 -0
- package/dist/docs/assets/chunks/diagram-WEI45ONY.yXgVkURA.js +41 -0
- package/dist/docs/assets/chunks/ebnfDiagram-CCIWWBDH.UucqGQ_d.js +1 -0
- package/dist/docs/assets/chunks/erDiagram-Q63AITRT.C6qmOrvh.js +85 -0
- package/dist/docs/assets/chunks/flowDiagram-23GEKE2U.BZLu-WUl.js +156 -0
- package/dist/docs/assets/chunks/framework.D_Xv2a7c.js +19 -0
- package/dist/docs/assets/chunks/ganttDiagram-NO4QXBWP.DUzsw4Yr.js +292 -0
- package/dist/docs/assets/chunks/gitGraphDiagram-IHSO6WYX.BqLfYTI7.js +106 -0
- package/dist/docs/assets/chunks/graph.C2PyVmSI.js +1 -0
- package/dist/docs/assets/chunks/infoDiagram-FWYZ7A6U.CiKWveW9.js +2 -0
- package/dist/docs/assets/chunks/init.Gi6I4Gst.js +1 -0
- package/dist/docs/assets/chunks/ishikawaDiagram-FXEZZL3T.jerUXEXA.js +70 -0
- package/dist/docs/assets/chunks/journeyDiagram-5HDEW3XC.Cqzvo6I_.js +139 -0
- package/dist/docs/assets/chunks/kanban-definition-HUTT4EX6.BzJ4OPe5.js +89 -0
- package/dist/docs/assets/chunks/katex.C5jXJg4s.js +257 -0
- package/dist/docs/assets/chunks/layout.BG3qr61M.js +1 -0
- package/dist/docs/assets/chunks/linear.hFjgYGMN.js +1 -0
- package/dist/docs/assets/chunks/map.DwDi8XlU.js +1 -0
- package/dist/docs/assets/chunks/mermaid-client.D3gEaJ5e.js +2 -0
- package/dist/docs/assets/chunks/mermaid.core.CEHdFh45.js +314 -0
- package/dist/docs/assets/chunks/mindmap-definition-LN4V7U3C.ChC5FJW6.js +96 -0
- package/dist/docs/assets/chunks/ordinal.BYWQX77i.js +1 -0
- package/dist/docs/assets/chunks/pegDiagram-2B236MQR.ClnjsRYs.js +1 -0
- package/dist/docs/assets/chunks/pieDiagram-ENE6RG2P.Bb0MqerK.js +39 -0
- package/dist/docs/assets/chunks/quadrantDiagram-ABIIQ3AL.Do6HK_yb.js +7 -0
- package/dist/docs/assets/chunks/railroadDiagram-RFXS5EU6.D35m6hQn.js +1 -0
- package/dist/docs/assets/chunks/requirementDiagram-TGXJPOKE.DMtjRYUg.js +84 -0
- package/dist/docs/assets/chunks/sankeyDiagram-HTMAVEWB.dfXDu62B.js +40 -0
- package/dist/docs/assets/chunks/sequenceDiagram-DBY2YBRQ.CLZ0rZTY.js +162 -0
- package/dist/docs/assets/chunks/sizeCapture-X5ZJPWSS.DWvGYLUT.js +1 -0
- package/dist/docs/assets/chunks/stateDiagram-2N3HPSRC.DY8sDkI0.js +1 -0
- package/dist/docs/assets/chunks/stateDiagram-v2-6OUMAXLB.B9v-Vq5L.js +1 -0
- package/dist/docs/assets/chunks/swimlanes-5IMT3BWC.Dy9SffeT.js +2 -0
- package/dist/docs/assets/chunks/swimlanesDiagram-G3AALYLV.Kb9LnCTH.js +8 -0
- package/dist/docs/assets/chunks/theme.BLEczZWC.js +2 -0
- package/dist/docs/assets/chunks/timeline-definition-FHXFAJF6.CH6uzgIu.js +120 -0
- package/dist/docs/assets/chunks/vennDiagram-L72KCM5P.7EBCJmyP.js +34 -0
- package/dist/docs/assets/chunks/wardleyDiagram-EHGQE667.DPHAQssL.js +78 -0
- package/dist/docs/assets/chunks/xychartDiagram-FW5EYKEG.aKgxZVbK.js +7 -0
- package/dist/docs/assets/index.md.p9floL_p.js +1 -0
- package/dist/docs/assets/index.md.p9floL_p.lean.js +1 -0
- package/dist/docs/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
- package/dist/docs/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
- package/dist/docs/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
- package/dist/docs/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
- package/dist/docs/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
- package/dist/docs/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
- package/dist/docs/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
- package/dist/docs/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
- package/dist/docs/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
- package/dist/docs/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
- package/dist/docs/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
- package/dist/docs/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
- package/dist/docs/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
- package/dist/docs/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
- package/dist/docs/assets/overview.md.BKVdLT3o.js +70 -0
- package/dist/docs/assets/overview.md.BKVdLT3o.lean.js +1 -0
- package/dist/docs/assets/packages-utils.md.CvgYp5Ll.js +31 -0
- package/dist/docs/assets/packages-utils.md.CvgYp5Ll.lean.js +1 -0
- package/dist/docs/assets/proxy-admin_env-and-build.md.xkeQNYS3.js +40 -0
- package/dist/docs/assets/proxy-admin_env-and-build.md.xkeQNYS3.lean.js +1 -0
- package/dist/docs/assets/proxy-admin_index.md.DBLI0n0G.js +38 -0
- package/dist/docs/assets/proxy-admin_index.md.DBLI0n0G.lean.js +1 -0
- package/dist/docs/assets/proxy-admin_layout-and-menu.md.BKGcu49p.js +48 -0
- package/dist/docs/assets/proxy-admin_layout-and-menu.md.BKGcu49p.lean.js +1 -0
- package/dist/docs/assets/proxy-admin_pages.md.m_fGvvOH.js +51 -0
- package/dist/docs/assets/proxy-admin_pages.md.m_fGvvOH.lean.js +1 -0
- package/dist/docs/assets/proxy-admin_routing-and-auth.md.DZsdFese.js +106 -0
- package/dist/docs/assets/proxy-admin_routing-and-auth.md.DZsdFese.lean.js +1 -0
- package/dist/docs/assets/proxy-admin_services-and-mock.md.sdNPcf25.js +66 -0
- package/dist/docs/assets/proxy-admin_services-and-mock.md.sdNPcf25.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_api-layer.md.GfdbtEUx.js +1 -0
- package/dist/docs/assets/proxy-cli_api-layer.md.GfdbtEUx.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_app-shell.md.Do18CYhW.js +83 -0
- package/dist/docs/assets/proxy-cli_app-shell.md.Do18CYhW.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_components-common.md.Dd6Yazvz.js +23 -0
- package/dist/docs/assets/proxy-cli_components-common.md.Dd6Yazvz.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_components-config.md.B81Y3ta2.js +46 -0
- package/dist/docs/assets/proxy-cli_components-config.md.B81Y3ta2.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_components-requests.md.vN8IrwL_.js +84 -0
- package/dist/docs/assets/proxy-cli_components-requests.md.vN8IrwL_.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_components-stats.md.B90esaNa.js +14 -0
- package/dist/docs/assets/proxy-cli_components-stats.md.B90esaNa.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_components-status.md.C5lAzS2c.js +42 -0
- package/dist/docs/assets/proxy-cli_components-status.md.C5lAzS2c.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_data-hooks.md.w9Oe1OD3.js +87 -0
- package/dist/docs/assets/proxy-cli_data-hooks.md.w9Oe1OD3.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_index.md.BA6g8QD-.js +34 -0
- package/dist/docs/assets/proxy-cli_index.md.BA6g8QD-.lean.js +1 -0
- package/dist/docs/assets/proxy-cli_utils-and-i18n.md.Ch_e-g_o.js +34 -0
- package/dist/docs/assets/proxy-cli_utils-and-i18n.md.Ch_e-g_o.lean.js +1 -0
- package/dist/docs/assets/proxy-core_chat-api.md.DHihiBxR.js +152 -0
- package/dist/docs/assets/proxy-core_chat-api.md.DHihiBxR.lean.js +1 -0
- package/dist/docs/assets/proxy-core_cli.md.DCFYX4Bd.js +37 -0
- package/dist/docs/assets/proxy-core_cli.md.DCFYX4Bd.lean.js +1 -0
- package/dist/docs/assets/proxy-core_config.md.BXSOyxYE.js +83 -0
- package/dist/docs/assets/proxy-core_config.md.BXSOyxYE.lean.js +1 -0
- package/dist/docs/assets/proxy-core_data-layer.md.Cdomb3Gz.js +85 -0
- package/dist/docs/assets/proxy-core_data-layer.md.Cdomb3Gz.lean.js +1 -0
- package/dist/docs/assets/proxy-core_entry.md.BZmIcCUM.js +90 -0
- package/dist/docs/assets/proxy-core_entry.md.BZmIcCUM.lean.js +1 -0
- package/dist/docs/assets/proxy-core_index.md.BM6VV5Qe.js +55 -0
- package/dist/docs/assets/proxy-core_index.md.BM6VV5Qe.lean.js +1 -0
- package/dist/docs/assets/proxy-core_pm2.md.DUhWEtgn.js +79 -0
- package/dist/docs/assets/proxy-core_pm2.md.DUhWEtgn.lean.js +1 -0
- package/dist/docs/assets/proxy-core_providers.md.CbDZ6b_7.js +1 -0
- package/dist/docs/assets/proxy-core_providers.md.CbDZ6b_7.lean.js +1 -0
- package/dist/docs/assets/proxy-core_proxy.md.CzQYmX6X.js +46 -0
- package/dist/docs/assets/proxy-core_proxy.md.CzQYmX6X.lean.js +1 -0
- package/dist/docs/assets/proxy-core_stats.md.BsM6wuK_.js +42 -0
- package/dist/docs/assets/proxy-core_stats.md.BsM6wuK_.lean.js +1 -0
- package/dist/docs/assets/proxy-core_tool.md.B6Le1nQr.js +100 -0
- package/dist/docs/assets/proxy-core_tool.md.B6Le1nQr.lean.js +1 -0
- package/dist/docs/assets/proxy-core_ui-routes.md.Dyqkeoiv.js +27 -0
- package/dist/docs/assets/proxy-core_ui-routes.md.Dyqkeoiv.lean.js +1 -0
- package/dist/docs/assets/proxy-core_utilities.md.C18pjnkz.js +63 -0
- package/dist/docs/assets/proxy-core_utilities.md.C18pjnkz.lean.js +1 -0
- package/dist/docs/assets/quickstart.md.Cy_FmXIY.js +38 -0
- package/dist/docs/assets/quickstart.md.Cy_FmXIY.lean.js +1 -0
- package/dist/docs/assets/request-flow.md.C1fyxdPE.js +146 -0
- package/dist/docs/assets/request-flow.md.C1fyxdPE.lean.js +1 -0
- package/dist/docs/assets/style.DU_kNMWy.css +1 -0
- package/dist/docs/hashmap.json +1 -0
- package/dist/docs/index.html +25 -0
- package/dist/docs/overview.html +94 -0
- package/dist/docs/packages-utils.html +55 -0
- package/dist/docs/proxy-admin/env-and-build.html +64 -0
- package/dist/docs/proxy-admin/index.html +62 -0
- package/dist/docs/proxy-admin/layout-and-menu.html +72 -0
- package/dist/docs/proxy-admin/pages.html +75 -0
- package/dist/docs/proxy-admin/routing-and-auth.html +130 -0
- package/dist/docs/proxy-admin/services-and-mock.html +90 -0
- package/dist/docs/proxy-cli/api-layer.html +38 -0
- package/dist/docs/proxy-cli/app-shell.html +107 -0
- package/dist/docs/proxy-cli/components-common.html +47 -0
- package/dist/docs/proxy-cli/components-config.html +70 -0
- package/dist/docs/proxy-cli/components-requests.html +108 -0
- package/dist/docs/proxy-cli/components-stats.html +38 -0
- package/dist/docs/proxy-cli/components-status.html +66 -0
- package/dist/docs/proxy-cli/data-hooks.html +111 -0
- package/dist/docs/proxy-cli/index.html +58 -0
- package/dist/docs/proxy-cli/utils-and-i18n.html +58 -0
- package/dist/docs/proxy-core/chat-api.html +176 -0
- package/dist/docs/proxy-core/cli.html +61 -0
- package/dist/docs/proxy-core/config.html +107 -0
- package/dist/docs/proxy-core/data-layer.html +109 -0
- package/dist/docs/proxy-core/entry.html +114 -0
- package/dist/docs/proxy-core/index.html +79 -0
- package/dist/docs/proxy-core/pm2.html +103 -0
- package/dist/docs/proxy-core/providers.html +39 -0
- package/dist/docs/proxy-core/proxy.html +70 -0
- package/dist/docs/proxy-core/stats.html +66 -0
- package/dist/docs/proxy-core/tool.html +124 -0
- package/dist/docs/proxy-core/ui-routes.html +51 -0
- package/dist/docs/proxy-core/utilities.html +87 -0
- package/dist/docs/quickstart.html +62 -0
- package/dist/docs/request-flow.html +170 -0
- package/dist/docs/vp-icons.css +0 -0
- package/dist/server/proxy.js +2 -1
- package/dist/ui/assets/{1c-KmWe8RWs.js → 1c-DPsrzNHI.js} +1 -1
- package/dist/ui/assets/{abnf-BKQ6qIuo.js → abnf-DNkBIQRO.js} +1 -1
- package/dist/ui/assets/{abnfDiagram-VRR7QNED-CkRuDPu1.js → abnfDiagram-VRR7QNED-BqvHvzR8.js} +1 -1
- package/dist/ui/assets/{accesslog-DD9H5Ktc.js → accesslog-D5NxQ43Q.js} +1 -1
- package/dist/ui/assets/{actionscript-CAjf2Qtd.js → actionscript-DLr-LB2m.js} +1 -1
- package/dist/ui/assets/{ada-BXkXW16O.js → ada-BRSz3tHX.js} +1 -1
- package/dist/ui/assets/{angelscript-BxT7o0Up.js → angelscript-DMtEGgIa.js} +1 -1
- package/dist/ui/assets/{apache-C5z_tmVm.js → apache-C4gn4cSd.js} +1 -1
- package/dist/ui/assets/{applescript-DdIxl8rr.js → applescript-DoodcTwg.js} +1 -1
- package/dist/ui/assets/{arc-hSdFaqKn.js → arc-HmnzaGf9.js} +1 -1
- package/dist/ui/assets/{arcade-D5m0roat.js → arcade-RJZZSHSl.js} +1 -1
- package/dist/ui/assets/{architectureDiagram-ZJ3FMSHR-DOSHSqzf.js → architectureDiagram-ZJ3FMSHR-BUfDpSIw.js} +1 -1
- package/dist/ui/assets/{arduino-FDap8kq-.js → arduino-n6Dpx6Ig.js} +1 -1
- package/dist/ui/assets/{armasm-Kzp-Jr1v.js → armasm-DzCVITGB.js} +1 -1
- package/dist/ui/assets/{asciidoc-DbGMW3EE.js → asciidoc-CaqMsApq.js} +1 -1
- package/dist/ui/assets/{aspectj-CVYMmBCO.js → aspectj-B0kIcV0v.js} +1 -1
- package/dist/ui/assets/{autohotkey-9PmBGTPd.js → autohotkey-xUEXewap.js} +1 -1
- package/dist/ui/assets/{autoit-B4F86jgh.js → autoit-D3OfN2VX.js} +1 -1
- package/dist/ui/assets/{avrasm-CSzv2eHX.js → avrasm-Cbf0F4Kf.js} +1 -1
- package/dist/ui/assets/{awk-CjsvYvZE.js → awk-Cc0rWEwe.js} +1 -1
- package/dist/ui/assets/{axapta-BVgMoNRY.js → axapta-BKEeoUEe.js} +1 -1
- package/dist/ui/assets/{bash-IeBjW3pt.js → bash-D6JH6L3m.js} +1 -1
- package/dist/ui/assets/{basic-BTFJfmV1.js → basic-ka6JXc9C.js} +1 -1
- package/dist/ui/assets/{blockDiagram-677ZJIJ3-DLw3Bbhf.js → blockDiagram-677ZJIJ3-BHXRSjnM.js} +1 -1
- package/dist/ui/assets/{bnf-rCkeRYk0.js → bnf-Bxclk5tZ.js} +1 -1
- package/dist/ui/assets/{brainfuck-DBHuB3uZ.js → brainfuck--s_Fd8b9.js} +1 -1
- package/dist/ui/assets/{coq-TwFFolHa.js → c-BsgdDna0.js} +1 -1
- package/dist/ui/assets/{c-like-CK1xGeX_.js → c-like-CNkOkbqh.js} +1 -1
- package/dist/ui/assets/{c4Diagram-LMCZKHZV-cqY51yJw.js → c4Diagram-LMCZKHZV-Bp1uSrW8.js} +1 -1
- package/dist/ui/assets/{cal-BxGPpEZK.js → cal-LVlIOy9W.js} +1 -1
- package/dist/ui/assets/{capnproto-Bo2fgXF9.js → capnproto-r9DiQ1H8.js} +1 -1
- package/dist/ui/assets/{ceylon-C4Bb4pNB.js → ceylon-CTNzyZJX.js} +1 -1
- package/dist/ui/assets/channel-_rFUXR2i.js +1 -0
- package/dist/ui/assets/{chunk-2Q5K7J3B-CGTiTBmo.js → chunk-2Q5K7J3B-nnLVtUW3.js} +1 -1
- package/dist/ui/assets/{chunk-32BRIVSS-DWagYBp9.js → chunk-32BRIVSS-BDNS6igp.js} +1 -1
- package/dist/ui/assets/{chunk-5VM5RSS4-BzSBMKJX.js → chunk-5VM5RSS4-D713xBhI.js} +1 -1
- package/dist/ui/assets/{chunk-EX3LRPZG-4-aKwCgZ.js → chunk-EX3LRPZG-DExsU6Rd.js} +1 -1
- package/dist/ui/assets/{chunk-JWPE2WC7-CPC_cBN0.js → chunk-JWPE2WC7-DcpW5RnW.js} +1 -1
- package/dist/ui/assets/{chunk-MOJQB5TN-DrDE4H9w.js → chunk-MOJQB5TN-BQiSZNTn.js} +1 -1
- package/dist/ui/assets/{chunk-RYQCIY6F-DkdXe_kU.js → chunk-RYQCIY6F-DfblgZPd.js} +1 -1
- package/dist/ui/assets/{chunk-V7JOEXUC-Da6EWcQt.js → chunk-V7JOEXUC-np--VgmN.js} +1 -1
- package/dist/ui/assets/{chunk-VR4S4FIN-nP6dstD5.js → chunk-VR4S4FIN-BG0IhjO6.js} +1 -1
- package/dist/ui/assets/{chunk-XXDRQBXY-Bi_rRAPA.js → chunk-XXDRQBXY-DHuoh-RB.js} +1 -1
- package/dist/ui/assets/classDiagram-OUVF2IWQ-DqgbMzM1.js +1 -0
- package/dist/ui/assets/classDiagram-v2-EOCWNBFH-DqgbMzM1.js +1 -0
- package/dist/ui/assets/{clean-cc1m9AxK.js → clean-CtVj0-EB.js} +1 -1
- package/dist/ui/assets/{clojure-DX5V8QA8.js → clojure-CZwle60-.js} +1 -1
- package/dist/ui/assets/{clojure-repl-FzjnVNWQ.js → clojure-repl-DJXWH00I.js} +1 -1
- package/dist/ui/assets/{cmake-COZZyrKs.js → cmake-Boxf0e7r.js} +1 -1
- package/dist/ui/assets/{coffeescript-DBsnOmC4.js → coffeescript-h85ZW4Gm.js} +1 -1
- package/dist/ui/assets/{c-C95V0zHL.js → coq-CVLui3m8.js} +1 -1
- package/dist/ui/assets/{cos-Dm5g-IQT.js → cos-CL0igafw.js} +1 -1
- package/dist/ui/assets/{cose-bilkent-JH36ORCC-B3-weOQF.js → cose-bilkent-JH36ORCC-CnXyotYB.js} +1 -1
- package/dist/ui/assets/{cpp-_RZxQjg7.js → cpp-vite1NvJ.js} +1 -1
- package/dist/ui/assets/{crmsh-DGPJ11Gt.js → crmsh-DqT9g0Iq.js} +1 -1
- package/dist/ui/assets/{crystal-BOMSPGge.js → crystal-Oans-K8G.js} +1 -1
- package/dist/ui/assets/{csharp-DZXiHH72.js → csharp-sCaDAzIB.js} +1 -1
- package/dist/ui/assets/{csp-DDSIMUoU.js → csp-rMcp93pK.js} +1 -1
- package/dist/ui/assets/{css-Bjye-ZWr.js → css-BwDLHi_h.js} +1 -1
- package/dist/ui/assets/{cynefin-VYW2F7L2-Cj5c4L3y.js → cynefin-VYW2F7L2-D8Bmecdd.js} +1 -1
- package/dist/ui/assets/{cynefinDiagram-TSTJHNR4-BYsfTeNX.js → cynefinDiagram-TSTJHNR4-BT2YFmPZ.js} +1 -1
- package/dist/ui/assets/{d-22pfurOx.js → d-BFgZm0RV.js} +1 -1
- package/dist/ui/assets/{dagre-VKFMJZFB-DiEob-by.js → dagre-VKFMJZFB-BeJU73ex.js} +1 -1
- package/dist/ui/assets/{dart-Doiu8cDW.js → dart-rIo85iL3.js} +1 -1
- package/dist/ui/assets/{delphi-CQ7epp84.js → delphi-Bi2Rfp1o.js} +1 -1
- package/dist/ui/assets/{diagram-FQU43EPY-BOPbQcL4.js → diagram-FQU43EPY-CHQiS5Fr.js} +1 -1
- package/dist/ui/assets/{diagram-G47NLZAW-C1UWDJTx.js → diagram-G47NLZAW-EVerd4V8.js} +1 -1
- package/dist/ui/assets/{diagram-NH7WQ7WH-CYsBqW3J.js → diagram-NH7WQ7WH-DMP0VOAs.js} +1 -1
- package/dist/ui/assets/{diagram-OA4YK3LP-Dnag0x_3.js → diagram-OA4YK3LP-CAur5jK9.js} +1 -1
- package/dist/ui/assets/{diagram-WEI45ONY-Bo4CsDoj.js → diagram-WEI45ONY-DvmKkPH7.js} +1 -1
- package/dist/ui/assets/{diff-Cs6VQQZt.js → diff-CZZCIG00.js} +1 -1
- package/dist/ui/assets/{django-Bo3okOrw.js → django-D88PKHy-.js} +1 -1
- package/dist/ui/assets/{dns-BpG60eIX.js → dns-DX4hzjUh.js} +1 -1
- package/dist/ui/assets/{dockerfile-BWyH8SlV.js → dockerfile-1lgzEXn1.js} +1 -1
- package/dist/ui/assets/{dos-DWlNbaB9.js → dos-CwrC1ROy.js} +1 -1
- package/dist/ui/assets/{dsconfig-D_8y8YrJ.js → dsconfig-tvVdBv4w.js} +1 -1
- package/dist/ui/assets/{dts-Cz4SyMYR.js → dts-DTgQkdRs.js} +1 -1
- package/dist/ui/assets/{dust-Cu4qLkeH.js → dust-BbLlyCpf.js} +1 -1
- package/dist/ui/assets/{ebnf-CTVHui3r.js → ebnf-D6Dc4oRr.js} +1 -1
- package/dist/ui/assets/{ebnfDiagram-CCIWWBDH-epcXQLEj.js → ebnfDiagram-CCIWWBDH-Kvilk1RF.js} +1 -1
- package/dist/ui/assets/{elixir-MAlwXhfU.js → elixir-CnMolQVs.js} +1 -1
- package/dist/ui/assets/{elm-Bdmwbvef.js → elm-BQ7VQFn7.js} +1 -1
- package/dist/ui/assets/{erDiagram-Q63AITRT-Bb60TqAM.js → erDiagram-Q63AITRT-C-S9oHZd.js} +1 -1
- package/dist/ui/assets/{erb-Ce9TpP4g.js → erb-B_1g6fXE.js} +1 -1
- package/dist/ui/assets/{erlang-CN2GEiqk.js → erlang-3b3ITXJu.js} +1 -1
- package/dist/ui/assets/{erlang-repl-D8K4O_cp.js → erlang-repl-Cy6Z3TdH.js} +1 -1
- package/dist/ui/assets/{excel-eVZU1r0f.js → excel-DtkATto8.js} +1 -1
- package/dist/ui/assets/{fix-BzKerEv0.js → fix-DsEG7TDI.js} +1 -1
- package/dist/ui/assets/{flix-B9CE3skV.js → flix-CQ-rKwGO.js} +1 -1
- package/dist/ui/assets/{flowDiagram-23GEKE2U-DzMLZIyt.js → flowDiagram-23GEKE2U-EbHDNMCC.js} +1 -1
- package/dist/ui/assets/{fortran-B4__3vos.js → fortran-AqzaRCEt.js} +1 -1
- package/dist/ui/assets/{fsharp-BJ3-ARHz.js → fsharp-CCzWGasu.js} +1 -1
- package/dist/ui/assets/{gams-Cu43oSYT.js → gams-Bqa6CB_r.js} +1 -1
- package/dist/ui/assets/{ganttDiagram-NO4QXBWP-D_aAoMRP.js → ganttDiagram-NO4QXBWP-B6jvc6O7.js} +1 -1
- package/dist/ui/assets/{gauss-T8vk_TpE.js → gauss-D4Utubeh.js} +1 -1
- package/dist/ui/assets/{gcode-9j3BicpZ.js → gcode-By3KwWjb.js} +1 -1
- package/dist/ui/assets/{gherkin-Dyh5KFG-.js → gherkin-PXOPjT7Y.js} +1 -1
- package/dist/ui/assets/{gitGraphDiagram-IHSO6WYX-CMxCHC-Z.js → gitGraphDiagram-IHSO6WYX-C5l6rHvK.js} +1 -1
- package/dist/ui/assets/{glsl-DWWjN4ts.js → glsl-KmmyBk93.js} +1 -1
- package/dist/ui/assets/{gml-BcYE-D5A.js → gml-C1Qw_Nrt.js} +1 -1
- package/dist/ui/assets/{go-DUnUzOEI.js → go-DaBQtdp1.js} +1 -1
- package/dist/ui/assets/{golo-BDoc1QQL.js → golo-D7PDzNpb.js} +1 -1
- package/dist/ui/assets/{gradle-B_WRa_bT.js → gradle-nXueCYH-.js} +1 -1
- package/dist/ui/assets/{groovy-CgjqFq1e.js → groovy-DFDsQDhl.js} +1 -1
- package/dist/ui/assets/{haml-DCqcg7Ti.js → haml-B_zxHzy_.js} +1 -1
- package/dist/ui/assets/{handlebars-DSDUQrnw.js → handlebars-BdMY-8KA.js} +1 -1
- package/dist/ui/assets/{haskell-DPVnctVi.js → haskell-CftsIPps.js} +1 -1
- package/dist/ui/assets/{haxe-BuCGXBa4.js → haxe-BFZb0OIE.js} +1 -1
- package/dist/ui/assets/{hsp-BTKpS_u0.js → hsp-EPTuqwtZ.js} +1 -1
- package/dist/ui/assets/{htmlbars-Cql3Jvy2.js → htmlbars-B7ZSC-iN.js} +1 -1
- package/dist/ui/assets/{http-BB8I9jUh.js → http-BxSd_aa1.js} +1 -1
- package/dist/ui/assets/{hy-DG7xkZNz.js → hy-D-rBN9MQ.js} +1 -1
- package/dist/ui/assets/index-CWFn1h-J.css +10 -0
- package/dist/ui/assets/{index-CfTIGTiY.js → index-DSGZBcd1.js} +166 -171
- package/dist/ui/assets/{index-DqIiCkSD.js → index-Dlp8uGHu.js} +3 -3
- package/dist/ui/assets/{infoDiagram-FWYZ7A6U-DIzEV-BJ.js → infoDiagram-FWYZ7A6U-BOF_kBqe.js} +1 -1
- package/dist/ui/assets/{inform7-BWNpVEkA.js → inform7-OjpbRXZf.js} +1 -1
- package/dist/ui/assets/{ini-BMw_C8EP.js → ini-Dc-QApXQ.js} +1 -1
- package/dist/ui/assets/{irpf90-Cy42ibFZ.js → irpf90-C4OfYiST.js} +1 -1
- package/dist/ui/assets/{isbl-CjFSc0hz.js → isbl-9km6K6Sf.js} +1 -1
- package/dist/ui/assets/{ishikawaDiagram-FXEZZL3T-BZcxp5am.js → ishikawaDiagram-FXEZZL3T-BvKSD8LY.js} +1 -1
- package/dist/ui/assets/{java-BDxe9dp1.js → java-C2mOf3QX.js} +1 -1
- package/dist/ui/assets/{javascript-CgLkkj7h.js → javascript-_i0Q5MkQ.js} +1 -1
- package/dist/ui/assets/{jboss-cli-C8biclrb.js → jboss-cli-BS5ipQOv.js} +1 -1
- package/dist/ui/assets/{journeyDiagram-5HDEW3XC-BbJu6m6Q.js → journeyDiagram-5HDEW3XC-yKdSl63P.js} +1 -1
- package/dist/ui/assets/{json-BjJKhmM6.js → json-Dci0MO4x.js} +1 -1
- package/dist/ui/assets/{julia-DvKEpg-R.js → julia-bEqo4nlV.js} +1 -1
- package/dist/ui/assets/{julia-repl-BDJWZxkU.js → julia-repl-Co6hf47q.js} +1 -1
- package/dist/ui/assets/{kanban-definition-HUTT4EX6-DeIVPlbv.js → kanban-definition-HUTT4EX6-B7BbZCd6.js} +1 -1
- package/dist/ui/assets/{kotlin-DCoXcnEb.js → kotlin-krx8WewB.js} +1 -1
- package/dist/ui/assets/{lasso-C7m0QmV2.js → lasso-d3ZTv9Tj.js} +1 -1
- package/dist/ui/assets/{latex-SHnTG9Eq.js → latex-BNWbHYxK.js} +1 -1
- package/dist/ui/assets/{ldif-_6hUnKPV.js → ldif-Bs8eb63L.js} +1 -1
- package/dist/ui/assets/{leaf-Co9qxlaF.js → leaf-BTbRDVWB.js} +1 -1
- package/dist/ui/assets/{less-CJRDPwNA.js → less-DH5cqJTD.js} +1 -1
- package/dist/ui/assets/{lisp-JEHGYbiW.js → lisp-CBUvBYtR.js} +1 -1
- package/dist/ui/assets/{livecodeserver-BSYaUj4k.js → livecodeserver-CkM7-E4a.js} +1 -1
- package/dist/ui/assets/{livescript-WQMCQeuz.js → livescript-DomXyXUO.js} +1 -1
- package/dist/ui/assets/{llvm-DnAHqj5I.js → llvm-e_-ff59-.js} +1 -1
- package/dist/ui/assets/{lsl--k-ghYia.js → lsl-BNDsGOmv.js} +1 -1
- package/dist/ui/assets/{lua-CXb23hbC.js → lua-_ZmkXwc_.js} +1 -1
- package/dist/ui/assets/{makefile-CM7o86yn.js → makefile-BhG7cThe.js} +1 -1
- package/dist/ui/assets/{markdown-HB3HvChQ.js → markdown-ClW2SRy6.js} +1 -1
- package/dist/ui/assets/{mathematica-9NTuf22N.js → mathematica-kqoCR611.js} +1 -1
- package/dist/ui/assets/{matlab-CWv-ik4r.js → matlab-DqawyK3q.js} +1 -1
- package/dist/ui/assets/{maxima-CqYiKCrw.js → maxima-B0qzCXe1.js} +1 -1
- package/dist/ui/assets/{mel-BbsRpUm5.js → mel-BZaSas3B.js} +1 -1
- package/dist/ui/assets/{mercury-Cz2j4HhU.js → mercury-ByD0wyJH.js} +1 -1
- package/dist/ui/assets/{mindmap-definition-LN4V7U3C-WyJS8oye.js → mindmap-definition-LN4V7U3C-Ce6QsaH5.js} +1 -1
- package/dist/ui/assets/{mipsasm-BqWSRbQV.js → mipsasm-B08lqZSo.js} +1 -1
- package/dist/ui/assets/{mizar-JLBfQ6vt.js → mizar-7iaUqWPq.js} +1 -1
- package/dist/ui/assets/{mojolicious-D0LbMmyk.js → mojolicious-CbH-d8Wh.js} +1 -1
- package/dist/ui/assets/{monkey-DAGL6-JN.js → monkey-D5z6-hFH.js} +1 -1
- package/dist/ui/assets/{moonscript-DzbwNSKy.js → moonscript-DuLd7pdm.js} +1 -1
- package/dist/ui/assets/{n1ql-dkgKq6Yv.js → n1ql-EbVfQMfD.js} +1 -1
- package/dist/ui/assets/{nginx-AUoaDPV4.js → nginx-D-4AxpHP.js} +1 -1
- package/dist/ui/assets/{nim-CdqYmVrl.js → nim-wPHQEX5v.js} +1 -1
- package/dist/ui/assets/{nix-CxmVjwwo.js → nix-6SVkxAXi.js} +1 -1
- package/dist/ui/assets/{node-repl-B1Z3zUAh.js → node-repl-CaFKEOyj.js} +1 -1
- package/dist/ui/assets/{nsis-CTAuPWhe.js → nsis-BmqbwVv_.js} +1 -1
- package/dist/ui/assets/{objectivec-CvbKeAPz.js → objectivec-BX0R-sI2.js} +1 -1
- package/dist/ui/assets/{ocaml-DCiyXKOH.js → ocaml-CyfdrIqo.js} +1 -1
- package/dist/ui/assets/{openscad-CPGUwmeR.js → openscad-B5qfaF1E.js} +1 -1
- package/dist/ui/assets/{oxygene-CI_bD1Gw.js → oxygene-CmlCgXLr.js} +1 -1
- package/dist/ui/assets/{parser3-C91CVs85.js → parser3-DdpPyZkn.js} +1 -1
- package/dist/ui/assets/{pegDiagram-2B236MQR-yF8AW7GR.js → pegDiagram-2B236MQR-ByyVqaXh.js} +1 -1
- package/dist/ui/assets/{perl-ChxfKl-n.js → perl-D3qc2wEe.js} +1 -1
- package/dist/ui/assets/{pf-CKCHkzIA.js → pf-Bv3zza37.js} +1 -1
- package/dist/ui/assets/{pgsql-BwOP20uH.js → pgsql-BZIppw1a.js} +1 -1
- package/dist/ui/assets/{php-B7Rs2tM5.js → php-D1ScecZC.js} +1 -1
- package/dist/ui/assets/{php-template-Cx-Fh4AR.js → php-template-sEqzzKWJ.js} +1 -1
- package/dist/ui/assets/{pieDiagram-ENE6RG2P-BS4hnGNX.js → pieDiagram-ENE6RG2P-T1OgWN3l.js} +1 -1
- package/dist/ui/assets/{plaintext-U7qkdtgS.js → plaintext-DO7Jy_T2.js} +1 -1
- package/dist/ui/assets/{pony-_fGYgePh.js → pony-CTXTp2Tb.js} +1 -1
- package/dist/ui/assets/{powershell-CFBTcUce.js → powershell-C9lzZsbj.js} +1 -1
- package/dist/ui/assets/{processing-BWHneU0K.js → processing-hzJAP_Li.js} +1 -1
- package/dist/ui/assets/{profile-BJ-HxhzS.js → profile-bFiAkh7e.js} +1 -1
- package/dist/ui/assets/{prolog-ChHo7n6L.js → prolog-CE0trHSn.js} +1 -1
- package/dist/ui/assets/{properties-e_DOYclC.js → properties-MeANnTVc.js} +1 -1
- package/dist/ui/assets/{protobuf-5aGSIv7w.js → protobuf-S-rp7SK0.js} +1 -1
- package/dist/ui/assets/{puppet-D2vQatzX.js → puppet-B5YT8Ct1.js} +1 -1
- package/dist/ui/assets/{purebasic-n6krfaeF.js → purebasic-DO-5HeDl.js} +1 -1
- package/dist/ui/assets/{python-CbIo0XxP.js → python-DVGTQbwU.js} +1 -1
- package/dist/ui/assets/{python-repl-BpIq9kyr.js → python-repl-CQ4VlKLC.js} +1 -1
- package/dist/ui/assets/{q-jntnvcCx.js → q-nS96imov.js} +1 -1
- package/dist/ui/assets/{qml-BafQlZNV.js → qml-BkzkCgUU.js} +1 -1
- package/dist/ui/assets/{quadrantDiagram-ABIIQ3AL-C3Th8mUJ.js → quadrantDiagram-ABIIQ3AL-BkaCzlXD.js} +1 -1
- package/dist/ui/assets/{r-CHgvQFLK.js → r-y4Q5t85r.js} +1 -1
- package/dist/ui/assets/{railroadDiagram-RFXS5EU6-CMQkbGJl.js → railroadDiagram-RFXS5EU6-C1lbwk19.js} +1 -1
- package/dist/ui/assets/{reasonml-DNwlPD_T.js → reasonml-Bzhzc5Ao.js} +1 -1
- package/dist/ui/assets/{requirementDiagram-TGXJPOKE-B70_oR7v.js → requirementDiagram-TGXJPOKE-C8Rw6N2I.js} +1 -1
- package/dist/ui/assets/{rib-CX4e9JSF.js → rib-BP3Y9dW3.js} +1 -1
- package/dist/ui/assets/{roboconf-ee4qsPGf.js → roboconf-87QE7cIh.js} +1 -1
- package/dist/ui/assets/{routeros-BJSwvu2L.js → routeros-BV3nt8wW.js} +1 -1
- package/dist/ui/assets/{rsl-BiKdMl_F.js → rsl-DfQf4CW_.js} +1 -1
- package/dist/ui/assets/{ruby-CAXTU5LY.js → ruby-DQxFKbgX.js} +1 -1
- package/dist/ui/assets/{ruleslanguage-C1kgDGXM.js → ruleslanguage-B8oCm_aw.js} +1 -1
- package/dist/ui/assets/{rust-DyEf_GXL.js → rust-DzZgPf9W.js} +1 -1
- package/dist/ui/assets/{sankeyDiagram-HTMAVEWB-CvUfseMg.js → sankeyDiagram-HTMAVEWB-Dxiuo8Hz.js} +1 -1
- package/dist/ui/assets/{sas-Q1rlUxPH.js → sas-CFh-Rsrv.js} +1 -1
- package/dist/ui/assets/{scala-Dg6KNmge.js → scala-3UDyJBiS.js} +1 -1
- package/dist/ui/assets/{scheme-D9iooUxI.js → scheme-KaUTge9W.js} +1 -1
- package/dist/ui/assets/{scilab-CztEJXJY.js → scilab-CLSBZzuh.js} +1 -1
- package/dist/ui/assets/{scss-BMh-JkdE.js → scss-DaEkfHWX.js} +1 -1
- package/dist/ui/assets/{sequenceDiagram-DBY2YBRQ-DB0c9kf4.js → sequenceDiagram-DBY2YBRQ-Cv__zR2v.js} +1 -1
- package/dist/ui/assets/{shell-DWo6z0MG.js → shell-B0d4cZTk.js} +1 -1
- package/dist/ui/assets/{sizeCapture-X5ZJPWSS-BcQlgjfD.js → sizeCapture-X5ZJPWSS-C4nD-ShQ.js} +1 -1
- package/dist/ui/assets/{smali-Cijeb6pL.js → smali-CLhfky4R.js} +1 -1
- package/dist/ui/assets/{smalltalk-D0lvqa_d.js → smalltalk-B4aaTMO5.js} +1 -1
- package/dist/ui/assets/{sml-B-vqWZ3b.js → sml-x4CTxWEZ.js} +1 -1
- package/dist/ui/assets/{sqf-BJ-1Q583.js → sqf-G_0vdVVs.js} +1 -1
- package/dist/ui/assets/{sql-CMGLxEYV.js → sql-C--WH0Fo.js} +1 -1
- package/dist/ui/assets/{sql_more-gsRmbNCH.js → sql_more-B4LrzCtd.js} +1 -1
- package/dist/ui/assets/{stan-D1AlTSpf.js → stan-CACDFOA0.js} +1 -1
- package/dist/ui/assets/{stata-DnEYviI0.js → stata-BP9M7sZt.js} +1 -1
- package/dist/ui/assets/{stateDiagram-2N3HPSRC-BSRgVsHO.js → stateDiagram-2N3HPSRC-z3-31Cr2.js} +1 -1
- package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-BKIXFHzO.js +1 -0
- package/dist/ui/assets/{step21-DbQV9sMo.js → step21-MAOu4dNb.js} +1 -1
- package/dist/ui/assets/{stylus-Cyc7vdUc.js → stylus-CpuP3pvE.js} +1 -1
- package/dist/ui/assets/{subunit-16ipyMie.js → subunit-NWzuqFhT.js} +1 -1
- package/dist/ui/assets/{swift-DTNnw4qS.js → swift-DuFKNmKv.js} +1 -1
- package/dist/ui/assets/{swimlanes-5IMT3BWC-DgOdcc4_.js → swimlanes-5IMT3BWC-E463-rXd.js} +2 -2
- package/dist/ui/assets/swimlanesDiagram-G3AALYLV-CkQvBOYs.js +8 -0
- package/dist/ui/assets/{taggerscript-DM6pvUWE.js → taggerscript-BDnv2jvg.js} +1 -1
- package/dist/ui/assets/{tap-Ch-uyKZq.js → tap-aB2cLXdf.js} +1 -1
- package/dist/ui/assets/{tcl-D0T_V5dA.js → tcl-7WepIaIa.js} +1 -1
- package/dist/ui/assets/{thrift-D9xJjYw4.js → thrift-BLh6pdjc.js} +1 -1
- package/dist/ui/assets/{timeline-definition-FHXFAJF6-BBeDMHxb.js → timeline-definition-FHXFAJF6-FA_RNhFQ.js} +1 -1
- package/dist/ui/assets/{tp-kUrCGo9X.js → tp-D1rt5u_j.js} +1 -1
- package/dist/ui/assets/{twig-Cgub6rxA.js → twig-DgfeYg4W.js} +1 -1
- package/dist/ui/assets/{typescript-BxNP9Ap9.js → typescript-oU560Q8V.js} +1 -1
- package/dist/ui/assets/{vala-DF9ZZagU.js → vala-DlXsaz2B.js} +1 -1
- package/dist/ui/assets/{vbnet-Cf46ypDg.js → vbnet-BjpxjeMZ.js} +1 -1
- package/dist/ui/assets/{vbscript-DNs-QKLH.js → vbscript-DfNdtdO3.js} +1 -1
- package/dist/ui/assets/{vbscript-html-DyS6I5L1.js → vbscript-html-D09WPsgK.js} +1 -1
- package/dist/ui/assets/{vennDiagram-L72KCM5P-8WpWycE-.js → vennDiagram-L72KCM5P-zaCDWwTs.js} +1 -1
- package/dist/ui/assets/{verilog-CF5wC4X-.js → verilog-B9vENtLK.js} +1 -1
- package/dist/ui/assets/{vhdl-Dm0jpDMn.js → vhdl-CJLTZOu1.js} +1 -1
- package/dist/ui/assets/{vim-nyO2DRAx.js → vim-FuPhupu9.js} +1 -1
- package/dist/ui/assets/{wardleyDiagram-EHGQE667-UeIOK-jv.js → wardleyDiagram-EHGQE667-BS8ApwmV.js} +1 -1
- package/dist/ui/assets/{x86asm-BNw2-6GG.js → x86asm-kX_Cp6wB.js} +1 -1
- package/dist/ui/assets/{xl-D-YHxr6V.js → xl-MuHNmLUj.js} +1 -1
- package/dist/ui/assets/{xml-BijAlrow.js → xml-Mbn2z12n.js} +1 -1
- package/dist/ui/assets/{xquery-z0wxWBKz.js → xquery-Dy4lt-m-.js} +1 -1
- package/dist/ui/assets/{xychartDiagram-FW5EYKEG-BNzHLweN.js → xychartDiagram-FW5EYKEG-DoNZtZus.js} +1 -1
- package/dist/ui/assets/{yaml-n5TIQArR.js → yaml-CxxAisfE.js} +1 -1
- package/dist/ui/assets/{zephir-DrGhH8jG.js → zephir-WWG8qyld.js} +1 -1
- package/dist/ui/index.html +2 -2
- package/package.json +2 -2
- package/dist/ui/assets/channel-D9Y4iN1l.js +0 -1
- package/dist/ui/assets/classDiagram-OUVF2IWQ-C4UVH6RI.js +0 -1
- package/dist/ui/assets/classDiagram-v2-EOCWNBFH-C4UVH6RI.js +0 -1
- package/dist/ui/assets/index-CK_lJsTu.css +0 -10
- package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-BLdfpGJO.js +0 -1
- package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DRVnkg3M.js +0 -8
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import{_ as i,o as a,c as n,a2 as t}from"./chunks/framework.D_Xv2a7c.js";const g=JSON.parse('{"title":"proxy-core / 配置与日志","description":"","frontmatter":{},"headers":[],"relativePath":"proxy-core/config.md","filePath":"proxy-core/config.md"}'),h={name:"proxy-core/config.md"};function l(k,s,p,e,d,E){return a(),n("div",null,[...s[0]||(s[0]=[t(`<h1 id="proxy-core-配置与日志" tabindex="-1">proxy-core / 配置与日志 <a class="header-anchor" href="#proxy-core-配置与日志" aria-label="Permalink to "proxy-core / 配置与日志""></a></h1><h2 id="本文档覆盖的源文件" tabindex="-1">本文档覆盖的源文件 <a class="header-anchor" href="#本文档覆盖的源文件" aria-label="Permalink to "本文档覆盖的源文件""></a></h2><ul><li><code>apps/proxy-core/src/config/schema.ts</code></li><li><code>apps/proxy-core/src/config/index.ts</code></li><li><code>apps/proxy-core/src/logger/index.ts</code></li><li><code>apps/proxy-core/src/types/config.ts</code> / <code>log.ts</code></li></ul><h2 id="zod-schema" tabindex="-1">Zod Schema <a class="header-anchor" href="#zod-schema" aria-label="Permalink to "Zod Schema""></a></h2><p><code>apps/proxy-core/src/config/schema.ts:3-29</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;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> AppConfigSchema</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">object</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
2
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> server: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">object</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
3
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> port: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">number</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">int</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">min</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">max</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">65535</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
4
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> host: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">min</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
5
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }),</span></span>
|
|
6
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> proxy: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">object</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
7
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> target: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">url</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(),</span></span>
|
|
8
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> changeOrigin: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">boolean</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(),</span></span>
|
|
9
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> rewritePrefix: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">optional</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(),</span></span>
|
|
10
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> apiKey: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">min</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">optional</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
|
11
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }),</span></span>
|
|
12
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> logging: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">object</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
13
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> level: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">enum</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">([</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'debug'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'info'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'warn'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'error'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]),</span></span>
|
|
14
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> file: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">min</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
15
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> maxSize: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'10m'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
16
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> interval: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'1d'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
17
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> compress: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">boolean</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
18
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }),</span></span>
|
|
19
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> storage: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">object</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
20
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> type: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">enum</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">([</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'sqlite'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'sqlite'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
21
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">min</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'logs/proxy.db'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
22
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> maxDays: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">number</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">int</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">min</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:#6F42C1;--shiki-dark:#B392F0;">default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">7</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
23
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">optional</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">default</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ type: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'sqlite'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, path: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'logs/proxy.db'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, maxDays: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">7</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }),</span></span>
|
|
24
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> auth: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">object</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
25
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> token: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">min</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
26
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">optional</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
|
27
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span>
|
|
28
|
+
<span class="line"></span>
|
|
29
|
+
<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;"> validateConfig</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:#005CC5;--shiki-dark:#79B8FF;"> unknown</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;"> ValidationResult</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></code></pre></div><h3 id="字段说明" tabindex="-1">字段说明 <a class="header-anchor" href="#字段说明" aria-label="Permalink to "字段说明""></a></h3><table tabindex="0"><thead><tr><th>段</th><th>字段</th><th>必填</th><th>默认</th><th>备注</th></tr></thead><tbody><tr><td>server</td><td>port</td><td>✔</td><td>—</td><td>1..65535</td></tr><tr><td>server</td><td>host</td><td>✔</td><td>—</td><td>空串会拒</td></tr><tr><td>proxy</td><td>target</td><td>✔</td><td>—</td><td>必须合法 URL</td></tr><tr><td>proxy</td><td>changeOrigin</td><td>✔</td><td>—</td><td>实际上目前<strong>未使用</strong>(应用层 fetch 无 <code>changeOrigin</code> 概念,代码里不读它)</td></tr><tr><td>proxy</td><td>rewritePrefix</td><td>✖</td><td>—</td><td>目前<strong>未使用</strong>,早期透明代理遗留</td></tr><tr><td>proxy</td><td>apiKey</td><td>✖</td><td>—</td><td>若设置,替换客户端 <code>x-api-key</code> / <code>Authorization</code> 发给上游</td></tr><tr><td>logging</td><td>level</td><td>✔</td><td>—</td><td>Pino level 枚举</td></tr><tr><td>logging</td><td>file</td><td>✔</td><td>—</td><td>相对路径按 config 所在目录解析</td></tr><tr><td>logging</td><td>maxSize</td><td>✖</td><td><code>'10m'</code></td><td>file-stream-rotator 参数</td></tr><tr><td>logging</td><td>interval</td><td>✖</td><td><code>'1d'</code></td><td>rotator 参数(当前代码固定用 <code>frequency: 'daily'</code>)</td></tr><tr><td>logging</td><td>compress</td><td>✖</td><td><code>true</code></td><td>rotator 参数(当前代码没启用 gzip)</td></tr><tr><td>storage</td><td>type</td><td>✖</td><td><code>'sqlite'</code></td><td>只有 sqlite 一个选项</td></tr><tr><td>storage</td><td>path</td><td>✖</td><td><code>'logs/proxy.db'</code></td><td>相对路径按 config 目录解析</td></tr><tr><td>storage</td><td>maxDays</td><td>✖</td><td>7</td><td>0 或负数 = 不清理</td></tr><tr><td>auth</td><td>token</td><td>✖</td><td>—</td><td>非空字符串;未配置时不校验</td></tr></tbody></table><h3 id="校验入口" tabindex="-1">校验入口 <a class="header-anchor" href="#校验入口" aria-label="Permalink to "校验入口""></a></h3><p><code>validateConfig(config)</code>(<code>schema.ts:33-45</code>)返回 <code>{ valid: true, data }</code> 或 <code>{ valid: false, errors: [{field, message}] }</code>。</p><h2 id="配置加载" tabindex="-1">配置加载 <a class="header-anchor" href="#配置加载" aria-label="Permalink to "配置加载""></a></h2><p><code>apps/proxy-core/src/config/index.ts:7-33</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;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> async</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> loadConfig</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">configPath</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getConfigPath</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;"><</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">AppConfig</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">> {</span></span>
|
|
30
|
+
<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;">fsSync.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">existsSync</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(configPath)) {</span></span>
|
|
31
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> ensureDataDirs</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
|
32
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> resetConfig</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(configPath) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 首次运行自动写默认</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;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> content</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> fs.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">readFile</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(configPath, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'utf-8'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
35
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> raw</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</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;">(content)</span></span>
|
|
36
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> result</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> validateConfig</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(raw)</span></span>
|
|
37
|
+
<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;">result.valid) </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;"> ConfigError</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>
|
|
38
|
+
<span class="line"></span>
|
|
39
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> configDir</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">dirname</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(configPath)</span></span>
|
|
40
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> config</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> result.data</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!</span></span>
|
|
41
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (config.logging.file </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&&</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> !</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">isAbsolute</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(config.logging.file)) {</span></span>
|
|
42
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> config.logging.file </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">resolve</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(configDir, config.logging.file)</span></span>
|
|
43
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
44
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (config.storage?.path </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&&</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> !</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">isAbsolute</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(config.storage.path)) {</span></span>
|
|
45
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> config.storage.path </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">resolve</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(configDir, config.storage.path)</span></span>
|
|
46
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
47
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> config</span></span>
|
|
48
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><ul><li><strong>首次自动初始化</strong>:文件不存在 → <code>ensureDataDirs</code>(建 <code>~/.cc-monitoring/logs</code>) + <code>resetConfig</code>(写默认)</li><li><strong>相对路径归一化</strong>:<code>logging.file</code> 和 <code>storage.path</code> 未绝对路径时,以 config 文件所在目录为基准解析。这让「移动 config 到别处 → 相关文件也跟着走」的行为直觉</li><li><strong>校验失败即抛</strong>:不 fallback,服务不启动</li></ul><h3 id="默认配置" tabindex="-1">默认配置 <a class="header-anchor" href="#默认配置" aria-label="Permalink to "默认配置""></a></h3><p><code>config/index.ts:43-64</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;">{</span></span>
|
|
49
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> server</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">port</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">9527</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">host</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'localhost'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
50
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> proxy</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
|
|
51
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> target</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'https://ark.cn-beijing.volces.com/api/coding'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
52
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> changeOrigin</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span></span>
|
|
53
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
54
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> logging</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">level</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'info'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">file</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'logs/proxy.log'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">maxSize</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'10m'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">interval</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'1d'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">compress</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
55
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> storage</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: { </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">type</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'sqlite'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">path</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'logs/proxy.db'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">maxDays</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">7</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
56
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>(<code>host: 'localhost'</code>——但仓库根 <code>config.json</code> 是 <code>0.0.0.0</code>,这是用户手动改的。)</p><h3 id="保存与重置" tabindex="-1">保存与重置 <a class="header-anchor" href="#保存与重置" aria-label="Permalink to "保存与重置""></a></h3><ul><li><code>saveConfig(config, path?)</code>:先 <code>validateConfig</code> 再 <code>fs.writeFile</code>(<code>JSON.stringify(..., 2)</code> 缩进两格)</li><li><code>resetConfig(path?)</code>:<code>saveConfig(defaultConfig, path)</code> 覆盖当前文件</li><li><code>ConfigError</code>:自定义 Error 子类,<code>name = 'ConfigError'</code></li></ul><h2 id="logger" tabindex="-1">Logger <a class="header-anchor" href="#logger" aria-label="Permalink to "Logger""></a></h2><p><code>apps/proxy-core/src/logger/index.ts:25-68</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;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createLogger</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;"> LogConfig</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;"> pino</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Logger</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
57
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> fs.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">mkdirSync</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">dirname</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(config.file), { recursive: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> })</span></span>
|
|
58
|
+
<span class="line"></span>
|
|
59
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> patternFilename</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">join</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(dirname, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">\`\${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">basename</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}-%DATE%.log\`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
60
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> rotatingStream</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> rotator.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getStream</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
61
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> filename: patternFilename,</span></span>
|
|
62
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> frequency: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'daily'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
63
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> date_format: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'YYYY-MM-DD'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
64
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> size: config.maxSize </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">||</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '10m'</span></span>
|
|
65
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> })</span></span>
|
|
66
|
+
<span class="line"></span>
|
|
67
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> dualStream</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
68
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> write</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:#005CC5;--shiki-dark:#79B8FF;"> string</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>
|
|
69
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> rotatingStream.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">write</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(data)</span></span>
|
|
70
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> try</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
71
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> log</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</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;">(data)</span></span>
|
|
72
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">\`[\${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">time</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}] \${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">coloredLevel</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">} (\${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">pid</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}): \${</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">cyan</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">(</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">msg</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">)</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}\${</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">formatBindings</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">(</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">log</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>
|
|
73
|
+
<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;"> {</span></span>
|
|
74
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(data)</span></span>
|
|
75
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
76
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
77
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
78
|
+
<span class="line"></span>
|
|
79
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> pino</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ level: config.level, timestamp: pino.stdTimeFunctions.isoTime }, dualStream)</span></span>
|
|
80
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p><strong>双输出机制</strong>:把 <code>dualStream</code> 传给 pino 作为唯一 sink。每条日志同时进两个 destination:</p><ul><li>轮转文件(<code>file-stream-rotator</code> 按天切分 <code>proxy-YYYY-MM-DD.log</code>;size 超过 10m 也切)</li><li>终端 console(重新解析 JSON 后带 ANSI 颜色美化输出)</li></ul><p><strong>颜色映射</strong>(<code>levelColor</code>):</p><ul><li>trace → 紫</li><li>debug → 青</li><li>info → 绿</li><li>warn → 黄</li><li>error → 红</li><li>fatal → 红底白字</li></ul><p><strong>msg 用青色</strong>。<code>formatBindings</code> 单独把 <code>reqId / req / res / responseTime</code> 从 log 对象中挑出来另起一行显示,避免与主消息挤在一起。</p><h3 id="只有-frequency-daily" tabindex="-1">只有 <code>frequency: 'daily'</code> <a class="header-anchor" href="#只有-frequency-daily" aria-label="Permalink to "只有 \`frequency: 'daily'\`""></a></h3><p>尽管 schema 允许 <code>interval</code> 配置,代码里目前<strong>硬编码</strong> <code>frequency: 'daily'</code>,<code>config.logging.interval</code> 只有默认值 <code>'1d'</code> 才与实际行为一致。改成小时/其它需修改 <code>createLogger</code>。</p><h3 id="无-gzip-压缩" tabindex="-1">无 gzip 压缩 <a class="header-anchor" href="#无-gzip-压缩" aria-label="Permalink to "无 gzip 压缩""></a></h3><p><code>config.logging.compress</code> 是 schema 里的字段,但 <code>rotator.getStream</code> 调用未传对应参数——目前不启用压缩。</p><h2 id="readlogs" tabindex="-1"><code>readLogs</code> <a class="header-anchor" href="#readlogs" aria-label="Permalink to "\`readLogs\`""></a></h2><p><code>logger/index.ts:96-133</code>:CLI <code>logs</code> 命令使用。</p><ul><li>读整个 <code>filePath</code> → split lines</li><li>按 <code>options.level</code>(把用户传的 <code>'info'</code> 等映射到 <code>pino</code> 的数值 level 30)过滤</li><li>按 <code>options.grep</code> 做大小写不敏感 substring 匹配</li><li>按 <code>options.limit</code> 截尾(保留最新 N 行)</li></ul><p>一次性读整个文件,日志膨胀到几十 MB 时会占内存;日常运维(默认 50 行)无感。</p><h2 id="fastify-集成" tabindex="-1">Fastify 集成 <a class="header-anchor" href="#fastify-集成" aria-label="Permalink to "Fastify 集成""></a></h2><p><code>server/index.ts:17-21</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;"> fastify</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Fastify</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
81
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> logger: logger </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;"> FastifyBaseLogger</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
82
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> trustProxy: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span></span>
|
|
83
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span></code></pre></div><p><code>FastifyBaseLogger</code> 与 <code>pino.Logger</code> 类型定义有差异,<code>as unknown as</code> 强转(<code>server/index.ts:5-6</code> 也导入了 <code>FastifyBaseLogger</code>)。所有 <code>request.log.info(...)</code> 都最终进 pino 的 dualStream。</p><h2 id="类型" tabindex="-1">类型 <a class="header-anchor" href="#类型" aria-label="Permalink to "类型""></a></h2><p><code>src/types/config.ts</code> 单独定义了 <code>ServerConfig / ProxyConfig / LogConfig / StorageConfig / AuthConfig</code>(供其它文件 import,不是 Zod 推导)。Zod 的 <code>AppConfig</code> 是主类型;<code>types/config.ts</code> 的等价接口是<strong>冗余定义</strong>,历史遗留(Zod 加入前)。</p><p><code>src/types/log.ts</code> 定义面向前端的日志形状(<code>LogEntry / RequestSummaryEntry / LogItem</code>),不是本文的重点,见 <a href="./../proxy-cli/utils-and-i18n.html">../proxy-cli/utils-and-i18n.md</a>。</p>`,43)])])}const o=i(h,[["render",l]]);export{g as __pageData,o 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 g=JSON.parse('{"title":"proxy-core / 配置与日志","description":"","frontmatter":{},"headers":[],"relativePath":"proxy-core/config.md","filePath":"proxy-core/config.md"}'),h={name:"proxy-core/config.md"};function l(k,s,p,e,d,E){return a(),n("div",null,[...s[0]||(s[0]=[t("",43)])])}const o=i(h,[["render",l]]);export{g as __pageData,o as default};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import{_ as i,o as a,c as e,a2 as t}from"./chunks/framework.D_Xv2a7c.js";const E=JSON.parse('{"title":"proxy-core / 数据层","description":"","frontmatter":{},"headers":[],"relativePath":"proxy-core/data-layer.md","filePath":"proxy-core/data-layer.md"}'),n={name:"proxy-core/data-layer.md"};function d(l,s,p,h,r,k){return a(),e("div",null,[...s[0]||(s[0]=[t(`<h1 id="proxy-core-数据层" tabindex="-1">proxy-core / 数据层 <a class="header-anchor" href="#proxy-core-数据层" aria-label="Permalink to "proxy-core / 数据层""></a></h1><h2 id="本文档覆盖的源文件" tabindex="-1">本文档覆盖的源文件 <a class="header-anchor" href="#本文档覆盖的源文件" aria-label="Permalink to "本文档覆盖的源文件""></a></h2><ul><li><code>apps/proxy-core/src/utils/db.ts</code></li><li><code>apps/proxy-core/src/utils/request-writer.ts</code></li><li><code>apps/proxy-core/src/utils/migrate-files-to-db.ts</code></li></ul><h2 id="单例-db" tabindex="-1">单例 DB <a class="header-anchor" href="#单例-db" aria-label="Permalink to "单例 DB""></a></h2><p><code>utils/db.ts</code>。文件级私有变量:</p><ul><li><code>dbPath: string | null</code>——由 <code>configureDbPath(absPath)</code> 设置(<code>server/index.ts:13-15</code> 在 loadConfig 后立即设)</li><li><code>db: Database.Database | null</code>——首次 <code>initDatabase()</code> 时创建</li></ul><p><code>initDatabase()</code> 幂等:已初始化则直接返回。首次会:</p><ol><li>用 <code>dbPath || path.join(logsDir, 'proxy.db')</code> 作为绝对路径</li><li><code>mkdirSync</code> 确保父目录存在</li><li><code>new Database(resolvedPath)</code></li><li><code>PRAGMA journal_mode = WAL</code>(并发读友好)</li><li><code>PRAGMA synchronous = NORMAL</code>(写延迟合理,掉电容忍)</li><li>建 <code>schema_version</code> 表 → 查当前 version → 逐版应用迁移</li></ol><p><code>closeDatabase()</code>:Fastify <code>onClose</code> 钩子调用(<code>proxy.ts:170-173</code>)。</p><p><code>getDatabase()</code>:未 init 抛错,供 handler 中同步查询。</p><h2 id="schema-迁移" tabindex="-1">Schema 迁移 <a class="header-anchor" href="#schema-迁移" aria-label="Permalink to "Schema 迁移""></a></h2><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;">graph LR</span></span>
|
|
2
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> V0[schema_version = 0] --> V1["v1: requests + stats"]</span></span>
|
|
3
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> V1 --> V2["v2: providers"]</span></span>
|
|
4
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> V2 --> V3["v3: ADD is_default"]</span></span>
|
|
5
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> V3 --> V4["v4: rebuild providers<br/>去掉 NOT NULL"]</span></span>
|
|
6
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> V4 --> V5["v5: machine_id + mcp_servers"]</span></span></code></pre></div><p><code>initDatabase()</code> 中的 4 个 <code>if (currentVersion < N)</code> 顺序应用,每次成功后 <code>INSERT OR REPLACE INTO schema_version</code> 更新版本号。冷启动新库会一次跑完 v1→v4;旧库按需增量。</p><h3 id="v1-applyschemav1-db-ts-134-210" tabindex="-1">v1:<code>applySchemaV1</code>(<code>db.ts:134-210</code>) <a class="header-anchor" href="#v1-applyschemav1-db-ts-134-210" aria-label="Permalink to "v1:\`applySchemaV1\`(\`db.ts:134-210\`)""></a></h3><p>建两张表 + 索引。</p><p><strong><code>requests</code> 表</strong>(每次请求一行):</p><table tabindex="0"><thead><tr><th>字段</th><th>类型</th><th>含义</th></tr></thead><tbody><tr><td>id</td><td>INTEGER PK AUTOINCREMENT</td><td>内部 ID</td></tr><tr><td>request_id</td><td>TEXT UNIQUE NOT NULL</td><td>云端 <code>x-request-id</code> 或 nanoid</td></tr><tr><td>session_id</td><td>TEXT NOT NULL</td><td><code>x-claude-code-session-id</code></td></tr><tr><td>timestamp</td><td>TEXT NOT NULL</td><td>ISO</td></tr><tr><td>method</td><td>TEXT NOT NULL</td><td>POST/GET/...</td></tr><tr><td>path</td><td>TEXT NOT NULL</td><td><code>/v1/messages</code> 等</td></tr><tr><td>status_code</td><td>INTEGER NOT NULL</td><td>HTTP 状态</td></tr><tr><td>response_time</td><td>INTEGER NOT NULL</td><td>毫秒</td></tr><tr><td>api_key</td><td>TEXT</td><td>客户端原始 key</td></tr><tr><td>proxy_api_key</td><td>TEXT</td><td>实际转给上游的 key</td></tr><tr><td>base_url</td><td>TEXT</td><td>上游 origin</td></tr><tr><td>model</td><td>TEXT</td><td>转发后的 model</td></tr><tr><td>input_tokens</td><td>INTEGER</td><td>提取自 message_delta.usage</td></tr><tr><td>output_tokens</td><td>INTEGER</td><td></td></tr><tr><td>cache_read_tokens</td><td>INTEGER</td><td></td></tr><tr><td>cache_creation_tokens</td><td>INTEGER</td><td></td></tr><tr><td>request_headers</td><td>TEXT</td><td>JSON</td></tr><tr><td>request_body</td><td>TEXT</td><td>JSON</td></tr><tr><td>response_headers</td><td>TEXT</td><td>JSON</td></tr><tr><td>response_events</td><td>TEXT</td><td>JSON(SSE events 数组)</td></tr><tr><td>completed_at</td><td>TEXT</td><td>ISO</td></tr><tr><td>closed_at</td><td>TEXT</td><td>ISO(预留)</td></tr><tr><td>error</td><td>TEXT</td><td>错误串</td></tr><tr><td>created_at</td><td>TEXT DEFAULT CURRENT_TIMESTAMP</td><td></td></tr></tbody></table><p><strong>索引</strong>(<code>db.ts:166-190</code>):</p><ul><li><code>idx_requests_session (session_id, timestamp DESC)</code> — 会话聚合查询</li><li><code>idx_requests_time (timestamp DESC)</code> — 全局时间序</li><li><code>idx_requests_status (status_code)</code> — 错误筛选</li><li><code>idx_requests_path (path)</code></li><li><code>idx_requests_api_key (api_key)</code></li><li><code>idx_requests_proxy_api_key (proxy_api_key)</code></li><li><code>idx_requests_base_url (base_url)</code></li><li><code>idx_requests_model (model)</code></li></ul><p><strong><code>stats</code> 表</strong>(预聚合):</p><table tabindex="0"><thead><tr><th>字段</th><th>类型</th><th>含义</th></tr></thead><tbody><tr><td>id</td><td>INTEGER PK AUTOINCREMENT</td><td></td></tr><tr><td>period</td><td>TEXT NOT NULL</td><td><code>'hourly'</code> / <code>'daily'</code></td></tr><tr><td>period_key</td><td>TEXT NOT NULL</td><td>时间桶键,见下文</td></tr><tr><td>input_tokens</td><td>INTEGER DEFAULT 0</td><td>SUM</td></tr><tr><td>output_tokens</td><td>INTEGER DEFAULT 0</td><td></td></tr><tr><td>cache_read_tokens</td><td>INTEGER DEFAULT 0</td><td></td></tr><tr><td>cache_creation_tokens</td><td>INTEGER DEFAULT 0</td><td></td></tr><tr><td>request_count</td><td>INTEGER DEFAULT 0</td><td></td></tr><tr><td>updated_at</td><td>TEXT DEFAULT CURRENT_TIMESTAMP</td><td></td></tr><tr><td>UNIQUE(period, period_key)</td><td></td><td></td></tr></tbody></table><p><code>period_key</code> 格式:</p><ul><li>hourly:<code>YYYY-MM-DD-HH</code>(UTC)</li><li>daily:<code>YYYY-MM-DD</code>(本地时区 UTC+8,见 <a href="./stats.html">stats.md</a>)</li></ul><h3 id="v2-applyschemav2-db-ts-68-86" tabindex="-1">v2:<code>applySchemaV2</code>(<code>db.ts:68-86</code>) <a class="header-anchor" href="#v2-applyschemav2-db-ts-68-86" aria-label="Permalink to "v2:\`applySchemaV2\`(\`db.ts:68-86\`)""></a></h3><p>建 <code>providers</code> 表 + <code>idx_providers_name</code> 唯一索引。字段见 <a href="./providers.html">providers.md</a>。</p><h3 id="v3-applyschemav3" tabindex="-1">v3:<code>applySchemaV3</code> <a class="header-anchor" href="#v3-applyschemav3" aria-label="Permalink to "v3:\`applySchemaV3\`""></a></h3><p><code>PRAGMA table_info(providers)</code> 找 <code>is_default</code> 列;缺则 <code>ALTER TABLE ADD COLUMN is_default INTEGER NOT NULL DEFAULT 0</code>。</p><h3 id="v4-applyschemav4" tabindex="-1">v4:<code>applySchemaV4</code> <a class="header-anchor" href="#v4-applyschemav4" aria-label="Permalink to "v4:\`applySchemaV4\`""></a></h3><p>SQLite 不能直接改列约束。检测 <code>base_url / api_key / model</code> 是否仍为 NOT NULL,是则:</p><div class="language-sql vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">sql</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;">CREATE</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> TABLE</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> providers_new</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (...允许 </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">NULL</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> 的字段...);</span></span>
|
|
7
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">INSERT INTO</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> providers_new </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">SELECT</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ...;</span></span>
|
|
8
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">DROP</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> TABLE</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> providers;</span></span>
|
|
9
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">ALTER</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> TABLE</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> providers_new RENAME </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">TO</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> providers;</span></span>
|
|
10
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">CREATE</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> UNIQUE INDEX</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> idx_providers_name</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ON</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> providers(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span></code></pre></div><p>条件触发,重复运行安全。</p><h3 id="v5-applyschemav5" tabindex="-1">v5:<code>applySchemaV5</code> <a class="header-anchor" href="#v5-applyschemav5" aria-label="Permalink to "v5:\`applySchemaV5\`""></a></h3><p>两步:</p><ol><li><strong><code>machine_id</code> 列</strong>:<code>PRAGMA table_info(requests)</code> 检测 <code>machine_id</code> 列是否存在,缺失则 <code>ALTER TABLE requests ADD COLUMN machine_id TEXT</code> + 创建索引 <code>idx_requests_machine_id</code></li><li><strong><code>mcp_servers</code> 表</strong>:</li></ol><div class="language-sql vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">sql</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;">CREATE</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> TABLE</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> IF</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> NOT</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> EXISTS</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mcp_servers (</span></span>
|
|
11
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> id </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">INTEGER</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> PRIMARY KEY</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> AUTOINCREMENT,</span></span>
|
|
12
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> name</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> TEXT</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> UNIQUE</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> NOT NULL</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
13
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> transport_type </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">TEXT</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> NOT NULL</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- 'stdio' | 'sse' | 'streamable-http'</span></span>
|
|
14
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> command </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">TEXT</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- stdio transport 的命令</span></span>
|
|
15
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> args </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">TEXT</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- JSON array string</span></span>
|
|
16
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> env </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">TEXT</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- JSON object string</span></span>
|
|
17
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> url</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> TEXT</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- HTTP transport 的 URL</span></span>
|
|
18
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> headers </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">TEXT</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- JSON object string (auth headers)</span></span>
|
|
19
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> enabled</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> INTEGER</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> NOT NULL</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> DEFAULT</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
20
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> created_at </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">TEXT</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> DEFAULT</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CURRENT_TIMESTAMP,</span></span>
|
|
21
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> updated_at </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">TEXT</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> DEFAULT</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CURRENT_TIMESTAMP</span></span>
|
|
22
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
|
|
23
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">CREATE</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> UNIQUE INDEX</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> IF</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> NOT</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> EXISTS</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> idx_mcp_servers_name </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">ON</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> mcp_servers(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span></code></pre></div><h2 id="er-图" tabindex="-1">ER 图 <a class="header-anchor" href="#er-图" aria-label="Permalink to "ER 图""></a></h2><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;">erDiagram</span></span>
|
|
24
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> REQUESTS ||--o{ STATS : "aggregate by hour/day"</span></span>
|
|
25
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> REQUESTS {</span></span>
|
|
26
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text request_id PK</span></span>
|
|
27
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text session_id</span></span>
|
|
28
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text timestamp</span></span>
|
|
29
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text method</span></span>
|
|
30
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text path</span></span>
|
|
31
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> int status_code</span></span>
|
|
32
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> int response_time</span></span>
|
|
33
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text api_key</span></span>
|
|
34
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text proxy_api_key</span></span>
|
|
35
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text base_url</span></span>
|
|
36
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text model</span></span>
|
|
37
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text machine_id</span></span>
|
|
38
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> int input_tokens</span></span>
|
|
39
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> int output_tokens</span></span>
|
|
40
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> int cache_read_tokens</span></span>
|
|
41
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> int cache_creation_tokens</span></span>
|
|
42
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text request_headers</span></span>
|
|
43
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text request_body</span></span>
|
|
44
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text response_headers</span></span>
|
|
45
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text response_events</span></span>
|
|
46
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
47
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> STATS {</span></span>
|
|
48
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text period</span></span>
|
|
49
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text period_key</span></span>
|
|
50
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> int input_tokens</span></span>
|
|
51
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> int output_tokens</span></span>
|
|
52
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> int cache_read_tokens</span></span>
|
|
53
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> int cache_creation_tokens</span></span>
|
|
54
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> int request_count</span></span>
|
|
55
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text updated_at</span></span>
|
|
56
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
57
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> PROVIDERS {</span></span>
|
|
58
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> int id PK</span></span>
|
|
59
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text name UK</span></span>
|
|
60
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text base_url</span></span>
|
|
61
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text api_key</span></span>
|
|
62
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text model</span></span>
|
|
63
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text haiku_model</span></span>
|
|
64
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text sonnet_model</span></span>
|
|
65
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text opus_model</span></span>
|
|
66
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text subagent_model</span></span>
|
|
67
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text provider</span></span>
|
|
68
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> int is_default</span></span>
|
|
69
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text created_at</span></span>
|
|
70
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text updated_at</span></span>
|
|
71
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
|
|
72
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> MCP_SERVERS {</span></span>
|
|
73
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> int id PK</span></span>
|
|
74
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text name UK</span></span>
|
|
75
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text transport_type</span></span>
|
|
76
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text command</span></span>
|
|
77
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text args</span></span>
|
|
78
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text env</span></span>
|
|
79
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text url</span></span>
|
|
80
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text headers</span></span>
|
|
81
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> int enabled</span></span>
|
|
82
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text created_at</span></span>
|
|
83
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text updated_at</span></span>
|
|
84
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span></code></pre></div><p><code>STATS</code> 与 <code>REQUESTS</code> 无外键,靠 <code>stats-aggregator.ts</code> 定时 UPSERT 维持一致性。<code>PROVIDERS</code> 独立表,<code>REQUESTS.base_url</code> 只是快照,不是 FK。<code>MCP_SERVERS</code> 独立表,与 <code>PROVIDERS</code> 无关联——MCP server 是 tool provider,不是 API provider。</p><h2 id="request-writer-ts-三大函数" tabindex="-1"><code>request-writer.ts</code> 三大函数 <a class="header-anchor" href="#request-writer-ts-三大函数" aria-label="Permalink to "\`request-writer.ts\` 三大函数""></a></h2><h3 id="saverequestdb-sessionid-requestid-data" tabindex="-1"><code>saveRequestDB(sessionId, requestId, data)</code> <a class="header-anchor" href="#saverequestdb-sessionid-requestid-data" aria-label="Permalink to "\`saveRequestDB(sessionId, requestId, data)\`""></a></h3><p><code>request-writer.ts:57-104</code>。<code>INSERT OR REPLACE INTO requests</code> 全字段。</p><ul><li><code>response_time</code> 现算:<code>completedAt - timestamp</code>(毫秒)</li><li><code>usage</code> 通过 <code>extractTokenUsage(events)</code> 拿:找 <code>type === 'message_delta'</code> 的 event,取 <code>.usage</code></li><li>所有 JSON 字段:<code>data.xxx ? JSON.stringify(data.xxx) : null</code></li><li><code>INSERT OR REPLACE</code>:若同 <code>request_id</code> 已存在(比如 SSE 完成后覆盖前面写的空占位),直接替换。目前实际上 <code>proxy.ts</code> 只在响应完成时调用一次,占位仅在内存中</li></ul><h3 id="loadrequestdb-compositeid" tabindex="-1"><code>loadRequestDB(compositeId)</code> <a class="header-anchor" href="#loadrequestdb-compositeid" aria-label="Permalink to "\`loadRequestDB(compositeId)\`""></a></h3><p><code>request-writer.ts:107-149</code>。<code>compositeId = sessionId + ':' + requestId</code>。用第一个 <code>:</code> 拆分,然后:</p><div class="language-sql vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">sql</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;">SELECT</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> FROM</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> requests </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">WHERE</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> request_id </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;">AND</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> session_id </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>Error(Request not found: ...)</code>。返回值反向组装:<code>request_headers</code> 等字段 <code>JSON.parse</code> 回对象。</p><h3 id="listrequestdb-limit-1000" tabindex="-1"><code>listRequestDB(limit = 1000)</code> <a class="header-anchor" href="#listrequestdb-limit-1000" aria-label="Permalink to "\`listRequestDB(limit = 1000)\`""></a></h3><p><code>request-writer.ts:152-185</code>。<code>ORDER BY timestamp DESC LIMIT ?</code>。只 SELECT 摘要列(不含 headers/body/events),返回 <code>RequestSummary[]</code>。<code>usage</code> 字段:只要 <code>input_tokens || output_tokens</code> 非空就构造 usage 对象。</p><h3 id="cleanoldrequestsdb-daystokeep-7" tabindex="-1"><code>cleanOldRequestsDB(daysToKeep = 7)</code> <a class="header-anchor" href="#cleanoldrequestsdb-daystokeep-7" aria-label="Permalink to "\`cleanOldRequestsDB(daysToKeep = 7)\`""></a></h3><p><code>request-writer.ts:189-200</code>。<code>daysToKeep <= 0</code> 直接 return。否则:</p><div class="language-sql vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">sql</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;">DELETE</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> FROM</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> requests </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">WHERE</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> timestamp</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>cutoff = now - daysToKeep * 86400000</code>(ISO 串比较)。<strong>每次业务请求都会调</strong>(<code>proxy.ts:233</code>)——SQLite 对 timestamp 索引 DELETE 微秒级,可以承受。</p><h2 id="extracttokenusage" tabindex="-1"><code>extractTokenUsage</code> <a class="header-anchor" href="#extracttokenusage" aria-label="Permalink to "\`extractTokenUsage\`""></a></h2><p><code>request-writer.ts:50-54</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;"> messageDelta</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> events.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">find</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">e</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> e?.type </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">===</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'message_delta'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
85
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> messageDelta?.usage</span></span></code></pre></div><p><code>message_delta</code> 是 Anthropic Messages API 最终事件,<code>usage</code> 里含四个 Token 字段:<code>input_tokens / output_tokens / cache_read_input_tokens / cache_creation_input_tokens</code>。</p><p><strong>JSON 分支不适用</strong>:JSON 响应体作为单一 event 直接 push(<code>proxy.ts:302</code>),<code>type</code> 字段可能不是 <code>message_delta</code>——所以 JSON 错误响应通常无 usage,写库时也是 null。</p><h2 id="一次性迁移脚本-migrate-files-to-db-ts" tabindex="-1">一次性迁移脚本 <code>migrate-files-to-db.ts</code> <a class="header-anchor" href="#一次性迁移脚本-migrate-files-to-db-ts" aria-label="Permalink to "一次性迁移脚本 \`migrate-files-to-db.ts\`""></a></h2><p>历史上请求以 JSON 文件存 <code>logs/requests/<sessionId>/req-<requestId>.json</code>。此脚本一次性把它们导入 SQLite:</p><ul><li><code>REQUESTS_DIR = path.resolve('../../logs/requests')</code>(相对 <code>packages/core</code> 的旧路径——路径已过时,需要在 <code>dist/utils</code> 下手动运行时会失效)</li><li><code>DB_PATH = path.resolve('../../logs/proxy.db')</code></li><li>遍历 sessionId 目录 → <code>req-*.json</code> 文件 → 解构字段 → 事务批量 <code>INSERT OR IGNORE</code></li></ul><p><code>INSERT OR IGNORE</code> 让重复运行安全。<strong>当前项目已切到 SQLite 直写</strong>(<code>saveRequestDB</code>),此脚本不再需要,仅供历史迁移参考。文件底部 <code>migrateFilesToDatabase().then(...)</code> 是自动执行块,直接 <code>node dist/utils/migrate-files-to-db.js</code> 即跑。</p>`,61)])])}const c=i(n,[["render",d]]);export{E as __pageData,c as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as i,o as a,c as e,a2 as t}from"./chunks/framework.D_Xv2a7c.js";const E=JSON.parse('{"title":"proxy-core / 数据层","description":"","frontmatter":{},"headers":[],"relativePath":"proxy-core/data-layer.md","filePath":"proxy-core/data-layer.md"}'),n={name:"proxy-core/data-layer.md"};function d(l,s,p,h,r,k){return a(),e("div",null,[...s[0]||(s[0]=[t("",61)])])}const c=i(n,[["render",d]]);export{E as __pageData,c as default};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import{_ as i,o as a,c as n,a2 as e}from"./chunks/framework.D_Xv2a7c.js";const E=JSON.parse('{"title":"proxy-core / 启动链","description":"","frontmatter":{},"headers":[],"relativePath":"proxy-core/entry.md","filePath":"proxy-core/entry.md"}'),t={name:"proxy-core/entry.md"};function p(l,s,h,k,r,d){return a(),n("div",null,[...s[0]||(s[0]=[e(`<h1 id="proxy-core-启动链" tabindex="-1">proxy-core / 启动链 <a class="header-anchor" href="#proxy-core-启动链" aria-label="Permalink to "proxy-core / 启动链""></a></h1><h2 id="本文档覆盖的源文件" tabindex="-1">本文档覆盖的源文件 <a class="header-anchor" href="#本文档覆盖的源文件" aria-label="Permalink to "本文档覆盖的源文件""></a></h2><ul><li><code>apps/proxy-core/bin/proxy-cli.ts</code></li><li><code>apps/proxy-core/src/cli/index.ts</code></li><li><code>apps/proxy-core/src/server/index.ts</code></li><li><code>apps/proxy-core/src/utils/paths.ts</code></li><li><code>apps/proxy-core/src/utils/esm-dirname.ts</code></li><li><code>apps/proxy-core/ecosystem.config.cjs</code></li></ul><h2 id="三条入口" tabindex="-1">三条入口 <a class="header-anchor" href="#三条入口" aria-label="Permalink to "三条入口""></a></h2><p><code>proxy-core</code> 有三种被启动的方式,都最终走到 <code>startServer()</code>:</p><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 TB</span></span>
|
|
2
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> A[pnpm cli / proxy CLI] --> BIN[bin/proxy-cli.ts]</span></span>
|
|
3
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> BIN --> CLI[src/cli/index.ts]</span></span>
|
|
4
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CLI -- start --> PM2[PM2 start ecosystem.config.cjs]</span></span>
|
|
5
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> PM2 --> SERVER[src/server/index.ts]</span></span>
|
|
6
|
+
<span class="line"></span>
|
|
7
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> B[pnpm dev:proxy-core] --> TSX[tsx src/server/index.ts]</span></span>
|
|
8
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> TSX --> SERVER</span></span>
|
|
9
|
+
<span class="line"></span>
|
|
10
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> C[PM2 daemon 重启] --> SERVER</span></span>
|
|
11
|
+
<span class="line"></span>
|
|
12
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> SERVER -->|_isPm2 ‖ _isDirectExecution| START[startServer]</span></span>
|
|
13
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> START --> LOAD[loadConfig]</span></span>
|
|
14
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> START --> DB[configureDbPath]</span></span>
|
|
15
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> START --> LOG[createLogger]</span></span>
|
|
16
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> START --> FASTIFY[Fastify + hooks]</span></span>
|
|
17
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> FASTIFY --> UI[setupUiRoutes]</span></span>
|
|
18
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> FASTIFY --> PROXY[setupProxy<br/>init MCP + preloadMachineId]</span></span>
|
|
19
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> FASTIFY --> CHAT[setupChatRoute<br/>MCP-enhanced endpoint]</span></span>
|
|
20
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> FASTIFY --> LISTEN[listen host:port]</span></span></code></pre></div><h2 id="bin-proxy-cli-ts" tabindex="-1"><code>bin/proxy-cli.ts</code> <a class="header-anchor" href="#bin-proxy-cli-ts" aria-label="Permalink to "\`bin/proxy-cli.ts\`""></a></h2><p><code>apps/proxy-core/bin/proxy-cli.ts:1-3</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:#6A737D;--shiki-dark:#6A737D;">#!/usr/bin/env node</span></span>
|
|
21
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '../dist/cli/index.js'</span></span></code></pre></div><p>只有两行:加 shebang 让它可直接执行,然后 side-effect import 编译产物。<code>package.json</code> 的 <code>bin</code> 字段指向 <code>./dist/cli/index.js</code>,全局装包(<code>npm i -g @cc-monitoring/cli-core</code>)后终端有 <code>proxy</code> 命令。</p><h2 id="src-cli-index-ts-—-commander-注册" tabindex="-1"><code>src/cli/index.ts</code> — Commander 注册 <a class="header-anchor" href="#src-cli-index-ts-—-commander-注册" aria-label="Permalink to "\`src/cli/index.ts\` — Commander 注册""></a></h2><p><code>apps/proxy-core/src/cli/index.ts:1-80</code>。核心结构:</p><ul><li>顶层 <code>program</code>:<code>name('proxy')</code>、<code>version('1.0.0')</code>、全局参数 <code>-c, --config <path></code></li><li><code>preAction</code> hook(<code>cli/index.ts:20-25</code>):如果传了 <code>--config</code>,用 <code>path.resolve</code> 得到绝对路径调用 <code>setConfigPathOverride</code>,供后续 <code>loadConfig</code> 命中</li><li>8 条显式命令:<code>start / stop / status / logs / config / reload / test / ui</code>(详见 <a href="./cli.html">cli.md</a>)</li><li>1 条隐藏命令:<code>clean-requests</code>(<code>cli/index.ts:63-78</code>),带 <code>--days <days></code> 参数(默认 7),动态 import <code>cleanOldRequestsDB</code> 清 SQLite 老数据</li></ul><p>命令 action 从 <code>commands/<name>.ts</code> 导入,保持文件级模块化。</p><h2 id="src-server-index-ts-—-服务端引导" tabindex="-1"><code>src/server/index.ts</code> — 服务端引导 <a class="header-anchor" href="#src-server-index-ts-—-服务端引导" aria-label="Permalink to "\`src/server/index.ts\` — 服务端引导""></a></h2><p><code>apps/proxy-core/src/server/index.ts:11-42</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;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> async</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createServer</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;"><</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">FastifyInstance</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">> {</span></span>
|
|
22
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> config</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;"> loadConfig</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
|
23
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (config.storage?.path) </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">configureDbPath</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(config.storage.path)</span></span>
|
|
24
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> logger</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createLogger</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(config.logging)</span></span>
|
|
25
|
+
<span class="line"></span>
|
|
26
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> fastify</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Fastify</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ logger, trustProxy: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> })</span></span>
|
|
27
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> fastify.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">register</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(requestIdMiddleware)</span></span>
|
|
28
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> setupUiRoutes</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(fastify) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 必须先于 setupProxy,否则 /ui/* 会被 /v1/* 通配</span></span>
|
|
29
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> setupProxy</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(fastify, config.proxy)</span></span>
|
|
30
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> setupChatRoute</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(fastify, config.proxy) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// MCP-enhanced chat endpoint</span></span>
|
|
31
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> fastify</span></span>
|
|
32
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
|
|
33
|
+
<span class="line"></span>
|
|
34
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> async</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> startServer</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;"><</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">void</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">> {</span></span>
|
|
35
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> config</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;"> loadConfig</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
|
36
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> server</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;"> createServer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
|
37
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> server.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">listen</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ port: config.server.port, host: config.server.host })</span></span>
|
|
38
|
+
<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 "注册顺序为什么重要""></a></h3><p><code>setupProxy</code> 内部注册 <code>fastify.all('/v1/*', ...)</code>(<code>proxy.ts:178</code>)。Fastify 的路由匹配按注册顺序,先注册的先命中。<code>setupUiRoutes</code> 里既有 <code>/ui</code>、<code>/ui/api/*</code>,也有 <code>/ui/*</code>(静态资源,<code>ui-route.ts:398-404</code>)。若顺序颠倒,静态资源的 wildcard 可能会吞掉 <code>/v1/*</code> 之外的路径——因此 <code>server/index.ts:24</code> 有明确注释 <code>UI routes registered BEFORE proxy</code>。</p><h3 id="trustproxy-true" tabindex="-1"><code>trustProxy: true</code> <a class="header-anchor" href="#trustproxy-true" aria-label="Permalink to "\`trustProxy: true\`""></a></h3><p>信任反向代理头(如 <code>X-Forwarded-For</code>)。用户可能把 proxy-core 再套一层 nginx,这样 <code>request.ip</code> 才能反映真实客户端。</p><h3 id="requestidmiddleware-提前注册" tabindex="-1"><code>requestIdMiddleware</code> 提前注册 <a class="header-anchor" href="#requestidmiddleware-提前注册" aria-label="Permalink to "\`requestIdMiddleware\` 提前注册""></a></h3><p><code>middleware/request-id.ts</code> 通过 <code>onRequest</code> hook 给每个请求分配 <code>request.id</code>。放在最外层让所有日志与后续 handler 都用同一 ID(Fastify 默认自己会生成 UUID,本项目替换为 <code>nanoid(12)</code> 或客户端提供的 <code>x-request-id</code>)。</p><h2 id="esm-pm2-双重入口守卫" tabindex="-1">ESM + PM2 双重入口守卫 <a class="header-anchor" href="#esm-pm2-双重入口守卫" aria-label="Permalink to "ESM + PM2 双重入口守卫""></a></h2><p><code>apps/proxy-core/src/server/index.ts:42-60</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;"> _isPm2</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> process.env.pm_id </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!==</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> undefined</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ||</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> process.env.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">NODE_APP_INSTANCE</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> !==</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> undefined</span></span>
|
|
39
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> _currentModuleUrl</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getCurrentModuleUrl</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// wraps import.meta.url</span></span>
|
|
40
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> _mainModulePath</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> process.argv[</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</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;"> path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">resolve</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(process.argv[</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ''</span></span>
|
|
41
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> _mainModuleUrl</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> _mainModulePath </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> \`file://\${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">_mainModulePath</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}\`</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> :</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ''</span></span>
|
|
42
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> _isDirectExecution</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> _currentModuleUrl </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">===</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> _mainModuleUrl</span></span>
|
|
43
|
+
<span class="line"></span>
|
|
44
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (_isPm2 </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">||</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> _isDirectExecution) {</span></span>
|
|
45
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> startServer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">catch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">err</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =></span><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:#032F62;--shiki-dark:#9ECBFF;">'Server start failed:'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, err); process.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">exit</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) })</span></span>
|
|
46
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>两个场景都会自动启动:</p><ul><li><strong>PM2 fork 模式</strong>:PM2 会把 <code>process.argv[1]</code> 改成 <code>ProcessContainerFork.js</code> 包装脚本,导致 <code>import.meta.url === main module url</code> 判定失败;用 <code>pm_id</code> / <code>NODE_APP_INSTANCE</code> 环境变量补检测</li><li><strong>直接执行</strong>(<code>tsx src/server/index.ts</code> 或 <code>node dist/server/index.js</code>):URL 相等判定成立</li></ul><p>第三种情况(只 import 不执行,例如测试)两条判定都不成立,<code>startServer</code> 不会自动跑。</p><h2 id="数据目录锚点-paths-ts" tabindex="-1">数据目录锚点 <code>paths.ts</code> <a class="header-anchor" href="#数据目录锚点-paths-ts" aria-label="Permalink to "数据目录锚点 \`paths.ts\`""></a></h2><p><code>apps/proxy-core/src/utils/paths.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;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> dataDir</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">join</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(os.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">homedir</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(), </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'.cc-monitoring'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
47
|
+
<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:#005CC5;--shiki-dark:#79B8FF;"> logsDir</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">join</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(dataDir, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'logs'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><ul><li>全局 npm/pnpm 安装后 <code>process.cwd()</code> 无法预测,锚定到用户主目录才可靠</li><li>CLI 全局 <code>--config</code> → <code>setConfigPathOverride</code> → 存到模块级变量 <code>configPathOverride</code></li><li><code>getConfigPath()</code> 优先级:override > <code>process.env.CONFIG_PATH</code> > <code>path.join(dataDir, 'config.json')</code></li><li><code>ensureDataDirs()</code> 首次运行时 <code>mkdirSync(logsDir, { recursive: true })</code></li></ul><h2 id="ecosystem-config-cjs" tabindex="-1">ecosystem.config.cjs <a class="header-anchor" href="#ecosystem-config-cjs" aria-label="Permalink to "ecosystem.config.cjs""></a></h2><p><code>apps/proxy-core/ecosystem.config.cjs</code>(本项目唯一的 CommonJS 文件):</p><div class="language-js vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">js</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;"> dataDir</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> process.env.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">CC_DATA_DIR</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ||</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">join</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(os.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">homedir</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(), </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'.cc-monitoring'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
48
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> configPath</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> process.env.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">CONFIG_PATH</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ||</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">join</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(dataDir, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'config.json'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
49
|
+
<span class="line"></span>
|
|
50
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">module</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">exports</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
51
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> apps: [{</span></span>
|
|
52
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'cc-monitoring'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
53
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> script: path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">join</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(__dirname, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'dist/server/index.js'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
54
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> cwd: dataDir,</span></span>
|
|
55
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> instances: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
56
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> exec_mode: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'fork'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// 必须 fork:ESM 与 cluster 不兼容</span></span>
|
|
57
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> autorestart: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
58
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> watch: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
59
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> max_memory_restart: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'200M'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
60
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> env: { NODE_ENV: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'production'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, CONFIG_PATH: configPath },</span></span>
|
|
61
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> env_development: { NODE_ENV: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'development'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, CONFIG_PATH: configPath },</span></span>
|
|
62
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> log_date_format: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'YYYY-MM-DD HH:mm:ss Z'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
63
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> error_file: path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">join</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(logsDir, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'error.log'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
64
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> out_file: path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">join</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(logsDir, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'out.log'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
|
|
65
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> merge_logs: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span></span>
|
|
66
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }]</span></span>
|
|
67
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><ul><li><code>script</code> 用 <code>path.join(__dirname, ...)</code>:ecosystem 无论从哪个 cwd 调都能找到编译产物</li><li><code>cwd: dataDir</code>:让相对路径日志/DB 落到用户目录,不污染项目工程</li><li><code>exec_mode: fork</code>:cluster 模式基于 <code>worker_threads</code> 子进程复制 <code>main</code>,ESM 会在 worker 里报 <code>Cannot use import statement</code>;fork 直接 spawn Node,安全</li><li><code>.cjs</code> 扩展名:根 <code>package.json</code> <code>type: "module"</code> 让 <code>.js</code> 变 ESM;PM2 是 CJS,必须 <code>.cjs</code> 让 Node 按 CJS 加载</li></ul><p>更多细节 → <a href="./pm2.html">pm2.md</a>。</p><h2 id="冷启动时序" tabindex="-1">冷启动时序 <a class="header-anchor" href="#冷启动时序" aria-label="Permalink to "冷启动时序""></a></h2><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;">sequenceDiagram</span></span>
|
|
68
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> autonumber</span></span>
|
|
69
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> actor U as 用户</span></span>
|
|
70
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant CLI as bin/proxy-cli.ts</span></span>
|
|
71
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant CMD as commands/start.ts</span></span>
|
|
72
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant PM2 as pm2.startProcess</span></span>
|
|
73
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant D as PM2 daemon</span></span>
|
|
74
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant S as dist/server/index.js</span></span>
|
|
75
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant N as waitForPort</span></span>
|
|
76
|
+
<span class="line"></span>
|
|
77
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> U->>CLI: proxy start</span></span>
|
|
78
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CLI->>CMD: startCommand()</span></span>
|
|
79
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CMD->>CMD: loadConfig(读 ~/.cc-monitoring/config.json)</span></span>
|
|
80
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CMD->>PM2: startProcess(ecosystemPath)</span></span>
|
|
81
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> PM2->>D: pm2 connect + start</span></span>
|
|
82
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> D->>S: fork dist/server/index.js</span></span>
|
|
83
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> S->>S: createServer → setupUi → setupProxy → setupChatRoute</span></span>
|
|
84
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> S->>S: listen host:port</span></span>
|
|
85
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Note over S: init SQLite 4 版 schema</span></span>
|
|
86
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CMD->>N: waitForOnline (轮询 pm2 list)</span></span>
|
|
87
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> N-->>CMD: online</span></span>
|
|
88
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CMD->>N: waitForPort (递增退避 5 次)</span></span>
|
|
89
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> N-->>CMD: listening</span></span>
|
|
90
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CMD-->>U: 打印 base URL / dashboard / logs 路径</span></span></code></pre></div><p><code>start.ts</code> 用 <code>ora</code> spinner 打印 6 步进度(Loading config → Locating PM2 config → Starting → Waiting online → Verifying port → Summary),失败时 spinner 变红并给出日志路径提示。</p>`,41)])])}const c=i(t,[["render",p]]);export{E as __pageData,c as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as i,o as a,c as n,a2 as e}from"./chunks/framework.D_Xv2a7c.js";const E=JSON.parse('{"title":"proxy-core / 启动链","description":"","frontmatter":{},"headers":[],"relativePath":"proxy-core/entry.md","filePath":"proxy-core/entry.md"}'),t={name:"proxy-core/entry.md"};function p(l,s,h,k,r,d){return a(),n("div",null,[...s[0]||(s[0]=[e("",41)])])}const c=i(t,[["render",p]]);export{E as __pageData,c as default};
|