@cc-monitoring/proxy-core 0.4.0 → 0.4.1
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/cli/__tests__/commands.test.js +19 -0
- package/dist/cli/commands/repair.d.ts +1 -0
- package/dist/cli/commands/repair.js +15 -0
- package/dist/cli/index.js +30 -0
- package/dist/docs/404.html +1 -1
- package/dist/docs/assets/{app.DtYNT5zS.js → app.g7N9jkzn.js} +1 -1
- package/dist/docs/assets/chunks/{@localSearchIndexroot.C4sjikMO.js → @localSearchIndexroot.IHxQqfJH.js} +1 -1
- package/dist/docs/assets/chunks/{VPLocalSearchBox.DpXF9ZAI.js → VPLocalSearchBox.BHwI475_.js} +1 -1
- package/dist/docs/assets/chunks/{theme.TS_gUyc7.js → theme.FhAJSNDh.js} +2 -2
- package/dist/docs/index.html +2 -2
- package/dist/docs/overview.html +2 -2
- package/dist/docs/packages-utils.html +2 -2
- package/dist/docs/proxy-admin/env-and-build.html +2 -2
- package/dist/docs/proxy-admin/index.html +2 -2
- package/dist/docs/proxy-admin/layout-and-menu.html +2 -2
- package/dist/docs/proxy-admin/pages.html +2 -2
- package/dist/docs/proxy-admin/routing-and-auth.html +2 -2
- package/dist/docs/proxy-admin/services-and-mock.html +2 -2
- package/dist/docs/proxy-cli/api-layer.html +2 -2
- package/dist/docs/proxy-cli/app-shell.html +2 -2
- package/dist/docs/proxy-cli/components-common.html +2 -2
- package/dist/docs/proxy-cli/components-config.html +2 -2
- package/dist/docs/proxy-cli/components-requests.html +2 -2
- package/dist/docs/proxy-cli/components-stats.html +2 -2
- package/dist/docs/proxy-cli/components-status.html +2 -2
- package/dist/docs/proxy-cli/data-hooks.html +2 -2
- package/dist/docs/proxy-cli/index.html +2 -2
- package/dist/docs/proxy-cli/utils-and-i18n.html +2 -2
- package/dist/docs/proxy-core/chat-api.html +2 -2
- package/dist/docs/proxy-core/cli.html +2 -2
- package/dist/docs/proxy-core/config.html +2 -2
- package/dist/docs/proxy-core/data-layer.html +2 -2
- package/dist/docs/proxy-core/entry.html +2 -2
- package/dist/docs/proxy-core/index.html +2 -2
- package/dist/docs/proxy-core/pm2.html +2 -2
- package/dist/docs/proxy-core/providers.html +2 -2
- package/dist/docs/proxy-core/proxy.html +2 -2
- package/dist/docs/proxy-core/stats.html +2 -2
- package/dist/docs/proxy-core/tool.html +2 -2
- package/dist/docs/proxy-core/ui-routes.html +2 -2
- package/dist/docs/proxy-core/utilities.html +2 -2
- package/dist/docs/quickstart.html +2 -2
- package/dist/docs/request-flow.html +2 -2
- package/dist/server/__tests__/data-push.test.js +44 -0
- package/dist/server/__tests__/proxy.test.js +281 -2
- package/dist/server/__tests__/server.test.js +15 -10
- package/dist/server/__tests__/ui-route.test.js +43 -0
- package/dist/server/data-push.d.ts +2 -0
- package/dist/server/data-push.js +22 -0
- package/dist/server/index.js +4 -3
- package/dist/server/proxy.js +81 -21
- package/dist/server/ui-route.js +8 -1
- package/dist/ui/assets/{1c-CCx-FOtz.js → 1c-CaPSZBmB.js} +1 -1
- package/dist/ui/assets/{abnf-Bwbi42Z8.js → abnf-DBDOsmne.js} +1 -1
- package/dist/ui/assets/{abnfDiagram-VRR7QNED-Dm1-8q0E.js → abnfDiagram-VRR7QNED-D8zK__Mj.js} +1 -1
- package/dist/ui/assets/{accesslog-DCytz_-m.js → accesslog-BOLs2Kig.js} +1 -1
- package/dist/ui/assets/{actionscript-3udf15oh.js → actionscript-BZYKhS1B.js} +1 -1
- package/dist/ui/assets/{ada-M5Xa74xG.js → ada-DyacnMpg.js} +1 -1
- package/dist/ui/assets/{angelscript-qlrFxfW-.js → angelscript-CAN6j0H3.js} +1 -1
- package/dist/ui/assets/{apache-B-sF-DQH.js → apache-BE4vouiQ.js} +1 -1
- package/dist/ui/assets/{applescript-4FdcBnbI.js → applescript-CS88I1yz.js} +1 -1
- package/dist/ui/assets/{arc-BB3K1enp.js → arc-CTMmdrSV.js} +1 -1
- package/dist/ui/assets/{arcade-B_yqWaaG.js → arcade-B0f0f5SD.js} +1 -1
- package/dist/ui/assets/{architectureDiagram-ZJ3FMSHR-B39vkY8V.js → architectureDiagram-ZJ3FMSHR-Dtvpnopp.js} +1 -1
- package/dist/ui/assets/{arduino-yAcBoTWU.js → arduino-Bhm-OSb2.js} +1 -1
- package/dist/ui/assets/{armasm-wIcY84bI.js → armasm-CEy-mDHc.js} +1 -1
- package/dist/ui/assets/{asciidoc-Bxnu28-Z.js → asciidoc-CrZqQBTj.js} +1 -1
- package/dist/ui/assets/{aspectj-B2cKJA_O.js → aspectj-B4IlFyyJ.js} +1 -1
- package/dist/ui/assets/{autohotkey-B_rMWTtE.js → autohotkey-Cihy-FjA.js} +1 -1
- package/dist/ui/assets/{autoit-DwcuvMwv.js → autoit-Dis_JVJq.js} +1 -1
- package/dist/ui/assets/{avrasm-heGX1PXK.js → avrasm-CVhMycHj.js} +1 -1
- package/dist/ui/assets/{awk-BiqCQAEf.js → awk-BCViwLf5.js} +1 -1
- package/dist/ui/assets/{axapta-Cv8M-Ih6.js → axapta-pWB4JVB_.js} +1 -1
- package/dist/ui/assets/{bash-Divgn3JV.js → bash-B6Giryub.js} +1 -1
- package/dist/ui/assets/{basic-B9dnAP55.js → basic-DcrjcHB0.js} +1 -1
- package/dist/ui/assets/{blockDiagram-677ZJIJ3-DQ1mf7A_.js → blockDiagram-677ZJIJ3-DfhtgI1r.js} +1 -1
- package/dist/ui/assets/{bnf-kIL5mSsP.js → bnf-cpKU0967.js} +1 -1
- package/dist/ui/assets/{brainfuck-DqB7xDjH.js → brainfuck-CFFdk4cM.js} +1 -1
- package/dist/ui/assets/{coq-6aKUn3zn.js → c-CW6KPMeI.js} +1 -1
- package/dist/ui/assets/{c-like-De5MhE7G.js → c-like-CWn59vrg.js} +1 -1
- package/dist/ui/assets/{c4Diagram-LMCZKHZV-DQxtYsAx.js → c4Diagram-LMCZKHZV-D1Oh6k37.js} +1 -1
- package/dist/ui/assets/{cal-mYdfz9en.js → cal-8i26_L39.js} +1 -1
- package/dist/ui/assets/{capnproto-D04CRlOt.js → capnproto-CviwnFBf.js} +1 -1
- package/dist/ui/assets/{ceylon-pi9lFCja.js → ceylon-CQyc4rWs.js} +1 -1
- package/dist/ui/assets/channel-Da2MvpNG.js +1 -0
- package/dist/ui/assets/{chunk-2Q5K7J3B-BDD1nPt8.js → chunk-2Q5K7J3B-oswPBwIn.js} +1 -1
- package/dist/ui/assets/{chunk-32BRIVSS-DgeQFBb5.js → chunk-32BRIVSS-B5pU_9b9.js} +1 -1
- package/dist/ui/assets/{chunk-5VM5RSS4-C7Xf2SnI.js → chunk-5VM5RSS4-gvtfMc4w.js} +1 -1
- package/dist/ui/assets/{chunk-EX3LRPZG-B_3p1HEv.js → chunk-EX3LRPZG-BkBaDMy4.js} +1 -1
- package/dist/ui/assets/{chunk-JWPE2WC7-Dvs7u8eY.js → chunk-JWPE2WC7-Ch-C75ar.js} +1 -1
- package/dist/ui/assets/{chunk-MOJQB5TN-By21wDCN.js → chunk-MOJQB5TN-BfYhj1jN.js} +1 -1
- package/dist/ui/assets/{chunk-RYQCIY6F-6NC700r1.js → chunk-RYQCIY6F-D8izfruP.js} +1 -1
- package/dist/ui/assets/{chunk-V7JOEXUC-vEUqZ3rh.js → chunk-V7JOEXUC-CbzHnW90.js} +1 -1
- package/dist/ui/assets/{chunk-VR4S4FIN-6tX2dNN9.js → chunk-VR4S4FIN-Dr4M5qZA.js} +1 -1
- package/dist/ui/assets/{chunk-XXDRQBXY-qDb2jxAR.js → chunk-XXDRQBXY-QE-R8dRe.js} +1 -1
- package/dist/ui/assets/classDiagram-OUVF2IWQ-mHUiWjcC.js +1 -0
- package/dist/ui/assets/classDiagram-v2-EOCWNBFH-mHUiWjcC.js +1 -0
- package/dist/ui/assets/{clean-CLCsDUl1.js → clean-DZeAtQ7H.js} +1 -1
- package/dist/ui/assets/{clojure-dVi5Xifj.js → clojure-U4ebZ7NQ.js} +1 -1
- package/dist/ui/assets/{clojure-repl-BO_FpFmF.js → clojure-repl-B4QSIzUI.js} +1 -1
- package/dist/ui/assets/{cmake-CP5aJbyK.js → cmake-UHexZySb.js} +1 -1
- package/dist/ui/assets/{coffeescript-ZEfu_9pF.js → coffeescript-Dg56H9Mr.js} +1 -1
- package/dist/ui/assets/{c-HmsCM6sx.js → coq-C1g3mm0X.js} +1 -1
- package/dist/ui/assets/{cos-BohCnRN2.js → cos-BL4DdyGh.js} +1 -1
- package/dist/ui/assets/{cose-bilkent-JH36ORCC-DyXCbbro.js → cose-bilkent-JH36ORCC-BHQslHP3.js} +1 -1
- package/dist/ui/assets/{cpp-FOgPWPEt.js → cpp-keZI-XAd.js} +1 -1
- package/dist/ui/assets/{crmsh-B0OYb-Oe.js → crmsh-DdXYVeeA.js} +1 -1
- package/dist/ui/assets/{crystal-CuWb_dXm.js → crystal-C4AN0m0I.js} +1 -1
- package/dist/ui/assets/{csharp-BbcqM09j.js → csharp-COUyKsNR.js} +1 -1
- package/dist/ui/assets/{csp-rgHnTaDq.js → csp-DBc-rgSJ.js} +1 -1
- package/dist/ui/assets/{css-C-ibh7ZG.js → css-B8m6O_Pw.js} +1 -1
- package/dist/ui/assets/{cynefin-VYW2F7L2-CkuBhgC4.js → cynefin-VYW2F7L2-B3L-WcKn.js} +1 -1
- package/dist/ui/assets/{cynefinDiagram-TSTJHNR4-eycFyDao.js → cynefinDiagram-TSTJHNR4-fzaM4qcZ.js} +1 -1
- package/dist/ui/assets/{d-C0gXxJ0O.js → d-dgQN4Rko.js} +1 -1
- package/dist/ui/assets/{dagre-VKFMJZFB-DzqX9e49.js → dagre-VKFMJZFB-DJHj16mR.js} +1 -1
- package/dist/ui/assets/{dart-C-fTpuUV.js → dart-D2Y7LOq-.js} +1 -1
- package/dist/ui/assets/{delphi-Chm0B9xv.js → delphi-DaGcSk5A.js} +1 -1
- package/dist/ui/assets/{diagram-FQU43EPY-BEgCqfg1.js → diagram-FQU43EPY-iZEZ1f-R.js} +1 -1
- package/dist/ui/assets/{diagram-G47NLZAW-Cw11Vs2v.js → diagram-G47NLZAW-rkQb3r-C.js} +1 -1
- package/dist/ui/assets/{diagram-NH7WQ7WH-DSG_UWpP.js → diagram-NH7WQ7WH-B4Fy72tP.js} +1 -1
- package/dist/ui/assets/{diagram-OA4YK3LP-CJz-WOaJ.js → diagram-OA4YK3LP-BndmuIBq.js} +1 -1
- package/dist/ui/assets/{diagram-WEI45ONY-CBXjBCvc.js → diagram-WEI45ONY-CwlAiqOe.js} +1 -1
- package/dist/ui/assets/{diff-C-vyuMSL.js → diff-prcRV1Y3.js} +1 -1
- package/dist/ui/assets/{django-CJK7lReT.js → django-B1zIoGSx.js} +1 -1
- package/dist/ui/assets/{dns-D02SHjSy.js → dns-ZxI_aTwc.js} +1 -1
- package/dist/ui/assets/{dockerfile-trKL1Bqu.js → dockerfile-Dp_fT6E-.js} +1 -1
- package/dist/ui/assets/{dos-C52dy-sK.js → dos-Cuu5c8vv.js} +1 -1
- package/dist/ui/assets/{dsconfig-MzHgzVrt.js → dsconfig-DcGTOhbS.js} +1 -1
- package/dist/ui/assets/{dts-B137dHyX.js → dts-DCF8VaRk.js} +1 -1
- package/dist/ui/assets/{dust-BcbM0r5C.js → dust-DeCmZWMK.js} +1 -1
- package/dist/ui/assets/{ebnf-DkbpI7bK.js → ebnf-BHQQcuF_.js} +1 -1
- package/dist/ui/assets/{ebnfDiagram-CCIWWBDH-aI5uQ7w1.js → ebnfDiagram-CCIWWBDH-DJ_RuhTm.js} +1 -1
- package/dist/ui/assets/{elixir-BOtDuqQy.js → elixir-BHmweJ4d.js} +1 -1
- package/dist/ui/assets/{elm-DS8Tyyu-.js → elm-v76Hd2B3.js} +1 -1
- package/dist/ui/assets/{erDiagram-Q63AITRT-2vCbd4Mm.js → erDiagram-Q63AITRT-DVZkY5RZ.js} +1 -1
- package/dist/ui/assets/{erb-CSXECRbn.js → erb-xvWF5bfx.js} +1 -1
- package/dist/ui/assets/{erlang-BMxlgKPJ.js → erlang-CKBMURym.js} +1 -1
- package/dist/ui/assets/{erlang-repl-DPzlolPg.js → erlang-repl-BjcfXt3Z.js} +1 -1
- package/dist/ui/assets/{excel-CW2Uxed3.js → excel-Cdrtxhml.js} +1 -1
- package/dist/ui/assets/{fix-UW84SlCs.js → fix-CB-So5So.js} +1 -1
- package/dist/ui/assets/{flix-4UGiPULd.js → flix-VM9AOrq6.js} +1 -1
- package/dist/ui/assets/{flowDiagram-23GEKE2U-R5PbCbZI.js → flowDiagram-23GEKE2U-vyGW67Xm.js} +1 -1
- package/dist/ui/assets/{fortran-nhHsngdu.js → fortran-CcwJVO8H.js} +1 -1
- package/dist/ui/assets/{fsharp-CDyZ1ST5.js → fsharp-DiATpw1u.js} +1 -1
- package/dist/ui/assets/{gams-DHzkkUie.js → gams-Csg9YNPz.js} +1 -1
- package/dist/ui/assets/{ganttDiagram-NO4QXBWP-CGcq4Ie_.js → ganttDiagram-NO4QXBWP-C2TRbwLw.js} +1 -1
- package/dist/ui/assets/{gauss-DdhFGyBv.js → gauss-Bc4TC8Wh.js} +1 -1
- package/dist/ui/assets/{gcode-ImHh8OLA.js → gcode-Rig_2OoA.js} +1 -1
- package/dist/ui/assets/{gherkin-CTWAW-XR.js → gherkin-ByBU06QB.js} +1 -1
- package/dist/ui/assets/{gitGraphDiagram-IHSO6WYX-8nM2Z9lD.js → gitGraphDiagram-IHSO6WYX-CEiqfFIF.js} +1 -1
- package/dist/ui/assets/{glsl-0_W_27G2.js → glsl-C8D6y2Tn.js} +1 -1
- package/dist/ui/assets/{gml-BoDggu2z.js → gml-PHpGPHbT.js} +1 -1
- package/dist/ui/assets/{go-DYfFygwl.js → go-BL_o_3ez.js} +1 -1
- package/dist/ui/assets/{golo-Mlq-TCg9.js → golo-CWQ6dTUz.js} +1 -1
- package/dist/ui/assets/{gradle-BALAinEB.js → gradle-Y_I2KN2z.js} +1 -1
- package/dist/ui/assets/{groovy-Dht--dWU.js → groovy-JnIv8p2l.js} +1 -1
- package/dist/ui/assets/{haml-DpMrxg0d.js → haml-B8W_h6mZ.js} +1 -1
- package/dist/ui/assets/{handlebars-DqHzujNj.js → handlebars-DVm8mJuD.js} +1 -1
- package/dist/ui/assets/{haskell-DZSchhkY.js → haskell-DlDi2Ty7.js} +1 -1
- package/dist/ui/assets/{haxe-C0zBRjdy.js → haxe-CftFNVE-.js} +1 -1
- package/dist/ui/assets/{hsp-D_PwbSv2.js → hsp-C67xnq9C.js} +1 -1
- package/dist/ui/assets/{htmlbars-DxAFMG8u.js → htmlbars-CmJCm67U.js} +1 -1
- package/dist/ui/assets/{http-DvTRF0Do.js → http-b-FPEcHP.js} +1 -1
- package/dist/ui/assets/{hy-lVO-kNyp.js → hy-BWD3ncpN.js} +1 -1
- package/dist/ui/assets/{index-Ci23SMK2.js → index-C7s1zgJb.js} +21 -21
- package/dist/ui/assets/{index-BbMRVVGt.js → index-D2UBwfSG.js} +3 -3
- package/dist/ui/assets/{infoDiagram-FWYZ7A6U-C7WYDlvc.js → infoDiagram-FWYZ7A6U-C0Px17IN.js} +1 -1
- package/dist/ui/assets/{inform7-B8Tf2n8v.js → inform7-C-OYaMO5.js} +1 -1
- package/dist/ui/assets/{ini-DSoYMaLF.js → ini-CVyYmykw.js} +1 -1
- package/dist/ui/assets/{irpf90-RCPdkB14.js → irpf90-BcpjWXIz.js} +1 -1
- package/dist/ui/assets/{isbl-C2p75PPj.js → isbl-ZraBBeEr.js} +1 -1
- package/dist/ui/assets/{ishikawaDiagram-FXEZZL3T-Cm6jsPlc.js → ishikawaDiagram-FXEZZL3T-BjmTMgpO.js} +1 -1
- package/dist/ui/assets/{java-DeY4Yuia.js → java-D_mE2DT6.js} +1 -1
- package/dist/ui/assets/{javascript-3uX1CO-H.js → javascript-akXESsox.js} +1 -1
- package/dist/ui/assets/{jboss-cli-DgnD8mEc.js → jboss-cli-CFe3gTDt.js} +1 -1
- package/dist/ui/assets/{journeyDiagram-5HDEW3XC-DEGV1uA5.js → journeyDiagram-5HDEW3XC-BpgJUvs6.js} +1 -1
- package/dist/ui/assets/{json-BV2PmJJp.js → json-sjN7AzRC.js} +1 -1
- package/dist/ui/assets/{julia-B-m8kQm7.js → julia-BJJYbUMV.js} +1 -1
- package/dist/ui/assets/{julia-repl-C51atU2X.js → julia-repl-BwruD8Ix.js} +1 -1
- package/dist/ui/assets/{kanban-definition-HUTT4EX6-BJ4k5iTX.js → kanban-definition-HUTT4EX6-DFlE9edA.js} +1 -1
- package/dist/ui/assets/{kotlin-CYBziIgl.js → kotlin-CAIQsLCF.js} +1 -1
- package/dist/ui/assets/{lasso-Dw2SBMDW.js → lasso-sU67h-5u.js} +1 -1
- package/dist/ui/assets/{latex-Dpd35yke.js → latex-CVX-jP88.js} +1 -1
- package/dist/ui/assets/{ldif-Ce9EZU__.js → ldif-DGM9xbFZ.js} +1 -1
- package/dist/ui/assets/{leaf-CpkZzQtC.js → leaf-AlB_zmwz.js} +1 -1
- package/dist/ui/assets/{less-Uzo7M0FD.js → less-CKwfEdZQ.js} +1 -1
- package/dist/ui/assets/{lisp-DWXDlJYm.js → lisp-CXYLaAPw.js} +1 -1
- package/dist/ui/assets/{livecodeserver-uEyPEgVJ.js → livecodeserver-C02fGGTS.js} +1 -1
- package/dist/ui/assets/{livescript-BQ5f07oK.js → livescript-CBMa8QF_.js} +1 -1
- package/dist/ui/assets/{llvm-BAvP-skE.js → llvm-WXTIohTC.js} +1 -1
- package/dist/ui/assets/{lsl-DhbiIKu6.js → lsl-4obd2U_I.js} +1 -1
- package/dist/ui/assets/{lua-COxeUeLx.js → lua-DTSy-TjF.js} +1 -1
- package/dist/ui/assets/{makefile-DhDx-IgL.js → makefile-Bf2UEO0i.js} +1 -1
- package/dist/ui/assets/{markdown-DX5_kSxq.js → markdown-BgoGmFfJ.js} +1 -1
- package/dist/ui/assets/{mathematica-D351ZddB.js → mathematica-CSiA8KQh.js} +1 -1
- package/dist/ui/assets/{matlab-CELqIiwF.js → matlab-DoMvLsGB.js} +1 -1
- package/dist/ui/assets/{maxima-B_YljrMm.js → maxima-BFO4dfZO.js} +1 -1
- package/dist/ui/assets/{mel-DltsbNS8.js → mel-DyBpmDxt.js} +1 -1
- package/dist/ui/assets/{mercury-axX-5Vjj.js → mercury-OL5G5uU6.js} +1 -1
- package/dist/ui/assets/{mindmap-definition-LN4V7U3C-Bl1EJo6p.js → mindmap-definition-LN4V7U3C-s-nUZuCs.js} +1 -1
- package/dist/ui/assets/{mipsasm-BxmerVwX.js → mipsasm-KQwdm39j.js} +1 -1
- package/dist/ui/assets/{mizar-XNHfbpL2.js → mizar-BqndJ30I.js} +1 -1
- package/dist/ui/assets/{mojolicious-BR0U_7zk.js → mojolicious-Bvc1uJd-.js} +1 -1
- package/dist/ui/assets/{monkey-lLuu9_f-.js → monkey-Dl_gLm7-.js} +1 -1
- package/dist/ui/assets/{moonscript-DoaZ3DRQ.js → moonscript-BL6R6eAz.js} +1 -1
- package/dist/ui/assets/{n1ql-C6TId6Iu.js → n1ql-C09iOJfQ.js} +1 -1
- package/dist/ui/assets/{nginx-BezSG-JT.js → nginx-C7W01nBr.js} +1 -1
- package/dist/ui/assets/{nim-Bb0rfXie.js → nim-Dj78szvD.js} +1 -1
- package/dist/ui/assets/{nix-o3sJ5-54.js → nix-BOtGyPmd.js} +1 -1
- package/dist/ui/assets/{node-repl-Sv5hhcTf.js → node-repl-19nZvZ4A.js} +1 -1
- package/dist/ui/assets/{nsis-B45BJFhF.js → nsis-ByCl1zIm.js} +1 -1
- package/dist/ui/assets/{objectivec-CzS6zVgh.js → objectivec-BhdaT_Jr.js} +1 -1
- package/dist/ui/assets/{ocaml-Bqux7PyP.js → ocaml-D_NXvSO7.js} +1 -1
- package/dist/ui/assets/{openscad-4Wf6mF84.js → openscad-DOhagvnA.js} +1 -1
- package/dist/ui/assets/{oxygene-Fvwqgkkt.js → oxygene-5BnkqMRH.js} +1 -1
- package/dist/ui/assets/{parser3-zEfzT5wv.js → parser3-jSWlxi8m.js} +1 -1
- package/dist/ui/assets/{pegDiagram-2B236MQR-Dd4rIztM.js → pegDiagram-2B236MQR-CideH-XT.js} +1 -1
- package/dist/ui/assets/{perl-CsS1Gs6o.js → perl-CfsqjZ4b.js} +1 -1
- package/dist/ui/assets/{pf-BNH1jO0R.js → pf-kOewxO29.js} +1 -1
- package/dist/ui/assets/{pgsql-DqPigHrq.js → pgsql-CXm2Xd-Z.js} +1 -1
- package/dist/ui/assets/{php-CdOl9bRs.js → php-CRiA_dH8.js} +1 -1
- package/dist/ui/assets/{php-template-DPfirJg2.js → php-template-ByMrxqSd.js} +1 -1
- package/dist/ui/assets/{pieDiagram-ENE6RG2P-DGaJNf4S.js → pieDiagram-ENE6RG2P-CJkCdB38.js} +1 -1
- package/dist/ui/assets/{plaintext-EHbgBKzw.js → plaintext-BJx0R6A5.js} +1 -1
- package/dist/ui/assets/{pony-DmJajtp2.js → pony-CozCHtz4.js} +1 -1
- package/dist/ui/assets/{powershell-DfGzdWR6.js → powershell-BT7gMMgn.js} +1 -1
- package/dist/ui/assets/{processing-BT0ETgPG.js → processing-FOIxn_W_.js} +1 -1
- package/dist/ui/assets/{profile-B3I-x5Lt.js → profile-BsoUuD9w.js} +1 -1
- package/dist/ui/assets/{prolog-B_4QJIvI.js → prolog-Bd3gvQ2N.js} +1 -1
- package/dist/ui/assets/{properties-BFVI8weS.js → properties-BWGFdny9.js} +1 -1
- package/dist/ui/assets/{protobuf-PaF39oZZ.js → protobuf-pQSKoOOY.js} +1 -1
- package/dist/ui/assets/{puppet-BDC6Q8VF.js → puppet-DnEN_mgS.js} +1 -1
- package/dist/ui/assets/{purebasic-B2ejrOZK.js → purebasic-BqoOGoRw.js} +1 -1
- package/dist/ui/assets/{python-BOxtIk9H.js → python-TeVYomkE.js} +1 -1
- package/dist/ui/assets/{python-repl-BslBh_Mx.js → python-repl-zqu5igFS.js} +1 -1
- package/dist/ui/assets/{q-BPe8WLGW.js → q-CZC9Dltd.js} +1 -1
- package/dist/ui/assets/{qml-BazRR6fz.js → qml-ZNInP45Q.js} +1 -1
- package/dist/ui/assets/{quadrantDiagram-ABIIQ3AL-BQ7aPkHk.js → quadrantDiagram-ABIIQ3AL-Dd7PwxsF.js} +1 -1
- package/dist/ui/assets/{r-C09pGNJC.js → r-B39DAmkC.js} +1 -1
- package/dist/ui/assets/{railroadDiagram-RFXS5EU6-sCO9VGvE.js → railroadDiagram-RFXS5EU6-DtO5PVFZ.js} +1 -1
- package/dist/ui/assets/{reasonml-S7dzwVL9.js → reasonml-B-ZWFJt_.js} +1 -1
- package/dist/ui/assets/{requirementDiagram-TGXJPOKE-CfT5aVZg.js → requirementDiagram-TGXJPOKE-DihF4OTj.js} +1 -1
- package/dist/ui/assets/{rib-fM2EwQd4.js → rib-CnGG0qMF.js} +1 -1
- package/dist/ui/assets/{roboconf-D7AaeyrW.js → roboconf-Ewtfps4u.js} +1 -1
- package/dist/ui/assets/{routeros-c6Q7mKuq.js → routeros-CPcmP1c7.js} +1 -1
- package/dist/ui/assets/{rsl-sCpEQBxh.js → rsl-NbjWFbPH.js} +1 -1
- package/dist/ui/assets/{ruby-lcKhz2w9.js → ruby-DWDdy5yE.js} +1 -1
- package/dist/ui/assets/{ruleslanguage-BW4ATOuX.js → ruleslanguage-Cv_DZe2r.js} +1 -1
- package/dist/ui/assets/{rust-BbpU-0VY.js → rust-NZnsfER5.js} +1 -1
- package/dist/ui/assets/{sankeyDiagram-HTMAVEWB-CaweCpvN.js → sankeyDiagram-HTMAVEWB-D6i-Mzte.js} +1 -1
- package/dist/ui/assets/{sas-BPt5R0dx.js → sas-C4wv0P6G.js} +1 -1
- package/dist/ui/assets/{scala-DxW_vqXs.js → scala-DUdTOIgx.js} +1 -1
- package/dist/ui/assets/{scheme-T2Q_jWzT.js → scheme-DEdFa14t.js} +1 -1
- package/dist/ui/assets/{scilab-DMORg9lV.js → scilab-xY51J2bR.js} +1 -1
- package/dist/ui/assets/{scss-t0VsosqT.js → scss-BEYp1sXc.js} +1 -1
- package/dist/ui/assets/{sequenceDiagram-DBY2YBRQ-o-H_R4zb.js → sequenceDiagram-DBY2YBRQ-njQlqy_J.js} +1 -1
- package/dist/ui/assets/{shell-CnCDa1s9.js → shell-fq6bkhOw.js} +1 -1
- package/dist/ui/assets/{sizeCapture-X5ZJPWSS-BNLkHGDS.js → sizeCapture-X5ZJPWSS-tLn70-Fb.js} +1 -1
- package/dist/ui/assets/{smali-_n-BxJyG.js → smali-CsSAuSYg.js} +1 -1
- package/dist/ui/assets/{smalltalk-B90PXJwK.js → smalltalk-DJ7zrd87.js} +1 -1
- package/dist/ui/assets/{sml-fuY7bj-n.js → sml-CnDwl0nH.js} +1 -1
- package/dist/ui/assets/{sqf-COpwkyuo.js → sqf-Cc2SX4Zy.js} +1 -1
- package/dist/ui/assets/{sql-CXIT0j-x.js → sql-DUQA_V_4.js} +1 -1
- package/dist/ui/assets/{sql_more-C1Oxq4rx.js → sql_more-BHoH-8oO.js} +1 -1
- package/dist/ui/assets/{stan-BZEpaHeC.js → stan-D-7F5jH6.js} +1 -1
- package/dist/ui/assets/{stata-CkBwaiZM.js → stata-xKD_DnDE.js} +1 -1
- package/dist/ui/assets/{stateDiagram-2N3HPSRC-BkdnNF7I.js → stateDiagram-2N3HPSRC-B4O8weor.js} +1 -1
- package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-CO881_ht.js +1 -0
- package/dist/ui/assets/{step21-fs9N_U3O.js → step21-obc_kzQY.js} +1 -1
- package/dist/ui/assets/{stylus-Bs_9cvKZ.js → stylus-CkAUSRd-.js} +1 -1
- package/dist/ui/assets/{subunit-DvgcOCqJ.js → subunit-BDv8PGo1.js} +1 -1
- package/dist/ui/assets/{swift-BE4ONsur.js → swift-CHsYyW-p.js} +1 -1
- package/dist/ui/assets/{swimlanes-5IMT3BWC-uqTAc7o7.js → swimlanes-5IMT3BWC-DSr9Ty4A.js} +2 -2
- package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DFMCDs8b.js +8 -0
- package/dist/ui/assets/{taggerscript-BhmPJ64C.js → taggerscript-C_2JQgO9.js} +1 -1
- package/dist/ui/assets/{tap-DkueIVKV.js → tap-Bi497Z2c.js} +1 -1
- package/dist/ui/assets/{tcl-DyXOOkFi.js → tcl-B1XMvLaD.js} +1 -1
- package/dist/ui/assets/{thrift-Dhgbk56T.js → thrift-D9X0Hmmc.js} +1 -1
- package/dist/ui/assets/{timeline-definition-FHXFAJF6-DBAk9Ouc.js → timeline-definition-FHXFAJF6-C4_gj50B.js} +1 -1
- package/dist/ui/assets/{tp-BsXyrRGH.js → tp-CJG4Odbx.js} +1 -1
- package/dist/ui/assets/{twig-J0HqIuHw.js → twig-flj72_wc.js} +1 -1
- package/dist/ui/assets/{typescript-Dkwvul39.js → typescript-CWPwVoLd.js} +1 -1
- package/dist/ui/assets/{vala-CRGnf8aY.js → vala-LuCNWNuU.js} +1 -1
- package/dist/ui/assets/{vbnet-BtJAUe3z.js → vbnet-CGUT6ss0.js} +1 -1
- package/dist/ui/assets/{vbscript-RgFFNuM3.js → vbscript-CNiUBJhn.js} +1 -1
- package/dist/ui/assets/{vbscript-html-DO32Io9Y.js → vbscript-html-CJGgjjbc.js} +1 -1
- package/dist/ui/assets/{vennDiagram-L72KCM5P-BJi6y0hh.js → vennDiagram-L72KCM5P-BxcAUnYo.js} +1 -1
- package/dist/ui/assets/{verilog-C4h6MLcI.js → verilog-C4f9ZBTK.js} +1 -1
- package/dist/ui/assets/{vhdl-DOafePyU.js → vhdl-CyDQIZve.js} +1 -1
- package/dist/ui/assets/{vim-BAdTA9TY.js → vim-XAUBqa0M.js} +1 -1
- package/dist/ui/assets/{wardleyDiagram-EHGQE667-C7c_4IJ6.js → wardleyDiagram-EHGQE667-DlwSH77q.js} +1 -1
- package/dist/ui/assets/{x86asm-BCL6__QH.js → x86asm-Cp6vHuUx.js} +1 -1
- package/dist/ui/assets/{xl-qIzE4HOe.js → xl-BHgDofIM.js} +1 -1
- package/dist/ui/assets/{xml-DE2sJXYU.js → xml-QloVn4s_.js} +1 -1
- package/dist/ui/assets/{xquery-CQ35t92y.js → xquery-spJZLmyM.js} +1 -1
- package/dist/ui/assets/{xychartDiagram-FW5EYKEG-D2ILn0jL.js → xychartDiagram-FW5EYKEG-BxGVZcnb.js} +1 -1
- package/dist/ui/assets/{yaml-5KaAvG5C.js → yaml-CUju4iq0.js} +1 -1
- package/dist/ui/assets/{zephir-CbR3Ryfq.js → zephir-ChVpmD0Y.js} +1 -1
- package/dist/ui/index.html +1 -1
- package/dist/utils/__tests__/db-maintenance.test.d.ts +1 -0
- package/dist/utils/__tests__/db-maintenance.test.js +55 -0
- package/dist/utils/__tests__/db-migration.test.js +79 -1
- package/dist/utils/__tests__/request-writer.test.js +264 -3
- package/dist/utils/__tests__/stats-aggregator.test.d.ts +1 -0
- package/dist/utils/__tests__/stats-aggregator.test.js +114 -0
- package/dist/utils/db-maintenance.d.ts +8 -0
- package/dist/utils/db-maintenance.js +18 -0
- package/dist/utils/db.d.ts +1 -0
- package/dist/utils/db.js +62 -0
- package/dist/utils/request-writer.d.ts +23 -1
- package/dist/utils/request-writer.js +200 -14
- package/dist/utils/stats-aggregator.d.ts +1 -1
- package/dist/utils/stats-aggregator.js +44 -27
- package/ecosystem.config.cjs +2 -1
- package/package.json +1 -1
- package/dist/server/middleware/__tests__/request-id.test.js +0 -28
- package/dist/server/middleware/request-id.d.ts +0 -2
- package/dist/server/middleware/request-id.js +0 -12
- package/dist/ui/assets/channel-ChTtxQDg.js +0 -1
- package/dist/ui/assets/classDiagram-OUVF2IWQ-Ccbvamlu.js +0 -1
- package/dist/ui/assets/classDiagram-v2-EOCWNBFH-Ccbvamlu.js +0 -1
- package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-0JnZ1VSQ.js +0 -1
- package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DQRIIEmi.js +0 -8
- /package/dist/server/{middleware/__tests__/request-id.test.d.ts → __tests__/data-push.test.d.ts} +0 -0
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/proxy-cli_data-hooks.md.Bz8CVbxO.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/proxy-cli_index.md.BA6g8QD-.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/proxy-cli_utils-and-i18n.md.Ch_e-g_o.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/proxy-core_chat-api.md.DHihiBxR.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/proxy-core_cli.md.DCFYX4Bd.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/proxy-core_config.md.BXSOyxYE.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/proxy-core_data-layer.md.Cdomb3Gz.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/proxy-core_entry.md.BZmIcCUM.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/proxy-core_index.md.BM6VV5Qe.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/proxy-core_pm2.md.DUhWEtgn.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/proxy-core_providers.md.CbDZ6b_7.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/proxy-core_proxy.md.CzQYmX6X.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/proxy-core_stats.md.BsM6wuK_.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/proxy-core_tool.md.B6Le1nQr.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/proxy-core_ui-routes.md.B21t1p7R.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/proxy-core_utilities.md.C18pjnkz.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/quickstart.md.Cy_FmXIY.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
|
|
10
10
|
<link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
|
|
11
11
|
|
|
12
|
-
<script type="module" src="/docs/assets/app.
|
|
12
|
+
<script type="module" src="/docs/assets/app.g7N9jkzn.js"></script>
|
|
13
13
|
<link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
|
14
|
-
<link rel="modulepreload" href="/docs/assets/chunks/theme.
|
|
14
|
+
<link rel="modulepreload" href="/docs/assets/chunks/theme.FhAJSNDh.js">
|
|
15
15
|
<link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
|
|
16
16
|
<link rel="modulepreload" href="/docs/assets/request-flow.md.C1fyxdPE.lean.js">
|
|
17
17
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { WebSocket } from 'ws';
|
|
2
|
+
import { addDataClient, removeDataClient, pushNewRequest } from '../data-push';
|
|
3
|
+
// 统计 fake client 收到的各类广播
|
|
4
|
+
function messagesOf(send) {
|
|
5
|
+
return send.mock.calls.map((call) => JSON.parse(call[0]));
|
|
6
|
+
}
|
|
7
|
+
describe('data-push stats notify debounce', () => {
|
|
8
|
+
let send;
|
|
9
|
+
const fakeWs = {
|
|
10
|
+
readyState: WebSocket.OPEN,
|
|
11
|
+
send: jest.fn()
|
|
12
|
+
};
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
jest.useFakeTimers();
|
|
15
|
+
send = fakeWs.send;
|
|
16
|
+
send.mockClear();
|
|
17
|
+
addDataClient(fakeWs);
|
|
18
|
+
});
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
removeDataClient(fakeWs);
|
|
21
|
+
jest.clearAllTimers();
|
|
22
|
+
jest.useRealTimers();
|
|
23
|
+
});
|
|
24
|
+
it('trailing:重复 completed push 会重置延迟窗口,只在最后一次后 1.5s 广播一次', () => {
|
|
25
|
+
// t=0 第一次 completed push
|
|
26
|
+
pushNewRequest({ id: 1 }, 'completed');
|
|
27
|
+
jest.advanceTimersByTime(1000);
|
|
28
|
+
// t=1000 第二次 completed push,trailing 重置:窗口从第二次重新起算
|
|
29
|
+
pushNewRequest({ id: 2 }, 'completed');
|
|
30
|
+
// 距第二次 1499ms(总 2499ms)仍无 stats 广播;若没有重置,第一次的 timer 在 t=1500 就会触发
|
|
31
|
+
jest.advanceTimersByTime(1499);
|
|
32
|
+
expect(messagesOf(send).filter((m) => m.type === 'stats')).toHaveLength(0);
|
|
33
|
+
// 总 2500ms(距第二次 1500ms)恰好广播一次
|
|
34
|
+
jest.advanceTimersByTime(1);
|
|
35
|
+
const statsMessages = messagesOf(send).filter((m) => m.type === 'stats');
|
|
36
|
+
expect(statsMessages).toHaveLength(1);
|
|
37
|
+
expect(statsMessages[0]).toEqual({ type: 'stats', action: 'notify' });
|
|
38
|
+
});
|
|
39
|
+
it('pending push 不产生 stats 广播', () => {
|
|
40
|
+
pushNewRequest({ id: 1 }, 'pending');
|
|
41
|
+
jest.advanceTimersByTime(5000);
|
|
42
|
+
expect(messagesOf(send).filter((m) => m.type === 'stats')).toHaveLength(0);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { getErrorStatusCode, getErrorMessage, resolveProxyTarget, filterForwardHeaders } from '../proxy';
|
|
1
|
+
import { getErrorStatusCode, getErrorMessage, resolveProxyTarget, filterForwardHeaders, setupProxy } from '../proxy';
|
|
2
|
+
import Fastify from 'fastify';
|
|
3
|
+
import http from 'node:http';
|
|
2
4
|
import Database from 'better-sqlite3';
|
|
3
5
|
jest.mock('@utils/db', () => ({
|
|
4
6
|
__esModule: true,
|
|
@@ -6,7 +8,24 @@ jest.mock('@utils/db', () => ({
|
|
|
6
8
|
initDatabase: jest.fn(),
|
|
7
9
|
closeDatabase: jest.fn()
|
|
8
10
|
}));
|
|
9
|
-
|
|
11
|
+
jest.mock('@config/index', () => ({
|
|
12
|
+
loadConfig: jest.fn().mockResolvedValue({ storage: { maxDays: 7 } })
|
|
13
|
+
}));
|
|
14
|
+
jest.mock('../../utils/mcp-manager', () => ({
|
|
15
|
+
mcpManager: {
|
|
16
|
+
init: jest.fn().mockResolvedValue(undefined),
|
|
17
|
+
close: jest.fn().mockResolvedValue(undefined)
|
|
18
|
+
}
|
|
19
|
+
}));
|
|
20
|
+
jest.mock('../../utils/machine-id', () => ({
|
|
21
|
+
getMachineId: jest.fn().mockResolvedValue('test-machine-id'),
|
|
22
|
+
getMachineIdSync: jest.fn().mockReturnValue('test-machine-id'),
|
|
23
|
+
preloadMachineId: jest.fn().mockResolvedValue(undefined)
|
|
24
|
+
}));
|
|
25
|
+
jest.mock('../../utils/stats-aggregator', () => ({
|
|
26
|
+
aggregateStats: jest.fn()
|
|
27
|
+
}));
|
|
28
|
+
const { getDatabase, initDatabase } = jest.requireMock('@utils/db');
|
|
10
29
|
function makeError(code, message) {
|
|
11
30
|
const error = new Error(message);
|
|
12
31
|
error.code = code;
|
|
@@ -135,3 +154,263 @@ describe('filterForwardHeaders with authStyle', () => {
|
|
|
135
154
|
expect(out['x-api-key']).toBe('inbound-key');
|
|
136
155
|
});
|
|
137
156
|
});
|
|
157
|
+
// --- G2: 逻辑终止识别 + 收割接入(setupProxy 集成测试)---
|
|
158
|
+
// 构造集成测试用内存库:仅建 proxy.ts 运行路径触及的表
|
|
159
|
+
function createIntegrationDb() {
|
|
160
|
+
const db = new Database(':memory:');
|
|
161
|
+
db.exec(`
|
|
162
|
+
CREATE TABLE requests (
|
|
163
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
164
|
+
request_id TEXT UNIQUE NOT NULL,
|
|
165
|
+
session_id TEXT NOT NULL,
|
|
166
|
+
timestamp TEXT NOT NULL,
|
|
167
|
+
method TEXT NOT NULL,
|
|
168
|
+
path TEXT NOT NULL,
|
|
169
|
+
status_code INTEGER NOT NULL,
|
|
170
|
+
response_time INTEGER NOT NULL,
|
|
171
|
+
api_key TEXT,
|
|
172
|
+
proxy_api_key TEXT,
|
|
173
|
+
base_url TEXT,
|
|
174
|
+
model TEXT,
|
|
175
|
+
machine_id TEXT,
|
|
176
|
+
user_agent TEXT,
|
|
177
|
+
input_tokens INTEGER,
|
|
178
|
+
output_tokens INTEGER,
|
|
179
|
+
cache_read_tokens INTEGER,
|
|
180
|
+
cache_creation_tokens INTEGER,
|
|
181
|
+
request_headers TEXT,
|
|
182
|
+
request_body TEXT,
|
|
183
|
+
response_headers TEXT,
|
|
184
|
+
response_events TEXT,
|
|
185
|
+
completed_at TEXT,
|
|
186
|
+
closed_at TEXT,
|
|
187
|
+
error TEXT,
|
|
188
|
+
created_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
189
|
+
);
|
|
190
|
+
CREATE TABLE response_events (
|
|
191
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
192
|
+
request_id TEXT NOT NULL,
|
|
193
|
+
session_id TEXT NOT NULL,
|
|
194
|
+
event_index INTEGER NOT NULL,
|
|
195
|
+
event_type TEXT,
|
|
196
|
+
event_data TEXT NOT NULL
|
|
197
|
+
);
|
|
198
|
+
CREATE TABLE learn_tasks (
|
|
199
|
+
task_id TEXT PRIMARY KEY,
|
|
200
|
+
slug TEXT NOT NULL,
|
|
201
|
+
source_type TEXT NOT NULL,
|
|
202
|
+
label TEXT NOT NULL,
|
|
203
|
+
status TEXT NOT NULL,
|
|
204
|
+
error TEXT,
|
|
205
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
206
|
+
ended_at TEXT
|
|
207
|
+
);
|
|
208
|
+
CREATE TABLE providers (
|
|
209
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
210
|
+
name TEXT UNIQUE NOT NULL,
|
|
211
|
+
base_url TEXT,
|
|
212
|
+
api_key TEXT,
|
|
213
|
+
model TEXT,
|
|
214
|
+
haiku_model TEXT,
|
|
215
|
+
sonnet_model TEXT,
|
|
216
|
+
opus_model TEXT,
|
|
217
|
+
subagent_model TEXT,
|
|
218
|
+
provider TEXT NOT NULL,
|
|
219
|
+
is_default INTEGER NOT NULL DEFAULT 0,
|
|
220
|
+
is_openai_compatible INTEGER NOT NULL DEFAULT 0,
|
|
221
|
+
auth_style TEXT NOT NULL DEFAULT 'bearer',
|
|
222
|
+
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
223
|
+
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
224
|
+
);
|
|
225
|
+
`);
|
|
226
|
+
return db;
|
|
227
|
+
}
|
|
228
|
+
function sseFrame(event, data) {
|
|
229
|
+
const body = typeof data === 'string' ? data : JSON.stringify(data);
|
|
230
|
+
return event !== null ? `event: ${event}\ndata: ${body}\n\n` : `data: ${body}\n\n`;
|
|
231
|
+
}
|
|
232
|
+
const completeClaudeFrames = [
|
|
233
|
+
sseFrame('message_start', { type: 'message_start', usage: { input_tokens: 10, cache_read_input_tokens: 2 } }),
|
|
234
|
+
sseFrame('ping', { type: 'ping' }),
|
|
235
|
+
sseFrame('message_delta', { type: 'message_delta', usage: { output_tokens: 4 } }),
|
|
236
|
+
sseFrame('message_stop', { type: 'message_stop' })
|
|
237
|
+
];
|
|
238
|
+
const incompleteClaudeFrames = [
|
|
239
|
+
sseFrame('message_start', { type: 'message_start', usage: { input_tokens: 3 } }),
|
|
240
|
+
sseFrame('content_block_start', { type: 'content_block_start', index: 0, content_block: { type: 'text', text: '' } }),
|
|
241
|
+
sseFrame('content_block_delta', { type: 'content_block_delta', index: 0, delta: { type: 'text_delta', text: 'hel' } })
|
|
242
|
+
];
|
|
243
|
+
// 上游 Web 流:逐帧异步入队;endAfter=false 时入队后保持悬挂(不 close)。
|
|
244
|
+
// singleChunk=true 时所有帧合并为一次 enqueue(模拟真实 TCP 合包,如
|
|
245
|
+
// finish_reason chunk 与紧随的 [DONE] 通常在同一缓冲到达)。
|
|
246
|
+
function createUpstreamWebStream(frames, endAfter = false, singleChunk = false) {
|
|
247
|
+
let controller;
|
|
248
|
+
const webStream = new ReadableStream({
|
|
249
|
+
start(c) { controller = c; }
|
|
250
|
+
});
|
|
251
|
+
void (async () => {
|
|
252
|
+
try {
|
|
253
|
+
if (singleChunk) {
|
|
254
|
+
controller.enqueue(Buffer.from(frames.join(''), 'utf-8'));
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
for (const frame of frames) {
|
|
258
|
+
controller.enqueue(Buffer.from(frame, 'utf-8'));
|
|
259
|
+
await new Promise(r => setTimeout(r, 3));
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (endAfter)
|
|
263
|
+
controller.close();
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
// nodeStream.destroy 取消 web 流后 controller 已关闭,忽略后续入队
|
|
267
|
+
}
|
|
268
|
+
})();
|
|
269
|
+
return webStream;
|
|
270
|
+
}
|
|
271
|
+
async function waitFor(predicate, { timeout = 3000, interval = 20 } = {}) {
|
|
272
|
+
const start = Date.now();
|
|
273
|
+
while (Date.now() - start < timeout) {
|
|
274
|
+
const value = predicate();
|
|
275
|
+
if (value !== undefined)
|
|
276
|
+
return value;
|
|
277
|
+
await new Promise(r => setTimeout(r, interval));
|
|
278
|
+
}
|
|
279
|
+
throw new Error('waitFor timed out');
|
|
280
|
+
}
|
|
281
|
+
function mockUpstreamFetch(webStream, requestId) {
|
|
282
|
+
return jest.spyOn(globalThis, 'fetch').mockImplementation(async () => new Response(webStream, {
|
|
283
|
+
status: 200,
|
|
284
|
+
headers: { 'content-type': 'text/event-stream', 'x-request-id': requestId }
|
|
285
|
+
}));
|
|
286
|
+
}
|
|
287
|
+
const proxyConfig = {
|
|
288
|
+
target: 'https://upstream.example.com/apps/anthropic',
|
|
289
|
+
changeOrigin: true
|
|
290
|
+
};
|
|
291
|
+
const requestPayload = JSON.stringify({
|
|
292
|
+
model: 'claude-sonnet-4-20250514',
|
|
293
|
+
max_tokens: 16,
|
|
294
|
+
messages: [{ role: 'user', content: 'hi' }]
|
|
295
|
+
});
|
|
296
|
+
describe('setupProxy SSE lifecycle (G2)', () => {
|
|
297
|
+
let db;
|
|
298
|
+
let fastify;
|
|
299
|
+
beforeEach(() => {
|
|
300
|
+
jest.clearAllMocks();
|
|
301
|
+
db = createIntegrationDb();
|
|
302
|
+
getDatabase.mockReturnValue(db);
|
|
303
|
+
initDatabase.mockReturnValue(db);
|
|
304
|
+
fastify = Fastify();
|
|
305
|
+
});
|
|
306
|
+
afterEach(async () => {
|
|
307
|
+
delete process.env.CCM_STREAM_IDLE_TIMEOUT_MS;
|
|
308
|
+
await fastify.close();
|
|
309
|
+
db.close();
|
|
310
|
+
});
|
|
311
|
+
test('message_stop 已发出后上游悬挂:行落 completed_at,不标中断,客户端不悬挂', async () => {
|
|
312
|
+
await setupProxy(fastify, proxyConfig);
|
|
313
|
+
mockUpstreamFetch(createUpstreamWebStream(completeClaudeFrames), 'cloud-req-1');
|
|
314
|
+
const response = await fastify.inject({
|
|
315
|
+
method: 'POST',
|
|
316
|
+
url: '/v1/messages',
|
|
317
|
+
headers: { 'content-type': 'application/json' },
|
|
318
|
+
payload: requestPayload
|
|
319
|
+
});
|
|
320
|
+
expect(response.statusCode).toBe(200);
|
|
321
|
+
expect(response.payload).toContain('message_stop');
|
|
322
|
+
const row = db.prepare('SELECT * FROM requests WHERE request_id = ?').get('cloud-req-1');
|
|
323
|
+
expect(row).toBeDefined();
|
|
324
|
+
expect(row.completed_at).not.toBeNull();
|
|
325
|
+
expect(row.closed_at).toBeNull();
|
|
326
|
+
expect(row.error).toBeNull();
|
|
327
|
+
});
|
|
328
|
+
test('无 message_stop 的 idle 超时仍标中断(closed_at + error)', async () => {
|
|
329
|
+
// 测试专用时长覆盖:真实定时器,只缩短看门狗超时
|
|
330
|
+
process.env.CCM_STREAM_IDLE_TIMEOUT_MS = '80';
|
|
331
|
+
await setupProxy(fastify, proxyConfig);
|
|
332
|
+
mockUpstreamFetch(createUpstreamWebStream(incompleteClaudeFrames), 'cloud-req-2');
|
|
333
|
+
// 走真实 TCP:中断分支 pipe 不结束客户端(保持既有语义),客户端自行判超时
|
|
334
|
+
await fastify.listen({ port: 0, host: '127.0.0.1' });
|
|
335
|
+
const port = fastify.server.address().port;
|
|
336
|
+
const clientReq = http.request({
|
|
337
|
+
port,
|
|
338
|
+
host: '127.0.0.1',
|
|
339
|
+
method: 'POST',
|
|
340
|
+
path: '/v1/messages',
|
|
341
|
+
headers: { 'content-type': 'application/json', 'content-length': Buffer.byteLength(requestPayload) }
|
|
342
|
+
});
|
|
343
|
+
clientReq.on('error', () => { });
|
|
344
|
+
clientReq.end(requestPayload);
|
|
345
|
+
// 客户端收到数据后看门狗触发,不再有数据;保底 1s 后自毁连接
|
|
346
|
+
const clientTimer = setTimeout(() => clientReq.destroy(), 1000);
|
|
347
|
+
clientReq.on('close', () => clearTimeout(clientTimer));
|
|
348
|
+
const row = await waitFor(() => {
|
|
349
|
+
const r = db.prepare('SELECT * FROM requests LIMIT 1').get();
|
|
350
|
+
return r && r.closed_at ? r : undefined;
|
|
351
|
+
});
|
|
352
|
+
expect(row.completed_at).toBeNull();
|
|
353
|
+
expect(row.closed_at).not.toBeNull();
|
|
354
|
+
expect(row.error).toContain('idle timeout');
|
|
355
|
+
expect(row.status_code).toBe(200);
|
|
356
|
+
});
|
|
357
|
+
test('OpenAI 流 finish_reason + [DONE] 后上游悬挂:行落 completed_at', async () => {
|
|
358
|
+
db.prepare(`
|
|
359
|
+
INSERT INTO providers (name, base_url, api_key, model, provider, is_default, is_openai_compatible, auth_style)
|
|
360
|
+
VALUES ('openai-test', 'https://openai.example.com/v1', 'k', 'gpt-4o', 'openai', 1, 1, 'bearer')
|
|
361
|
+
`).run();
|
|
362
|
+
await setupProxy(fastify, proxyConfig);
|
|
363
|
+
const openaiFrames = [
|
|
364
|
+
sseFrame(null, { id: 'chat-1', choices: [{ delta: { role: 'assistant' }, finish_reason: null }] }),
|
|
365
|
+
sseFrame(null, { id: 'chat-1', choices: [{ delta: { content: 'hi' }, finish_reason: null }] }),
|
|
366
|
+
sseFrame(null, { id: 'chat-1', choices: [{ delta: {}, finish_reason: 'stop' }], usage: { prompt_tokens: 5, completion_tokens: 7 } }),
|
|
367
|
+
sseFrame(null, '[DONE]')
|
|
368
|
+
];
|
|
369
|
+
const fetchSpy = mockUpstreamFetch(createUpstreamWebStream(openaiFrames, false, true), 'cloud-openai-1');
|
|
370
|
+
const response = await fastify.inject({
|
|
371
|
+
method: 'POST',
|
|
372
|
+
url: '/v1/messages',
|
|
373
|
+
headers: { 'content-type': 'application/json' },
|
|
374
|
+
payload: requestPayload
|
|
375
|
+
});
|
|
376
|
+
expect(response.statusCode).toBe(200);
|
|
377
|
+
expect(response.payload).toContain('message_stop');
|
|
378
|
+
expect(fetchSpy.mock.calls[0][0]).toBe('https://openai.example.com/v1/chat/completions');
|
|
379
|
+
const row = db.prepare('SELECT * FROM requests WHERE request_id = ?').get('cloud-openai-1');
|
|
380
|
+
expect(row).toBeDefined();
|
|
381
|
+
expect(row.completed_at).not.toBeNull();
|
|
382
|
+
expect(row.closed_at).toBeNull();
|
|
383
|
+
expect(row.error).toBeNull();
|
|
384
|
+
});
|
|
385
|
+
test('message_stop 到达后客户端断开:内容已完整交付,仍走 complete', async () => {
|
|
386
|
+
await setupProxy(fastify, proxyConfig);
|
|
387
|
+
mockUpstreamFetch(createUpstreamWebStream(completeClaudeFrames), 'cloud-req-3');
|
|
388
|
+
await fastify.listen({ port: 0, host: '127.0.0.1' });
|
|
389
|
+
const port = fastify.server.address().port;
|
|
390
|
+
await new Promise((resolve, reject) => {
|
|
391
|
+
const clientReq = http.request({
|
|
392
|
+
port,
|
|
393
|
+
host: '127.0.0.1',
|
|
394
|
+
method: 'POST',
|
|
395
|
+
path: '/v1/messages',
|
|
396
|
+
headers: { 'content-type': 'application/json', 'content-length': Buffer.byteLength(requestPayload) }
|
|
397
|
+
});
|
|
398
|
+
clientReq.on('error', () => { });
|
|
399
|
+
clientReq.on('response', (res) => {
|
|
400
|
+
res.on('data', (chunk) => {
|
|
401
|
+
if (chunk.toString().includes('message_stop'))
|
|
402
|
+
clientReq.destroy();
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
clientReq.on('close', () => resolve());
|
|
406
|
+
setTimeout(() => reject(new Error('client did not close')), 3000).unref();
|
|
407
|
+
clientReq.end(requestPayload);
|
|
408
|
+
});
|
|
409
|
+
const row = await waitFor(() => {
|
|
410
|
+
const r = db.prepare('SELECT * FROM requests WHERE request_id = ?').get('cloud-req-3');
|
|
411
|
+
return r && r.completed_at ? r : undefined;
|
|
412
|
+
});
|
|
413
|
+
expect(row.closed_at).toBeNull();
|
|
414
|
+
expect(row.error).toBeNull();
|
|
415
|
+
});
|
|
416
|
+
});
|