hermes-web-ui 0.4.3 → 0.4.4
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/README.md +2 -1
- package/dist/client/assets/Add-C5vmHXvi.js +1 -0
- package/dist/client/assets/{Button-vKfgky-Y.js → Button-BkFCVws1.js} +3 -3
- package/dist/client/assets/{ChannelsView-CHWtzAkF.js → ChannelsView-kmohhCQz.js} +1 -1
- package/dist/client/assets/ChatView-BqERLIKm.js +3 -0
- package/dist/client/assets/{ChatView-b0_L3ucp.css → ChatView-CjCcr65D.css} +1 -1
- package/dist/client/assets/{Close-Brba3ay5.js → Close-BQv4cWxW.js} +2 -2
- package/dist/client/assets/Dropdown-CalW5lgg.js +125 -0
- package/dist/client/assets/Empty-Crwpm9aR.js +24 -0
- package/dist/client/assets/FilesView-BIhdGj93.css +1 -0
- package/dist/client/assets/FilesView-DDqOER0C.js +279 -0
- package/dist/client/assets/{FormItem-kXuCeSKq.js → FormItem-rZXpOEwq.js} +3 -3
- package/dist/client/assets/GatewaysView-CBisX7sg.js +1 -0
- package/dist/client/assets/Input-CACQWEc-.js +234 -0
- package/dist/client/assets/{InputNumber-BXy4reTI.js → InputNumber-BtDJhuZ_.js} +2 -2
- package/dist/client/assets/JobsView-D2rkutWf.js +2 -0
- package/dist/client/assets/LoginView-fbo3JyWY.js +1 -0
- package/dist/client/assets/LogsView-D6S5uWNR.js +1 -0
- package/dist/client/assets/{MarkdownRenderer-B7t0ZEw0.js → MarkdownRenderer-4flsL0HK.js} +17 -17
- package/dist/client/assets/MemoryView-Ct-Xub44.js +7 -0
- package/dist/client/assets/{Modal-6Bv1v4kO.js → Modal-pv2obz6L.js} +4 -4
- package/dist/client/assets/{ModelsView-BStkMmEH.css → ModelsView-DoxebjaU.css} +1 -1
- package/dist/client/assets/ModelsView-NQaSxgAw.js +1 -0
- package/dist/client/assets/Popconfirm-BtGpKlX7.js +16 -0
- package/dist/client/assets/Popover-CrGHm4Ci.js +117 -0
- package/dist/client/assets/ProfilesView-BkxAC36G.js +1 -0
- package/dist/client/assets/Select-D9RT-keZ.js +317 -0
- package/dist/client/assets/SettingRow-Uz-cvlWh.js +1 -0
- package/dist/client/assets/SettingsView-ZqYSPWDq.js +352 -0
- package/dist/client/assets/SkillsView-CynAdT4a.js +1 -0
- package/dist/client/assets/{Spin-DKwUVt1F.js → Spin-Cl861IYY.js} +3 -3
- package/dist/client/assets/Suffix-lZvgRyRJ.js +90 -0
- package/dist/client/assets/{Switch-DG-3EwdR.js → Switch-Cgr6t0l5.js} +2 -2
- package/dist/client/assets/{Tag-BWD1u63m.js → Tag-DTjJYhIj.js} +2 -2
- package/dist/client/assets/{TerminalView-DTR8bNOy.js → TerminalView-B-24Rkd7.js} +6 -6
- package/dist/client/assets/Tooltip-BSRTJcks.js +1 -0
- package/dist/client/assets/Upload-GVPlkKwO.js +440 -0
- package/dist/client/assets/UsageView-MG6jNAat.js +1 -0
- package/dist/client/assets/{Warning-CCZES7el.js → Warning-C_N-vtES.js} +1 -1
- package/dist/client/assets/{_plugin-vue_export-helper-Bl_Pm_OI.js → _plugin-vue_export-helper-BQLp1Z61.js} +2 -2
- package/dist/client/assets/abap-Cj2ZJqTY.js +1 -0
- package/dist/client/assets/apex-DMOzUZZB.js +1 -0
- package/dist/client/assets/app-CawwM3Gr.js +1 -0
- package/dist/client/assets/app-DMdMpEzR.js +1 -0
- package/dist/client/assets/{auth-BPBv1nNQ.js → auth-Bkk8rJhI.js} +1 -1
- package/dist/client/assets/azcli-BJqyCQCD.js +1 -0
- package/dist/client/assets/bat-D9jfAgXL.js +1 -0
- package/dist/client/assets/bicep-IyCF8AHg.js +2 -0
- package/dist/client/assets/browser-C0KKMpa8.js +47 -0
- package/dist/client/assets/cameligo-DqphQ1Vf.js +1 -0
- package/dist/client/assets/chat-BdoAzXti.js +6 -0
- package/dist/client/assets/chunk-DECur_0Z.js +1 -0
- package/dist/client/assets/clipboard-D5ziXDzU.js +1 -0
- package/dist/client/assets/clojure-CqmBZ3SB.js +1 -0
- package/dist/client/assets/codicon-ngg6Pgfi.ttf +0 -0
- package/dist/client/assets/coffee-CD7nYioG.js +1 -0
- package/dist/client/assets/composables-gdfCfHJJ.js +1 -0
- package/dist/client/assets/cpp-CJjcH3OV.js +1 -0
- package/dist/client/assets/{create-5zWq3BEB.js → create-DgSD0xTd.js} +1 -1
- package/dist/client/assets/csharp-Bh3KEkzK.js +1 -0
- package/dist/client/assets/csp-Bwqlbr_S.js +1 -0
- package/dist/client/assets/css-CoIOcuFa.js +3 -0
- package/dist/client/assets/css.worker-DyDu5ynT.js +89 -0
- package/dist/client/assets/cssMode-DEq9g7fF.js +1 -0
- package/dist/client/assets/cypher-BI5xYxDU.js +1 -0
- package/dist/client/assets/dart-C48Nsypx.js +1 -0
- package/dist/client/assets/dockerfile-ueCsFBIO.js +1 -0
- package/dist/client/assets/ecl-bYObu0Am.js +1 -0
- package/dist/client/assets/editor-Br_kD0ds.css +1 -0
- package/dist/client/assets/editor.api2-Be2SWebq.js +872 -0
- package/dist/client/assets/editor.worker-Dpt_xPrs.js +26 -0
- package/dist/client/assets/elixir-C3hRLmcx.js +1 -0
- package/dist/client/assets/fade-in.cssr-D3Wt-ego.js +12 -0
- package/dist/client/assets/flow9-DFj18iNE.js +1 -0
- package/dist/client/assets/freemarker2-DL4Fzu5B.js +3 -0
- package/dist/client/assets/fsharp-AnzNBUww.js +1 -0
- package/dist/client/assets/go-tJ6Rmw6i.js +1 -0
- package/dist/client/assets/graphql-C0hIG8nm.js +1 -0
- package/dist/client/assets/handlebars-BHnMuvUj.js +1 -0
- package/dist/client/assets/hcl-BuyUNygY.js +1 -0
- package/dist/client/assets/html-GXFtBUzj.js +1 -0
- package/dist/client/assets/html.worker-IWNXhnIC.js +502 -0
- package/dist/client/assets/htmlMode-BcCXcf_0.js +1 -0
- package/dist/client/assets/index-8ao2g7sV.js +284 -0
- package/dist/client/assets/{index-BRXOdlZt.css → index-C9EadcMt.css} +1 -1
- package/dist/client/assets/ini-BeJtyijW.js +1 -0
- package/dist/client/assets/java-C2VAgfs1.js +1 -0
- package/dist/client/assets/javascript-U_9WP-aM.js +1 -0
- package/dist/client/assets/jobs-B5TmkmHx.js +1 -0
- package/dist/client/assets/jobs-ByeskmbT.js +1 -0
- package/dist/client/assets/json.worker-c4h5s80L.js +58 -0
- package/dist/client/assets/jsonMode-tONQS06s.js +7 -0
- package/dist/client/assets/julia-L5N2QjZH.js +1 -0
- package/dist/client/assets/kotlin-CoM2kw6K.js +1 -0
- package/dist/client/assets/less-zbg2EZtP.js +2 -0
- package/dist/client/assets/lexon-DYXVK96z.js +1 -0
- package/dist/client/assets/{light-DLz3o2il.js → light-0XEUqxc9.js} +1 -1
- package/dist/client/assets/{light-BNuYwJcs.js → light-5OhOi42N.js} +1 -1
- package/dist/client/assets/light-B2F950-4.js +1 -0
- package/dist/client/assets/{light-DcGe0-g1.js → light-CqEvxEaQ.js} +1 -1
- package/dist/client/assets/{light-DbUQYfY2.js → light-KCWDej_e.js} +1 -1
- package/dist/client/assets/{light-cIgLWDVk.js → light-Q_cJ87-J.js} +1 -1
- package/dist/client/assets/light-m-6OEHOE.js +1 -0
- package/dist/client/assets/liquid-B0bBAmrr.js +1 -0
- package/dist/client/assets/lspLanguageFeatures-CTVvD5p-.js +4 -0
- package/dist/client/assets/lua-BLOIBWLB.js +1 -0
- package/dist/client/assets/m3-cDvqo2bv.js +1 -0
- package/dist/client/assets/markdown-Dl_DNBM2.js +1 -0
- package/dist/client/assets/mdx-RopAvSlP.js +1 -0
- package/dist/client/assets/mips-BzzKjtTI.js +1 -0
- package/dist/client/assets/{models-EKNn3-zC.js → models-B81NGa-M.js} +1 -1
- package/dist/client/assets/monaco.contribution-BEuTYscZ.js +2 -0
- package/dist/client/assets/msdax-sEefJb9Q.js +1 -0
- package/dist/client/assets/mysql-DRV1IKn4.js +1 -0
- package/dist/client/assets/objective-c-DYtfYpNc.js +1 -0
- package/dist/client/assets/pascal-CpR5h_uZ.js +1 -0
- package/dist/client/assets/pascaligo-BI_Gz9Bp.js +1 -0
- package/dist/client/assets/perl-K9wCPr4J.js +1 -0
- package/dist/client/assets/pgsql-NrZG2xAf.js +1 -0
- package/dist/client/assets/php-DT0D5Htf.js +1 -0
- package/dist/client/assets/{pinia-C8BDM-Fc.js → pinia-Bf3FnMGw.js} +1 -1
- package/dist/client/assets/pla-COSVs9tJ.js +1 -0
- package/dist/client/assets/postiats-CpQICSCZ.js +1 -0
- package/dist/client/assets/powerquery-hpQUPY_r.js +1 -0
- package/dist/client/assets/powershell-CXKJShJs.js +1 -0
- package/dist/client/assets/preload-helper-rov5CBGT.js +1 -0
- package/dist/client/assets/profiles-CySy48VW.js +1 -0
- package/dist/client/assets/protobuf-VEer4AfK.js +2 -0
- package/dist/client/assets/pug-CCviz4wy.js +1 -0
- package/dist/client/assets/python-DPgAafol.js +1 -0
- package/dist/client/assets/qsharp-DTveMB6M.js +1 -0
- package/dist/client/assets/r-CnY31RFU.js +1 -0
- package/dist/client/assets/razor-BRbs1kR5.js +1 -0
- package/dist/client/assets/redis-1g6etttg.js +1 -0
- package/dist/client/assets/redshift-BQFehQo7.js +1 -0
- package/dist/client/assets/restructuredtext-CR8m-OPX.js +1 -0
- package/dist/client/assets/router-DSISOBmz.js +4 -0
- package/dist/client/assets/ruby-BljIZnPI.js +1 -0
- package/dist/client/assets/rust-C7icjueR.js +1 -0
- package/dist/client/assets/sb-Cl_sCxp1.js +1 -0
- package/dist/client/assets/scala-CT-TSn-3.js +1 -0
- package/dist/client/assets/scheme-BkJvX1f4.js +1 -0
- package/dist/client/assets/scss-B5N7uefM.js +3 -0
- package/dist/client/assets/{session-browser-prefs-BI-rZu2N.js → session-browser-prefs-LLoiG_YM.js} +1 -1
- package/dist/client/assets/{sessions-CJI89wYu.js → sessions-LymnKAC6.js} +1 -1
- package/dist/client/assets/shell-DGQq63Qg.js +1 -0
- package/dist/client/assets/{skills-DjdZmDZP.js → skills-5sEozVye.js} +1 -1
- package/dist/client/assets/solidity-BGsdM1K-.js +1 -0
- package/dist/client/assets/sophia-2vdPWHk_.js +1 -0
- package/dist/client/assets/sparql-BVtOOc6V.js +1 -0
- package/dist/client/assets/sql-ceGY-xNe.js +1 -0
- package/dist/client/assets/st-DupPN7oj.js +1 -0
- package/dist/client/assets/swift-BVzV3sGw.js +1 -0
- package/dist/client/assets/systemverilog-hp5X8uST.js +1 -0
- package/dist/client/assets/tcl-D56hFaYe.js +1 -0
- package/dist/client/assets/ts.worker-BwM5Ha3L.js +67719 -0
- package/dist/client/assets/tsMode-DGr7-1MY.js +11 -0
- package/dist/client/assets/twig-C2ivmPwo.js +1 -0
- package/dist/client/assets/typescript-yGuzzsRv.js +1 -0
- package/dist/client/assets/typespec-DxADZqov.js +1 -0
- package/dist/client/assets/{use-message-sSsrvqld.js → use-message-DOCgeMXd.js} +1 -1
- package/dist/client/assets/{useTheme-DgQIobZP.js → useTheme-Dm7n8Zfn.js} +1 -1
- package/dist/client/assets/vb-EBCrbQ4-.js +1 -0
- package/dist/client/assets/wgsl-9pwzQzLa.js +298 -0
- package/dist/client/assets/workers-LkP66fNk.js +1 -0
- package/dist/client/assets/xml-Dnyprwt6.js +1 -0
- package/dist/client/assets/yaml-BU-x4ie7.js +1 -0
- package/dist/client/index.html +36 -31
- package/dist/server/index.js +2201 -398
- package/dist/server/index.js.map +4 -4
- package/package.json +18 -4
- package/dist/client/assets/Add-DiTv65Se.js +0 -1
- package/dist/client/assets/ChatView--lvFbW3I.js +0 -127
- package/dist/client/assets/GatewaysView-DUPP1UyD.js +0 -1
- package/dist/client/assets/Input-BS71ZaoJ.js +0 -234
- package/dist/client/assets/JobsView-CXa1h0NF.js +0 -2
- package/dist/client/assets/LoginView-Cpod3SAL.js +0 -1
- package/dist/client/assets/LogsView-CgxeVMn-.js +0 -1
- package/dist/client/assets/MemoryView-BQjYVDJc.js +0 -7
- package/dist/client/assets/ModelsView-CVghPzgk.js +0 -1
- package/dist/client/assets/Popconfirm-Bpz_dC1j.js +0 -16
- package/dist/client/assets/Popover-CXrjClQw.js +0 -117
- package/dist/client/assets/ProfilesView-Brpyzl-Q.js +0 -440
- package/dist/client/assets/Select-Z20Mp4nQ.js +0 -340
- package/dist/client/assets/SettingRow-Cz749k-e.js +0 -1
- package/dist/client/assets/SettingsView-C3HbKb4w.js +0 -352
- package/dist/client/assets/SkillsView-qVZkbI37.js +0 -1
- package/dist/client/assets/Suffix-C1Mw6UwH.js +0 -90
- package/dist/client/assets/Tooltip-Dka1-DNs.js +0 -1
- package/dist/client/assets/UsageView-elTUQCED.js +0 -1
- package/dist/client/assets/app-BMD_VOYs.js +0 -1
- package/dist/client/assets/app-y8cD3FPg.js +0 -1
- package/dist/client/assets/browser-DlPqZ-4M.js +0 -47
- package/dist/client/assets/chat-3-o9JAHE.js +0 -6
- package/dist/client/assets/composables-CoSqDggz.js +0 -1
- package/dist/client/assets/fade-in.cssr-D0suZaLL.js +0 -12
- package/dist/client/assets/index-CeFFa_Wg.js +0 -284
- package/dist/client/assets/jobs-DMiCP2Li.js +0 -1
- package/dist/client/assets/profiles-1vZTTlBc.js +0 -1
- package/dist/client/assets/router-kR4kqS2l.js +0 -4
- /package/dist/client/assets/{_common-D_mHAddk.js → _common-DdtSL-nr.js} +0 -0
- /package/dist/client/assets/{logo-Cd-t_oGE.js → logo-D12u0f1i.js} +0 -0
package/dist/server/index.js
CHANGED
|
@@ -2172,7 +2172,7 @@ var require_content_disposition = __commonJS({
|
|
|
2172
2172
|
"use strict";
|
|
2173
2173
|
module2.exports = contentDisposition;
|
|
2174
2174
|
module2.exports.parse = parse2;
|
|
2175
|
-
var
|
|
2175
|
+
var basename4 = require("path").basename;
|
|
2176
2176
|
var Buffer2 = require_safe_buffer().Buffer;
|
|
2177
2177
|
var ENCODE_URL_ATTR_CHAR_REGEXP = /[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g;
|
|
2178
2178
|
var HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/;
|
|
@@ -2208,9 +2208,9 @@ var require_content_disposition = __commonJS({
|
|
|
2208
2208
|
if (typeof fallback === "string" && NON_LATIN1_REGEXP.test(fallback)) {
|
|
2209
2209
|
throw new TypeError("fallback must be ISO-8859-1 string");
|
|
2210
2210
|
}
|
|
2211
|
-
var name =
|
|
2211
|
+
var name = basename4(filename);
|
|
2212
2212
|
var isQuotedString = TEXT_REGEXP.test(name);
|
|
2213
|
-
var fallbackName = typeof fallback !== "string" ? fallback && getlatin1(name) :
|
|
2213
|
+
var fallbackName = typeof fallback !== "string" ? fallback && getlatin1(name) : basename4(fallback);
|
|
2214
2214
|
var hasFallback = typeof fallbackName === "string" && fallbackName !== name;
|
|
2215
2215
|
if (hasFallback || !isQuotedString || HEX_ESCAPE_REGEXP.test(name)) {
|
|
2216
2216
|
params["filename*"] = name;
|
|
@@ -10866,7 +10866,7 @@ var require_mime_types = __commonJS({
|
|
|
10866
10866
|
"node_modules/mime-types/index.js"(exports2) {
|
|
10867
10867
|
"use strict";
|
|
10868
10868
|
var db = require_mime_db();
|
|
10869
|
-
var
|
|
10869
|
+
var extname2 = require("path").extname;
|
|
10870
10870
|
var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/;
|
|
10871
10871
|
var TEXT_TYPE_REGEXP = /^text\//i;
|
|
10872
10872
|
exports2.charset = charset;
|
|
@@ -10920,7 +10920,7 @@ var require_mime_types = __commonJS({
|
|
|
10920
10920
|
if (!path || typeof path !== "string") {
|
|
10921
10921
|
return false;
|
|
10922
10922
|
}
|
|
10923
|
-
var extension3 =
|
|
10923
|
+
var extension3 = extname2("x." + path).toLowerCase().substr(1);
|
|
10924
10924
|
if (!extension3) {
|
|
10925
10925
|
return false;
|
|
10926
10926
|
}
|
|
@@ -11247,7 +11247,7 @@ var require_type_is = __commonJS({
|
|
|
11247
11247
|
module2.exports = typeofrequest;
|
|
11248
11248
|
module2.exports.is = typeis2;
|
|
11249
11249
|
module2.exports.hasBody = hasbody;
|
|
11250
|
-
module2.exports.normalize =
|
|
11250
|
+
module2.exports.normalize = normalize2;
|
|
11251
11251
|
module2.exports.match = mimeMatch;
|
|
11252
11252
|
function typeis2(value, types_) {
|
|
11253
11253
|
var i;
|
|
@@ -11267,7 +11267,7 @@ var require_type_is = __commonJS({
|
|
|
11267
11267
|
}
|
|
11268
11268
|
var type2;
|
|
11269
11269
|
for (i = 0; i < types2.length; i++) {
|
|
11270
|
-
if (mimeMatch(
|
|
11270
|
+
if (mimeMatch(normalize2(type2 = types2[i]), val)) {
|
|
11271
11271
|
return type2[0] === "+" || type2.indexOf("*") !== -1 ? val : type2;
|
|
11272
11272
|
}
|
|
11273
11273
|
}
|
|
@@ -11290,7 +11290,7 @@ var require_type_is = __commonJS({
|
|
|
11290
11290
|
var value = req.headers["content-type"];
|
|
11291
11291
|
return typeis2(value, types2);
|
|
11292
11292
|
}
|
|
11293
|
-
function
|
|
11293
|
+
function normalize2(type2) {
|
|
11294
11294
|
if (typeof type2 !== "string") {
|
|
11295
11295
|
return false;
|
|
11296
11296
|
}
|
|
@@ -11420,10 +11420,10 @@ var require_statuses = __commonJS({
|
|
|
11420
11420
|
"node_modules/koa/node_modules/statuses/index.js"(exports2, module2) {
|
|
11421
11421
|
"use strict";
|
|
11422
11422
|
var codes = require_codes();
|
|
11423
|
-
module2.exports =
|
|
11424
|
-
|
|
11425
|
-
|
|
11426
|
-
|
|
11423
|
+
module2.exports = status3;
|
|
11424
|
+
status3.STATUS_CODES = codes;
|
|
11425
|
+
status3.codes = populateStatusesMap(status3, codes);
|
|
11426
|
+
status3.redirect = {
|
|
11427
11427
|
300: true,
|
|
11428
11428
|
301: true,
|
|
11429
11429
|
302: true,
|
|
@@ -11432,12 +11432,12 @@ var require_statuses = __commonJS({
|
|
|
11432
11432
|
307: true,
|
|
11433
11433
|
308: true
|
|
11434
11434
|
};
|
|
11435
|
-
|
|
11435
|
+
status3.empty = {
|
|
11436
11436
|
204: true,
|
|
11437
11437
|
205: true,
|
|
11438
11438
|
304: true
|
|
11439
11439
|
};
|
|
11440
|
-
|
|
11440
|
+
status3.retry = {
|
|
11441
11441
|
502: true,
|
|
11442
11442
|
503: true,
|
|
11443
11443
|
504: true
|
|
@@ -11446,17 +11446,17 @@ var require_statuses = __commonJS({
|
|
|
11446
11446
|
var arr = [];
|
|
11447
11447
|
Object.keys(codes2).forEach(function forEachCode(code) {
|
|
11448
11448
|
var message2 = codes2[code];
|
|
11449
|
-
var
|
|
11450
|
-
statuses[
|
|
11451
|
-
statuses[message2] =
|
|
11452
|
-
statuses[message2.toLowerCase()] =
|
|
11453
|
-
arr.push(
|
|
11449
|
+
var status4 = Number(code);
|
|
11450
|
+
statuses[status4] = message2;
|
|
11451
|
+
statuses[message2] = status4;
|
|
11452
|
+
statuses[message2.toLowerCase()] = status4;
|
|
11453
|
+
arr.push(status4);
|
|
11454
11454
|
});
|
|
11455
11455
|
return arr;
|
|
11456
11456
|
}
|
|
11457
|
-
function
|
|
11457
|
+
function status3(code) {
|
|
11458
11458
|
if (typeof code === "number") {
|
|
11459
|
-
if (!
|
|
11459
|
+
if (!status3[code]) throw new Error("invalid status code: " + code);
|
|
11460
11460
|
return code;
|
|
11461
11461
|
}
|
|
11462
11462
|
if (typeof code !== "string") {
|
|
@@ -11464,10 +11464,10 @@ var require_statuses = __commonJS({
|
|
|
11464
11464
|
}
|
|
11465
11465
|
var n = parseInt(code, 10);
|
|
11466
11466
|
if (!isNaN(n)) {
|
|
11467
|
-
if (!
|
|
11467
|
+
if (!status3[n]) throw new Error("invalid status code: " + n);
|
|
11468
11468
|
return n;
|
|
11469
11469
|
}
|
|
11470
|
-
n =
|
|
11470
|
+
n = status3[code.toLowerCase()];
|
|
11471
11471
|
if (!n) throw new Error('invalid status message: "' + code + '"');
|
|
11472
11472
|
return n;
|
|
11473
11473
|
}
|
|
@@ -11601,24 +11601,24 @@ var require_vary = __commonJS({
|
|
|
11601
11601
|
function parse2(header) {
|
|
11602
11602
|
var end = 0;
|
|
11603
11603
|
var list6 = [];
|
|
11604
|
-
var
|
|
11604
|
+
var start4 = 0;
|
|
11605
11605
|
for (var i = 0, len = header.length; i < len; i++) {
|
|
11606
11606
|
switch (header.charCodeAt(i)) {
|
|
11607
11607
|
case 32:
|
|
11608
|
-
if (
|
|
11609
|
-
|
|
11608
|
+
if (start4 === end) {
|
|
11609
|
+
start4 = end = i + 1;
|
|
11610
11610
|
}
|
|
11611
11611
|
break;
|
|
11612
11612
|
case 44:
|
|
11613
|
-
list6.push(header.substring(
|
|
11614
|
-
|
|
11613
|
+
list6.push(header.substring(start4, end));
|
|
11614
|
+
start4 = end = i + 1;
|
|
11615
11615
|
break;
|
|
11616
11616
|
default:
|
|
11617
11617
|
end = i + 1;
|
|
11618
11618
|
break;
|
|
11619
11619
|
}
|
|
11620
11620
|
}
|
|
11621
|
-
list6.push(header.substring(
|
|
11621
|
+
list6.push(header.substring(start4, end));
|
|
11622
11622
|
return list6;
|
|
11623
11623
|
}
|
|
11624
11624
|
function vary(res, field) {
|
|
@@ -11675,7 +11675,7 @@ var require_response = __commonJS({
|
|
|
11675
11675
|
var statuses = require_statuses();
|
|
11676
11676
|
var destroy = require_destroy();
|
|
11677
11677
|
var assert = require("assert");
|
|
11678
|
-
var
|
|
11678
|
+
var extname2 = require("path").extname;
|
|
11679
11679
|
var vary = require_vary();
|
|
11680
11680
|
var only = require_only();
|
|
11681
11681
|
var util3 = require("util");
|
|
@@ -11901,7 +11901,7 @@ var require_response = __commonJS({
|
|
|
11901
11901
|
* @api public
|
|
11902
11902
|
*/
|
|
11903
11903
|
attachment(filename, options) {
|
|
11904
|
-
if (filename) this.type =
|
|
11904
|
+
if (filename) this.type = extname2(filename);
|
|
11905
11905
|
this.set("Content-Disposition", contentDisposition(filename, options));
|
|
11906
11906
|
},
|
|
11907
11907
|
/**
|
|
@@ -12693,19 +12693,19 @@ var require_http_errors = __commonJS({
|
|
|
12693
12693
|
module2.exports.HttpError = createHttpErrorConstructor();
|
|
12694
12694
|
module2.exports.isHttpError = createIsHttpErrorFunction(module2.exports.HttpError);
|
|
12695
12695
|
populateConstructorExports(module2.exports, statuses.codes, module2.exports.HttpError);
|
|
12696
|
-
function codeClass(
|
|
12697
|
-
return Number(String(
|
|
12696
|
+
function codeClass(status3) {
|
|
12697
|
+
return Number(String(status3).charAt(0) + "00");
|
|
12698
12698
|
}
|
|
12699
12699
|
function createError() {
|
|
12700
12700
|
var err;
|
|
12701
12701
|
var msg;
|
|
12702
|
-
var
|
|
12702
|
+
var status3 = 500;
|
|
12703
12703
|
var props = {};
|
|
12704
12704
|
for (var i = 0; i < arguments.length; i++) {
|
|
12705
12705
|
var arg = arguments[i];
|
|
12706
12706
|
if (arg instanceof Error) {
|
|
12707
12707
|
err = arg;
|
|
12708
|
-
|
|
12708
|
+
status3 = err.status || err.statusCode || status3;
|
|
12709
12709
|
continue;
|
|
12710
12710
|
}
|
|
12711
12711
|
switch (typeof arg) {
|
|
@@ -12713,7 +12713,7 @@ var require_http_errors = __commonJS({
|
|
|
12713
12713
|
msg = arg;
|
|
12714
12714
|
break;
|
|
12715
12715
|
case "number":
|
|
12716
|
-
|
|
12716
|
+
status3 = arg;
|
|
12717
12717
|
if (i !== 0) {
|
|
12718
12718
|
deprecate2("non-first-argument status code; replace with createError(" + arg + ", ...)");
|
|
12719
12719
|
}
|
|
@@ -12723,20 +12723,20 @@ var require_http_errors = __commonJS({
|
|
|
12723
12723
|
break;
|
|
12724
12724
|
}
|
|
12725
12725
|
}
|
|
12726
|
-
if (typeof
|
|
12726
|
+
if (typeof status3 === "number" && (status3 < 400 || status3 >= 600)) {
|
|
12727
12727
|
deprecate2("non-error status code; use only 4xx or 5xx status codes");
|
|
12728
12728
|
}
|
|
12729
|
-
if (typeof
|
|
12730
|
-
|
|
12729
|
+
if (typeof status3 !== "number" || !statuses[status3] && (status3 < 400 || status3 >= 600)) {
|
|
12730
|
+
status3 = 500;
|
|
12731
12731
|
}
|
|
12732
|
-
var HttpError3 = createError[
|
|
12732
|
+
var HttpError3 = createError[status3] || createError[codeClass(status3)];
|
|
12733
12733
|
if (!err) {
|
|
12734
|
-
err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses[
|
|
12734
|
+
err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses[status3]);
|
|
12735
12735
|
Error.captureStackTrace(err, createError);
|
|
12736
12736
|
}
|
|
12737
|
-
if (!HttpError3 || !(err instanceof HttpError3) || err.status !==
|
|
12738
|
-
err.expose =
|
|
12739
|
-
err.status = err.statusCode =
|
|
12737
|
+
if (!HttpError3 || !(err instanceof HttpError3) || err.status !== status3) {
|
|
12738
|
+
err.expose = status3 < 500;
|
|
12739
|
+
err.status = err.statusCode = status3;
|
|
12740
12740
|
}
|
|
12741
12741
|
for (var key in props) {
|
|
12742
12742
|
if (key !== "status" && key !== "statusCode") {
|
|
@@ -13357,10 +13357,10 @@ var require_statuses2 = __commonJS({
|
|
|
13357
13357
|
"node_modules/http-assert/node_modules/statuses/index.js"(exports2, module2) {
|
|
13358
13358
|
"use strict";
|
|
13359
13359
|
var codes = require_codes2();
|
|
13360
|
-
module2.exports =
|
|
13361
|
-
|
|
13362
|
-
|
|
13363
|
-
|
|
13360
|
+
module2.exports = status3;
|
|
13361
|
+
status3.STATUS_CODES = codes;
|
|
13362
|
+
status3.codes = populateStatusesMap(status3, codes);
|
|
13363
|
+
status3.redirect = {
|
|
13364
13364
|
300: true,
|
|
13365
13365
|
301: true,
|
|
13366
13366
|
302: true,
|
|
@@ -13369,12 +13369,12 @@ var require_statuses2 = __commonJS({
|
|
|
13369
13369
|
307: true,
|
|
13370
13370
|
308: true
|
|
13371
13371
|
};
|
|
13372
|
-
|
|
13372
|
+
status3.empty = {
|
|
13373
13373
|
204: true,
|
|
13374
13374
|
205: true,
|
|
13375
13375
|
304: true
|
|
13376
13376
|
};
|
|
13377
|
-
|
|
13377
|
+
status3.retry = {
|
|
13378
13378
|
502: true,
|
|
13379
13379
|
503: true,
|
|
13380
13380
|
504: true
|
|
@@ -13383,17 +13383,17 @@ var require_statuses2 = __commonJS({
|
|
|
13383
13383
|
var arr = [];
|
|
13384
13384
|
Object.keys(codes2).forEach(function forEachCode(code) {
|
|
13385
13385
|
var message2 = codes2[code];
|
|
13386
|
-
var
|
|
13387
|
-
statuses[
|
|
13388
|
-
statuses[message2] =
|
|
13389
|
-
statuses[message2.toLowerCase()] =
|
|
13390
|
-
arr.push(
|
|
13386
|
+
var status4 = Number(code);
|
|
13387
|
+
statuses[status4] = message2;
|
|
13388
|
+
statuses[message2] = status4;
|
|
13389
|
+
statuses[message2.toLowerCase()] = status4;
|
|
13390
|
+
arr.push(status4);
|
|
13391
13391
|
});
|
|
13392
13392
|
return arr;
|
|
13393
13393
|
}
|
|
13394
|
-
function
|
|
13394
|
+
function status3(code) {
|
|
13395
13395
|
if (typeof code === "number") {
|
|
13396
|
-
if (!
|
|
13396
|
+
if (!status3[code]) throw new Error("invalid status code: " + code);
|
|
13397
13397
|
return code;
|
|
13398
13398
|
}
|
|
13399
13399
|
if (typeof code !== "string") {
|
|
@@ -13401,10 +13401,10 @@ var require_statuses2 = __commonJS({
|
|
|
13401
13401
|
}
|
|
13402
13402
|
var n = parseInt(code, 10);
|
|
13403
13403
|
if (!isNaN(n)) {
|
|
13404
|
-
if (!
|
|
13404
|
+
if (!status3[n]) throw new Error("invalid status code: " + n);
|
|
13405
13405
|
return n;
|
|
13406
13406
|
}
|
|
13407
|
-
n =
|
|
13407
|
+
n = status3[code.toLowerCase()];
|
|
13408
13408
|
if (!n) throw new Error('invalid status message: "' + code + '"');
|
|
13409
13409
|
return n;
|
|
13410
13410
|
}
|
|
@@ -13424,19 +13424,19 @@ var require_http_errors2 = __commonJS({
|
|
|
13424
13424
|
module2.exports.HttpError = createHttpErrorConstructor();
|
|
13425
13425
|
module2.exports.isHttpError = createIsHttpErrorFunction(module2.exports.HttpError);
|
|
13426
13426
|
populateConstructorExports(module2.exports, statuses.codes, module2.exports.HttpError);
|
|
13427
|
-
function codeClass(
|
|
13428
|
-
return Number(String(
|
|
13427
|
+
function codeClass(status3) {
|
|
13428
|
+
return Number(String(status3).charAt(0) + "00");
|
|
13429
13429
|
}
|
|
13430
13430
|
function createError() {
|
|
13431
13431
|
var err;
|
|
13432
13432
|
var msg;
|
|
13433
|
-
var
|
|
13433
|
+
var status3 = 500;
|
|
13434
13434
|
var props = {};
|
|
13435
13435
|
for (var i = 0; i < arguments.length; i++) {
|
|
13436
13436
|
var arg = arguments[i];
|
|
13437
13437
|
if (arg instanceof Error) {
|
|
13438
13438
|
err = arg;
|
|
13439
|
-
|
|
13439
|
+
status3 = err.status || err.statusCode || status3;
|
|
13440
13440
|
continue;
|
|
13441
13441
|
}
|
|
13442
13442
|
switch (typeof arg) {
|
|
@@ -13444,7 +13444,7 @@ var require_http_errors2 = __commonJS({
|
|
|
13444
13444
|
msg = arg;
|
|
13445
13445
|
break;
|
|
13446
13446
|
case "number":
|
|
13447
|
-
|
|
13447
|
+
status3 = arg;
|
|
13448
13448
|
if (i !== 0) {
|
|
13449
13449
|
deprecate2("non-first-argument status code; replace with createError(" + arg + ", ...)");
|
|
13450
13450
|
}
|
|
@@ -13454,20 +13454,20 @@ var require_http_errors2 = __commonJS({
|
|
|
13454
13454
|
break;
|
|
13455
13455
|
}
|
|
13456
13456
|
}
|
|
13457
|
-
if (typeof
|
|
13457
|
+
if (typeof status3 === "number" && (status3 < 400 || status3 >= 600)) {
|
|
13458
13458
|
deprecate2("non-error status code; use only 4xx or 5xx status codes");
|
|
13459
13459
|
}
|
|
13460
|
-
if (typeof
|
|
13461
|
-
|
|
13460
|
+
if (typeof status3 !== "number" || !statuses[status3] && (status3 < 400 || status3 >= 600)) {
|
|
13461
|
+
status3 = 500;
|
|
13462
13462
|
}
|
|
13463
|
-
var HttpError3 = createError[
|
|
13463
|
+
var HttpError3 = createError[status3] || createError[codeClass(status3)];
|
|
13464
13464
|
if (!err) {
|
|
13465
|
-
err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses[
|
|
13465
|
+
err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses[status3]);
|
|
13466
13466
|
Error.captureStackTrace(err, createError);
|
|
13467
13467
|
}
|
|
13468
|
-
if (!HttpError3 || !(err instanceof HttpError3) || err.status !==
|
|
13469
|
-
err.expose =
|
|
13470
|
-
err.status = err.statusCode =
|
|
13468
|
+
if (!HttpError3 || !(err instanceof HttpError3) || err.status !== status3) {
|
|
13469
|
+
err.expose = status3 < 500;
|
|
13470
|
+
err.status = err.statusCode = status3;
|
|
13471
13471
|
}
|
|
13472
13472
|
for (var key in props) {
|
|
13473
13473
|
if (key !== "status" && key !== "statusCode") {
|
|
@@ -13698,33 +13698,33 @@ var require_http_assert = __commonJS({
|
|
|
13698
13698
|
var createError = require_http_errors2();
|
|
13699
13699
|
var eql = require_deep_equal();
|
|
13700
13700
|
module2.exports = assert;
|
|
13701
|
-
function assert(value,
|
|
13701
|
+
function assert(value, status3, msg, opts) {
|
|
13702
13702
|
if (value) return;
|
|
13703
|
-
throw createError(
|
|
13703
|
+
throw createError(status3, msg, opts);
|
|
13704
13704
|
}
|
|
13705
|
-
assert.fail = function(
|
|
13706
|
-
assert(false,
|
|
13705
|
+
assert.fail = function(status3, msg, opts) {
|
|
13706
|
+
assert(false, status3, msg, opts);
|
|
13707
13707
|
};
|
|
13708
|
-
assert.equal = function(a, b,
|
|
13709
|
-
assert(a == b,
|
|
13708
|
+
assert.equal = function(a, b, status3, msg, opts) {
|
|
13709
|
+
assert(a == b, status3, msg, opts);
|
|
13710
13710
|
};
|
|
13711
|
-
assert.notEqual = function(a, b,
|
|
13712
|
-
assert(a != b,
|
|
13711
|
+
assert.notEqual = function(a, b, status3, msg, opts) {
|
|
13712
|
+
assert(a != b, status3, msg, opts);
|
|
13713
13713
|
};
|
|
13714
|
-
assert.ok = function(value,
|
|
13715
|
-
assert(value,
|
|
13714
|
+
assert.ok = function(value, status3, msg, opts) {
|
|
13715
|
+
assert(value, status3, msg, opts);
|
|
13716
13716
|
};
|
|
13717
|
-
assert.strictEqual = function(a, b,
|
|
13718
|
-
assert(a === b,
|
|
13717
|
+
assert.strictEqual = function(a, b, status3, msg, opts) {
|
|
13718
|
+
assert(a === b, status3, msg, opts);
|
|
13719
13719
|
};
|
|
13720
|
-
assert.notStrictEqual = function(a, b,
|
|
13721
|
-
assert(a !== b,
|
|
13720
|
+
assert.notStrictEqual = function(a, b, status3, msg, opts) {
|
|
13721
|
+
assert(a !== b, status3, msg, opts);
|
|
13722
13722
|
};
|
|
13723
|
-
assert.deepEqual = function(a, b,
|
|
13724
|
-
assert(eql(a, b),
|
|
13723
|
+
assert.deepEqual = function(a, b, status3, msg, opts) {
|
|
13724
|
+
assert(eql(a, b), status3, msg, opts);
|
|
13725
13725
|
};
|
|
13726
|
-
assert.notDeepEqual = function(a, b,
|
|
13727
|
-
assert(!eql(a, b),
|
|
13726
|
+
assert.notDeepEqual = function(a, b, status3, msg, opts) {
|
|
13727
|
+
assert(!eql(a, b), status3, msg, opts);
|
|
13728
13728
|
};
|
|
13729
13729
|
}
|
|
13730
13730
|
});
|
|
@@ -15301,24 +15301,24 @@ var require_fresh = __commonJS({
|
|
|
15301
15301
|
function parseTokenList(str2) {
|
|
15302
15302
|
var end = 0;
|
|
15303
15303
|
var list6 = [];
|
|
15304
|
-
var
|
|
15304
|
+
var start4 = 0;
|
|
15305
15305
|
for (var i = 0, len = str2.length; i < len; i++) {
|
|
15306
15306
|
switch (str2.charCodeAt(i)) {
|
|
15307
15307
|
case 32:
|
|
15308
|
-
if (
|
|
15309
|
-
|
|
15308
|
+
if (start4 === end) {
|
|
15309
|
+
start4 = end = i + 1;
|
|
15310
15310
|
}
|
|
15311
15311
|
break;
|
|
15312
15312
|
case 44:
|
|
15313
|
-
list6.push(str2.substring(
|
|
15314
|
-
|
|
15313
|
+
list6.push(str2.substring(start4, end));
|
|
15314
|
+
start4 = end = i + 1;
|
|
15315
15315
|
break;
|
|
15316
15316
|
default:
|
|
15317
15317
|
end = i + 1;
|
|
15318
15318
|
break;
|
|
15319
15319
|
}
|
|
15320
15320
|
}
|
|
15321
|
-
list6.push(str2.substring(
|
|
15321
|
+
list6.push(str2.substring(start4, end));
|
|
15322
15322
|
return list6;
|
|
15323
15323
|
}
|
|
15324
15324
|
}
|
|
@@ -15958,9 +15958,9 @@ var require_co = __commonJS({
|
|
|
15958
15958
|
function co(gen) {
|
|
15959
15959
|
var ctx = this;
|
|
15960
15960
|
var args2 = slice.call(arguments, 1);
|
|
15961
|
-
return new Promise(function(
|
|
15961
|
+
return new Promise(function(resolve11, reject) {
|
|
15962
15962
|
if (typeof gen === "function") gen = gen.apply(ctx, args2);
|
|
15963
|
-
if (!gen || typeof gen.next !== "function") return
|
|
15963
|
+
if (!gen || typeof gen.next !== "function") return resolve11(gen);
|
|
15964
15964
|
onFulfilled();
|
|
15965
15965
|
function onFulfilled(res) {
|
|
15966
15966
|
var ret;
|
|
@@ -15981,7 +15981,7 @@ var require_co = __commonJS({
|
|
|
15981
15981
|
next(ret);
|
|
15982
15982
|
}
|
|
15983
15983
|
function next(ret) {
|
|
15984
|
-
if (ret.done) return
|
|
15984
|
+
if (ret.done) return resolve11(ret.value);
|
|
15985
15985
|
var value = toPromise.call(ctx, ret.value);
|
|
15986
15986
|
if (value && isPromise(value)) return value.then(onFulfilled, onRejected);
|
|
15987
15987
|
return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, but the following object was passed: "' + String(ret.value) + '"'));
|
|
@@ -15999,11 +15999,11 @@ var require_co = __commonJS({
|
|
|
15999
15999
|
}
|
|
16000
16000
|
function thunkToPromise(fn2) {
|
|
16001
16001
|
var ctx = this;
|
|
16002
|
-
return new Promise(function(
|
|
16002
|
+
return new Promise(function(resolve11, reject) {
|
|
16003
16003
|
fn2.call(ctx, function(err, res) {
|
|
16004
16004
|
if (err) return reject(err);
|
|
16005
16005
|
if (arguments.length > 2) res = slice.call(arguments, 1);
|
|
16006
|
-
|
|
16006
|
+
resolve11(res);
|
|
16007
16007
|
});
|
|
16008
16008
|
});
|
|
16009
16009
|
}
|
|
@@ -16640,11 +16640,11 @@ var require_statuses3 = __commonJS({
|
|
|
16640
16640
|
"node_modules/statuses/index.js"(exports2, module2) {
|
|
16641
16641
|
"use strict";
|
|
16642
16642
|
var codes = require_codes3();
|
|
16643
|
-
module2.exports =
|
|
16644
|
-
|
|
16645
|
-
|
|
16646
|
-
|
|
16647
|
-
|
|
16643
|
+
module2.exports = status3;
|
|
16644
|
+
status3.message = codes;
|
|
16645
|
+
status3.code = createMessageToStatusCodeMap(codes);
|
|
16646
|
+
status3.codes = createStatusCodeList(codes);
|
|
16647
|
+
status3.redirect = {
|
|
16648
16648
|
300: true,
|
|
16649
16649
|
301: true,
|
|
16650
16650
|
302: true,
|
|
@@ -16653,12 +16653,12 @@ var require_statuses3 = __commonJS({
|
|
|
16653
16653
|
307: true,
|
|
16654
16654
|
308: true
|
|
16655
16655
|
};
|
|
16656
|
-
|
|
16656
|
+
status3.empty = {
|
|
16657
16657
|
204: true,
|
|
16658
16658
|
205: true,
|
|
16659
16659
|
304: true
|
|
16660
16660
|
};
|
|
16661
|
-
|
|
16661
|
+
status3.retry = {
|
|
16662
16662
|
502: true,
|
|
16663
16663
|
503: true,
|
|
16664
16664
|
504: true
|
|
@@ -16667,8 +16667,8 @@ var require_statuses3 = __commonJS({
|
|
|
16667
16667
|
var map2 = {};
|
|
16668
16668
|
Object.keys(codes2).forEach(function forEachCode(code) {
|
|
16669
16669
|
var message2 = codes2[code];
|
|
16670
|
-
var
|
|
16671
|
-
map2[message2.toLowerCase()] =
|
|
16670
|
+
var status4 = Number(code);
|
|
16671
|
+
map2[message2.toLowerCase()] = status4;
|
|
16672
16672
|
});
|
|
16673
16673
|
return map2;
|
|
16674
16674
|
}
|
|
@@ -16679,18 +16679,18 @@ var require_statuses3 = __commonJS({
|
|
|
16679
16679
|
}
|
|
16680
16680
|
function getStatusCode(message2) {
|
|
16681
16681
|
var msg = message2.toLowerCase();
|
|
16682
|
-
if (!Object.prototype.hasOwnProperty.call(
|
|
16682
|
+
if (!Object.prototype.hasOwnProperty.call(status3.code, msg)) {
|
|
16683
16683
|
throw new Error('invalid status message: "' + message2 + '"');
|
|
16684
16684
|
}
|
|
16685
|
-
return
|
|
16685
|
+
return status3.code[msg];
|
|
16686
16686
|
}
|
|
16687
16687
|
function getStatusMessage(code) {
|
|
16688
|
-
if (!Object.prototype.hasOwnProperty.call(
|
|
16688
|
+
if (!Object.prototype.hasOwnProperty.call(status3.message, code)) {
|
|
16689
16689
|
throw new Error("invalid status code: " + code);
|
|
16690
16690
|
}
|
|
16691
|
-
return
|
|
16691
|
+
return status3.message[code];
|
|
16692
16692
|
}
|
|
16693
|
-
function
|
|
16693
|
+
function status3(code) {
|
|
16694
16694
|
if (typeof code === "number") {
|
|
16695
16695
|
return getStatusMessage(code);
|
|
16696
16696
|
}
|
|
@@ -16719,22 +16719,22 @@ var require_http_errors3 = __commonJS({
|
|
|
16719
16719
|
module2.exports.HttpError = createHttpErrorConstructor();
|
|
16720
16720
|
module2.exports.isHttpError = createIsHttpErrorFunction(module2.exports.HttpError);
|
|
16721
16721
|
populateConstructorExports(module2.exports, statuses.codes, module2.exports.HttpError);
|
|
16722
|
-
function codeClass(
|
|
16723
|
-
return Number(String(
|
|
16722
|
+
function codeClass(status3) {
|
|
16723
|
+
return Number(String(status3).charAt(0) + "00");
|
|
16724
16724
|
}
|
|
16725
16725
|
function createError() {
|
|
16726
16726
|
var err;
|
|
16727
16727
|
var msg;
|
|
16728
|
-
var
|
|
16728
|
+
var status3 = 500;
|
|
16729
16729
|
var props = {};
|
|
16730
16730
|
for (var i = 0; i < arguments.length; i++) {
|
|
16731
16731
|
var arg = arguments[i];
|
|
16732
16732
|
var type2 = typeof arg;
|
|
16733
16733
|
if (type2 === "object" && arg instanceof Error) {
|
|
16734
16734
|
err = arg;
|
|
16735
|
-
|
|
16735
|
+
status3 = err.status || err.statusCode || status3;
|
|
16736
16736
|
} else if (type2 === "number" && i === 0) {
|
|
16737
|
-
|
|
16737
|
+
status3 = arg;
|
|
16738
16738
|
} else if (type2 === "string") {
|
|
16739
16739
|
msg = arg;
|
|
16740
16740
|
} else if (type2 === "object") {
|
|
@@ -16743,20 +16743,20 @@ var require_http_errors3 = __commonJS({
|
|
|
16743
16743
|
throw new TypeError("argument #" + (i + 1) + " unsupported type " + type2);
|
|
16744
16744
|
}
|
|
16745
16745
|
}
|
|
16746
|
-
if (typeof
|
|
16746
|
+
if (typeof status3 === "number" && (status3 < 400 || status3 >= 600)) {
|
|
16747
16747
|
deprecate2("non-error status code; use only 4xx or 5xx status codes");
|
|
16748
16748
|
}
|
|
16749
|
-
if (typeof
|
|
16750
|
-
|
|
16749
|
+
if (typeof status3 !== "number" || !statuses.message[status3] && (status3 < 400 || status3 >= 600)) {
|
|
16750
|
+
status3 = 500;
|
|
16751
16751
|
}
|
|
16752
|
-
var HttpError3 = createError[
|
|
16752
|
+
var HttpError3 = createError[status3] || createError[codeClass(status3)];
|
|
16753
16753
|
if (!err) {
|
|
16754
|
-
err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses.message[
|
|
16754
|
+
err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses.message[status3]);
|
|
16755
16755
|
Error.captureStackTrace(err, createError);
|
|
16756
16756
|
}
|
|
16757
|
-
if (!HttpError3 || !(err instanceof HttpError3) || err.status !==
|
|
16758
|
-
err.expose =
|
|
16759
|
-
err.status = err.statusCode =
|
|
16757
|
+
if (!HttpError3 || !(err instanceof HttpError3) || err.status !== status3) {
|
|
16758
|
+
err.expose = status3 < 500;
|
|
16759
|
+
err.status = err.statusCode = status3;
|
|
16760
16760
|
}
|
|
16761
16761
|
for (var key in props) {
|
|
16762
16762
|
if (key !== "status" && key !== "statusCode") {
|
|
@@ -20060,13 +20060,13 @@ var require_extend_node = __commonJS({
|
|
|
20060
20060
|
};
|
|
20061
20061
|
var SlowBuffer = require("buffer").SlowBuffer;
|
|
20062
20062
|
original.SlowBufferToString = SlowBuffer.prototype.toString;
|
|
20063
|
-
SlowBuffer.prototype.toString = function(encoding,
|
|
20063
|
+
SlowBuffer.prototype.toString = function(encoding, start4, end) {
|
|
20064
20064
|
encoding = String(encoding || "utf8").toLowerCase();
|
|
20065
20065
|
if (Buffer2.isNativeEncoding(encoding))
|
|
20066
|
-
return original.SlowBufferToString.call(this, encoding,
|
|
20067
|
-
if (typeof
|
|
20066
|
+
return original.SlowBufferToString.call(this, encoding, start4, end);
|
|
20067
|
+
if (typeof start4 == "undefined") start4 = 0;
|
|
20068
20068
|
if (typeof end == "undefined") end = this.length;
|
|
20069
|
-
return iconv.decode(this.slice(
|
|
20069
|
+
return iconv.decode(this.slice(start4, end), encoding);
|
|
20070
20070
|
};
|
|
20071
20071
|
original.SlowBufferWrite = SlowBuffer.prototype.write;
|
|
20072
20072
|
SlowBuffer.prototype.write = function(string, offset, length, encoding) {
|
|
@@ -20113,13 +20113,13 @@ var require_extend_node = __commonJS({
|
|
|
20113
20113
|
return iconv.encode(str2, encoding).length;
|
|
20114
20114
|
};
|
|
20115
20115
|
original.BufferToString = Buffer2.prototype.toString;
|
|
20116
|
-
Buffer2.prototype.toString = function(encoding,
|
|
20116
|
+
Buffer2.prototype.toString = function(encoding, start4, end) {
|
|
20117
20117
|
encoding = String(encoding || "utf8").toLowerCase();
|
|
20118
20118
|
if (Buffer2.isNativeEncoding(encoding))
|
|
20119
|
-
return original.BufferToString.call(this, encoding,
|
|
20120
|
-
if (typeof
|
|
20119
|
+
return original.BufferToString.call(this, encoding, start4, end);
|
|
20120
|
+
if (typeof start4 == "undefined") start4 = 0;
|
|
20121
20121
|
if (typeof end == "undefined") end = this.length;
|
|
20122
|
-
return iconv.decode(this.slice(
|
|
20122
|
+
return iconv.decode(this.slice(start4, end), encoding);
|
|
20123
20123
|
};
|
|
20124
20124
|
original.BufferWrite = Buffer2.prototype.write;
|
|
20125
20125
|
Buffer2.prototype.write = function(string, offset, length, encoding) {
|
|
@@ -20381,10 +20381,10 @@ var require_raw_body = __commonJS({
|
|
|
20381
20381
|
if (done) {
|
|
20382
20382
|
return readStream2(stream4, encoding, length, limit, wrap(done));
|
|
20383
20383
|
}
|
|
20384
|
-
return new Promise(function executor(
|
|
20384
|
+
return new Promise(function executor(resolve11, reject) {
|
|
20385
20385
|
readStream2(stream4, encoding, length, limit, function onRead(err, buf) {
|
|
20386
20386
|
if (err) return reject(err);
|
|
20387
|
-
|
|
20387
|
+
resolve11(buf);
|
|
20388
20388
|
});
|
|
20389
20389
|
});
|
|
20390
20390
|
}
|
|
@@ -22852,8 +22852,8 @@ var require_lodash = __commonJS({
|
|
|
22852
22852
|
}
|
|
22853
22853
|
assignMergeValue(object, key, newValue);
|
|
22854
22854
|
}
|
|
22855
|
-
function baseRest(func,
|
|
22856
|
-
return setToString(overRest(func,
|
|
22855
|
+
function baseRest(func, start4) {
|
|
22856
|
+
return setToString(overRest(func, start4, identity), func + "");
|
|
22857
22857
|
}
|
|
22858
22858
|
var baseSetToString = !defineProperty ? identity : function(func, string) {
|
|
22859
22859
|
return defineProperty(func, "toString", {
|
|
@@ -23002,19 +23002,19 @@ var require_lodash = __commonJS({
|
|
|
23002
23002
|
function objectToString(value) {
|
|
23003
23003
|
return nativeObjectToString.call(value);
|
|
23004
23004
|
}
|
|
23005
|
-
function overRest(func,
|
|
23006
|
-
|
|
23005
|
+
function overRest(func, start4, transform) {
|
|
23006
|
+
start4 = nativeMax(start4 === void 0 ? func.length - 1 : start4, 0);
|
|
23007
23007
|
return function() {
|
|
23008
|
-
var args2 = arguments, index = -1, length = nativeMax(args2.length -
|
|
23008
|
+
var args2 = arguments, index = -1, length = nativeMax(args2.length - start4, 0), array = Array(length);
|
|
23009
23009
|
while (++index < length) {
|
|
23010
|
-
array[index] = args2[
|
|
23010
|
+
array[index] = args2[start4 + index];
|
|
23011
23011
|
}
|
|
23012
23012
|
index = -1;
|
|
23013
|
-
var otherArgs = Array(
|
|
23014
|
-
while (++index <
|
|
23013
|
+
var otherArgs = Array(start4 + 1);
|
|
23014
|
+
while (++index < start4) {
|
|
23015
23015
|
otherArgs[index] = args2[index];
|
|
23016
23016
|
}
|
|
23017
|
-
otherArgs[
|
|
23017
|
+
otherArgs[start4] = transform(array);
|
|
23018
23018
|
return apply(func, this, otherArgs);
|
|
23019
23019
|
};
|
|
23020
23020
|
}
|
|
@@ -24001,10 +24001,10 @@ var require_statuses4 = __commonJS({
|
|
|
24001
24001
|
"node_modules/resolve-path/node_modules/statuses/index.js"(exports2, module2) {
|
|
24002
24002
|
"use strict";
|
|
24003
24003
|
var codes = require_codes4();
|
|
24004
|
-
module2.exports =
|
|
24005
|
-
|
|
24006
|
-
|
|
24007
|
-
|
|
24004
|
+
module2.exports = status3;
|
|
24005
|
+
status3.STATUS_CODES = codes;
|
|
24006
|
+
status3.codes = populateStatusesMap(status3, codes);
|
|
24007
|
+
status3.redirect = {
|
|
24008
24008
|
300: true,
|
|
24009
24009
|
301: true,
|
|
24010
24010
|
302: true,
|
|
@@ -24013,12 +24013,12 @@ var require_statuses4 = __commonJS({
|
|
|
24013
24013
|
307: true,
|
|
24014
24014
|
308: true
|
|
24015
24015
|
};
|
|
24016
|
-
|
|
24016
|
+
status3.empty = {
|
|
24017
24017
|
204: true,
|
|
24018
24018
|
205: true,
|
|
24019
24019
|
304: true
|
|
24020
24020
|
};
|
|
24021
|
-
|
|
24021
|
+
status3.retry = {
|
|
24022
24022
|
502: true,
|
|
24023
24023
|
503: true,
|
|
24024
24024
|
504: true
|
|
@@ -24027,17 +24027,17 @@ var require_statuses4 = __commonJS({
|
|
|
24027
24027
|
var arr = [];
|
|
24028
24028
|
Object.keys(codes2).forEach(function forEachCode(code) {
|
|
24029
24029
|
var message2 = codes2[code];
|
|
24030
|
-
var
|
|
24031
|
-
statuses[
|
|
24032
|
-
statuses[message2] =
|
|
24033
|
-
statuses[message2.toLowerCase()] =
|
|
24034
|
-
arr.push(
|
|
24030
|
+
var status4 = Number(code);
|
|
24031
|
+
statuses[status4] = message2;
|
|
24032
|
+
statuses[message2] = status4;
|
|
24033
|
+
statuses[message2.toLowerCase()] = status4;
|
|
24034
|
+
arr.push(status4);
|
|
24035
24035
|
});
|
|
24036
24036
|
return arr;
|
|
24037
24037
|
}
|
|
24038
|
-
function
|
|
24038
|
+
function status3(code) {
|
|
24039
24039
|
if (typeof code === "number") {
|
|
24040
|
-
if (!
|
|
24040
|
+
if (!status3[code]) throw new Error("invalid status code: " + code);
|
|
24041
24041
|
return code;
|
|
24042
24042
|
}
|
|
24043
24043
|
if (typeof code !== "string") {
|
|
@@ -24045,10 +24045,10 @@ var require_statuses4 = __commonJS({
|
|
|
24045
24045
|
}
|
|
24046
24046
|
var n = parseInt(code, 10);
|
|
24047
24047
|
if (!isNaN(n)) {
|
|
24048
|
-
if (!
|
|
24048
|
+
if (!status3[n]) throw new Error("invalid status code: " + n);
|
|
24049
24049
|
return n;
|
|
24050
24050
|
}
|
|
24051
|
-
n =
|
|
24051
|
+
n = status3[code.toLowerCase()];
|
|
24052
24052
|
if (!n) throw new Error('invalid status message: "' + code + '"');
|
|
24053
24053
|
return n;
|
|
24054
24054
|
}
|
|
@@ -24108,19 +24108,19 @@ var require_http_errors4 = __commonJS({
|
|
|
24108
24108
|
module2.exports = createError;
|
|
24109
24109
|
module2.exports.HttpError = createHttpErrorConstructor();
|
|
24110
24110
|
populateConstructorExports(module2.exports, statuses.codes, module2.exports.HttpError);
|
|
24111
|
-
function codeClass(
|
|
24112
|
-
return Number(String(
|
|
24111
|
+
function codeClass(status3) {
|
|
24112
|
+
return Number(String(status3).charAt(0) + "00");
|
|
24113
24113
|
}
|
|
24114
24114
|
function createError() {
|
|
24115
24115
|
var err;
|
|
24116
24116
|
var msg;
|
|
24117
|
-
var
|
|
24117
|
+
var status3 = 500;
|
|
24118
24118
|
var props = {};
|
|
24119
24119
|
for (var i = 0; i < arguments.length; i++) {
|
|
24120
24120
|
var arg = arguments[i];
|
|
24121
24121
|
if (arg instanceof Error) {
|
|
24122
24122
|
err = arg;
|
|
24123
|
-
|
|
24123
|
+
status3 = err.status || err.statusCode || status3;
|
|
24124
24124
|
continue;
|
|
24125
24125
|
}
|
|
24126
24126
|
switch (typeof arg) {
|
|
@@ -24128,7 +24128,7 @@ var require_http_errors4 = __commonJS({
|
|
|
24128
24128
|
msg = arg;
|
|
24129
24129
|
break;
|
|
24130
24130
|
case "number":
|
|
24131
|
-
|
|
24131
|
+
status3 = arg;
|
|
24132
24132
|
if (i !== 0) {
|
|
24133
24133
|
deprecate2("non-first-argument status code; replace with createError(" + arg + ", ...)");
|
|
24134
24134
|
}
|
|
@@ -24138,20 +24138,20 @@ var require_http_errors4 = __commonJS({
|
|
|
24138
24138
|
break;
|
|
24139
24139
|
}
|
|
24140
24140
|
}
|
|
24141
|
-
if (typeof
|
|
24141
|
+
if (typeof status3 === "number" && (status3 < 400 || status3 >= 600)) {
|
|
24142
24142
|
deprecate2("non-error status code; use only 4xx or 5xx status codes");
|
|
24143
24143
|
}
|
|
24144
|
-
if (typeof
|
|
24145
|
-
|
|
24144
|
+
if (typeof status3 !== "number" || !statuses[status3] && (status3 < 400 || status3 >= 600)) {
|
|
24145
|
+
status3 = 500;
|
|
24146
24146
|
}
|
|
24147
|
-
var HttpError3 = createError[
|
|
24147
|
+
var HttpError3 = createError[status3] || createError[codeClass(status3)];
|
|
24148
24148
|
if (!err) {
|
|
24149
|
-
err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses[
|
|
24149
|
+
err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses[status3]);
|
|
24150
24150
|
Error.captureStackTrace(err, createError);
|
|
24151
24151
|
}
|
|
24152
|
-
if (!HttpError3 || !(err instanceof HttpError3) || err.status !==
|
|
24153
|
-
err.expose =
|
|
24154
|
-
err.status = err.statusCode =
|
|
24152
|
+
if (!HttpError3 || !(err instanceof HttpError3) || err.status !== status3) {
|
|
24153
|
+
err.expose = status3 < 500;
|
|
24154
|
+
err.status = err.statusCode = status3;
|
|
24155
24155
|
}
|
|
24156
24156
|
for (var key in props) {
|
|
24157
24157
|
if (key !== "status" && key !== "statusCode") {
|
|
@@ -24277,9 +24277,9 @@ var require_resolve_path = __commonJS({
|
|
|
24277
24277
|
"use strict";
|
|
24278
24278
|
var createError = require_http_errors4();
|
|
24279
24279
|
var join14 = require("path").join;
|
|
24280
|
-
var
|
|
24280
|
+
var normalize2 = require("path").normalize;
|
|
24281
24281
|
var pathIsAbsolute = require_path_is_absolute();
|
|
24282
|
-
var
|
|
24282
|
+
var resolve11 = require("path").resolve;
|
|
24283
24283
|
var sep = require("path").sep;
|
|
24284
24284
|
module2.exports = resolvePath;
|
|
24285
24285
|
var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
|
|
@@ -24308,10 +24308,10 @@ var require_resolve_path = __commonJS({
|
|
|
24308
24308
|
if (pathIsAbsolute.posix(path) || pathIsAbsolute.win32(path)) {
|
|
24309
24309
|
throw createError(400, "Malicious Path");
|
|
24310
24310
|
}
|
|
24311
|
-
if (UP_PATH_REGEXP.test(
|
|
24311
|
+
if (UP_PATH_REGEXP.test(normalize2("." + sep + path))) {
|
|
24312
24312
|
throw createError(403);
|
|
24313
24313
|
}
|
|
24314
|
-
return
|
|
24314
|
+
return normalize2(join14(resolve11(root), path));
|
|
24315
24315
|
}
|
|
24316
24316
|
}
|
|
24317
24317
|
});
|
|
@@ -24819,10 +24819,10 @@ var require_statuses5 = __commonJS({
|
|
|
24819
24819
|
"node_modules/koa-send/node_modules/statuses/index.js"(exports2, module2) {
|
|
24820
24820
|
"use strict";
|
|
24821
24821
|
var codes = require_codes5();
|
|
24822
|
-
module2.exports =
|
|
24823
|
-
|
|
24824
|
-
|
|
24825
|
-
|
|
24822
|
+
module2.exports = status3;
|
|
24823
|
+
status3.STATUS_CODES = codes;
|
|
24824
|
+
status3.codes = populateStatusesMap(status3, codes);
|
|
24825
|
+
status3.redirect = {
|
|
24826
24826
|
300: true,
|
|
24827
24827
|
301: true,
|
|
24828
24828
|
302: true,
|
|
@@ -24831,12 +24831,12 @@ var require_statuses5 = __commonJS({
|
|
|
24831
24831
|
307: true,
|
|
24832
24832
|
308: true
|
|
24833
24833
|
};
|
|
24834
|
-
|
|
24834
|
+
status3.empty = {
|
|
24835
24835
|
204: true,
|
|
24836
24836
|
205: true,
|
|
24837
24837
|
304: true
|
|
24838
24838
|
};
|
|
24839
|
-
|
|
24839
|
+
status3.retry = {
|
|
24840
24840
|
502: true,
|
|
24841
24841
|
503: true,
|
|
24842
24842
|
504: true
|
|
@@ -24845,17 +24845,17 @@ var require_statuses5 = __commonJS({
|
|
|
24845
24845
|
var arr = [];
|
|
24846
24846
|
Object.keys(codes2).forEach(function forEachCode(code) {
|
|
24847
24847
|
var message2 = codes2[code];
|
|
24848
|
-
var
|
|
24849
|
-
statuses[
|
|
24850
|
-
statuses[message2] =
|
|
24851
|
-
statuses[message2.toLowerCase()] =
|
|
24852
|
-
arr.push(
|
|
24848
|
+
var status4 = Number(code);
|
|
24849
|
+
statuses[status4] = message2;
|
|
24850
|
+
statuses[message2] = status4;
|
|
24851
|
+
statuses[message2.toLowerCase()] = status4;
|
|
24852
|
+
arr.push(status4);
|
|
24853
24853
|
});
|
|
24854
24854
|
return arr;
|
|
24855
24855
|
}
|
|
24856
|
-
function
|
|
24856
|
+
function status3(code) {
|
|
24857
24857
|
if (typeof code === "number") {
|
|
24858
|
-
if (!
|
|
24858
|
+
if (!status3[code]) throw new Error("invalid status code: " + code);
|
|
24859
24859
|
return code;
|
|
24860
24860
|
}
|
|
24861
24861
|
if (typeof code !== "string") {
|
|
@@ -24863,10 +24863,10 @@ var require_statuses5 = __commonJS({
|
|
|
24863
24863
|
}
|
|
24864
24864
|
var n = parseInt(code, 10);
|
|
24865
24865
|
if (!isNaN(n)) {
|
|
24866
|
-
if (!
|
|
24866
|
+
if (!status3[n]) throw new Error("invalid status code: " + n);
|
|
24867
24867
|
return n;
|
|
24868
24868
|
}
|
|
24869
|
-
n =
|
|
24869
|
+
n = status3[code.toLowerCase()];
|
|
24870
24870
|
if (!n) throw new Error('invalid status message: "' + code + '"');
|
|
24871
24871
|
return n;
|
|
24872
24872
|
}
|
|
@@ -24886,19 +24886,19 @@ var require_http_errors5 = __commonJS({
|
|
|
24886
24886
|
module2.exports.HttpError = createHttpErrorConstructor();
|
|
24887
24887
|
module2.exports.isHttpError = createIsHttpErrorFunction(module2.exports.HttpError);
|
|
24888
24888
|
populateConstructorExports(module2.exports, statuses.codes, module2.exports.HttpError);
|
|
24889
|
-
function codeClass(
|
|
24890
|
-
return Number(String(
|
|
24889
|
+
function codeClass(status3) {
|
|
24890
|
+
return Number(String(status3).charAt(0) + "00");
|
|
24891
24891
|
}
|
|
24892
24892
|
function createError() {
|
|
24893
24893
|
var err;
|
|
24894
24894
|
var msg;
|
|
24895
|
-
var
|
|
24895
|
+
var status3 = 500;
|
|
24896
24896
|
var props = {};
|
|
24897
24897
|
for (var i = 0; i < arguments.length; i++) {
|
|
24898
24898
|
var arg = arguments[i];
|
|
24899
24899
|
if (arg instanceof Error) {
|
|
24900
24900
|
err = arg;
|
|
24901
|
-
|
|
24901
|
+
status3 = err.status || err.statusCode || status3;
|
|
24902
24902
|
continue;
|
|
24903
24903
|
}
|
|
24904
24904
|
switch (typeof arg) {
|
|
@@ -24906,7 +24906,7 @@ var require_http_errors5 = __commonJS({
|
|
|
24906
24906
|
msg = arg;
|
|
24907
24907
|
break;
|
|
24908
24908
|
case "number":
|
|
24909
|
-
|
|
24909
|
+
status3 = arg;
|
|
24910
24910
|
if (i !== 0) {
|
|
24911
24911
|
deprecate2("non-first-argument status code; replace with createError(" + arg + ", ...)");
|
|
24912
24912
|
}
|
|
@@ -24916,20 +24916,20 @@ var require_http_errors5 = __commonJS({
|
|
|
24916
24916
|
break;
|
|
24917
24917
|
}
|
|
24918
24918
|
}
|
|
24919
|
-
if (typeof
|
|
24919
|
+
if (typeof status3 === "number" && (status3 < 400 || status3 >= 600)) {
|
|
24920
24920
|
deprecate2("non-error status code; use only 4xx or 5xx status codes");
|
|
24921
24921
|
}
|
|
24922
|
-
if (typeof
|
|
24923
|
-
|
|
24922
|
+
if (typeof status3 !== "number" || !statuses[status3] && (status3 < 400 || status3 >= 600)) {
|
|
24923
|
+
status3 = 500;
|
|
24924
24924
|
}
|
|
24925
|
-
var HttpError3 = createError[
|
|
24925
|
+
var HttpError3 = createError[status3] || createError[codeClass(status3)];
|
|
24926
24926
|
if (!err) {
|
|
24927
|
-
err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses[
|
|
24927
|
+
err = HttpError3 ? new HttpError3(msg) : new Error(msg || statuses[status3]);
|
|
24928
24928
|
Error.captureStackTrace(err, createError);
|
|
24929
24929
|
}
|
|
24930
|
-
if (!HttpError3 || !(err instanceof HttpError3) || err.status !==
|
|
24931
|
-
err.expose =
|
|
24932
|
-
err.status = err.statusCode =
|
|
24930
|
+
if (!HttpError3 || !(err instanceof HttpError3) || err.status !== status3) {
|
|
24931
|
+
err.expose = status3 < 500;
|
|
24932
|
+
err.status = err.statusCode = status3;
|
|
24933
24933
|
}
|
|
24934
24934
|
for (var key in props) {
|
|
24935
24935
|
if (key !== "status" && key !== "statusCode") {
|
|
@@ -25067,10 +25067,10 @@ var require_koa_send = __commonJS({
|
|
|
25067
25067
|
}
|
|
25068
25068
|
}
|
|
25069
25069
|
var {
|
|
25070
|
-
normalize,
|
|
25071
|
-
basename:
|
|
25072
|
-
extname,
|
|
25073
|
-
resolve:
|
|
25070
|
+
normalize: normalize2,
|
|
25071
|
+
basename: basename4,
|
|
25072
|
+
extname: extname2,
|
|
25073
|
+
resolve: resolve11,
|
|
25074
25074
|
parse: parse2,
|
|
25075
25075
|
sep
|
|
25076
25076
|
} = require("path");
|
|
@@ -25079,7 +25079,7 @@ var require_koa_send = __commonJS({
|
|
|
25079
25079
|
assert(ctx, "koa context required");
|
|
25080
25080
|
assert(path, "pathname required");
|
|
25081
25081
|
debug2('send "%s" %j', path, opts);
|
|
25082
|
-
const root = opts.root ?
|
|
25082
|
+
const root = opts.root ? normalize2(resolve11(opts.root)) : "";
|
|
25083
25083
|
const trailingSlash = path[path.length - 1] === "/";
|
|
25084
25084
|
path = path.substr(parse2(path).root.length);
|
|
25085
25085
|
const index = opts.index;
|
|
@@ -25111,7 +25111,7 @@ var require_koa_send = __commonJS({
|
|
|
25111
25111
|
ctx.res.removeHeader("Content-Length");
|
|
25112
25112
|
encodingExt = ".gz";
|
|
25113
25113
|
}
|
|
25114
|
-
if (extensions && !/\./.exec(
|
|
25114
|
+
if (extensions && !/\./.exec(basename4(path))) {
|
|
25115
25115
|
const list6 = [].concat(extensions);
|
|
25116
25116
|
for (let i = 0; i < list6.length; i++) {
|
|
25117
25117
|
let ext = list6[i];
|
|
@@ -25166,7 +25166,7 @@ var require_koa_send = __commonJS({
|
|
|
25166
25166
|
return false;
|
|
25167
25167
|
}
|
|
25168
25168
|
function type2(file, ext) {
|
|
25169
|
-
return ext !== "" ?
|
|
25169
|
+
return ext !== "" ? extname2(basename4(file, ext)) : extname2(file);
|
|
25170
25170
|
}
|
|
25171
25171
|
function decode(path) {
|
|
25172
25172
|
try {
|
|
@@ -25183,7 +25183,7 @@ var require_koa_static = __commonJS({
|
|
|
25183
25183
|
"node_modules/koa-static/index.js"(exports2, module2) {
|
|
25184
25184
|
"use strict";
|
|
25185
25185
|
var debug2 = require_src2()("koa-static");
|
|
25186
|
-
var { resolve:
|
|
25186
|
+
var { resolve: resolve11 } = require("path");
|
|
25187
25187
|
var assert = require("assert");
|
|
25188
25188
|
var send2 = require_koa_send();
|
|
25189
25189
|
module2.exports = serve2;
|
|
@@ -25191,7 +25191,7 @@ var require_koa_static = __commonJS({
|
|
|
25191
25191
|
opts = Object.assign({}, opts);
|
|
25192
25192
|
assert(root, "root directory is required to serve files");
|
|
25193
25193
|
debug2('static "%s" %j', root, opts);
|
|
25194
|
-
opts.root =
|
|
25194
|
+
opts.root = resolve11(root);
|
|
25195
25195
|
if (opts.index !== false) opts.index = opts.index || "index.html";
|
|
25196
25196
|
if (!opts.defer) {
|
|
25197
25197
|
return async function serve3(ctx, next) {
|
|
@@ -25877,10 +25877,10 @@ function throwWarning(state, message2) {
|
|
|
25877
25877
|
state.onWarning.call(null, generateError(state, message2));
|
|
25878
25878
|
}
|
|
25879
25879
|
}
|
|
25880
|
-
function captureSegment(state,
|
|
25880
|
+
function captureSegment(state, start4, end, checkJson) {
|
|
25881
25881
|
var _position, _length, _character, _result;
|
|
25882
|
-
if (
|
|
25883
|
-
_result = state.input.slice(
|
|
25882
|
+
if (start4 < end) {
|
|
25883
|
+
_result = state.input.slice(start4, end);
|
|
25884
25884
|
if (checkJson) {
|
|
25885
25885
|
for (_position = 0, _length = _result.length; _position < _length; _position += 1) {
|
|
25886
25886
|
_character = _result.charCodeAt(_position);
|
|
@@ -27105,22 +27105,22 @@ function foldLine(line, width) {
|
|
|
27105
27105
|
if (line === "" || line[0] === " ") return line;
|
|
27106
27106
|
var breakRe = / [^ ]/g;
|
|
27107
27107
|
var match;
|
|
27108
|
-
var
|
|
27108
|
+
var start4 = 0, end, curr = 0, next = 0;
|
|
27109
27109
|
var result = "";
|
|
27110
27110
|
while (match = breakRe.exec(line)) {
|
|
27111
27111
|
next = match.index;
|
|
27112
|
-
if (next -
|
|
27113
|
-
end = curr >
|
|
27114
|
-
result += "\n" + line.slice(
|
|
27115
|
-
|
|
27112
|
+
if (next - start4 > width) {
|
|
27113
|
+
end = curr > start4 ? curr : next;
|
|
27114
|
+
result += "\n" + line.slice(start4, end);
|
|
27115
|
+
start4 = end + 1;
|
|
27116
27116
|
}
|
|
27117
27117
|
curr = next;
|
|
27118
27118
|
}
|
|
27119
27119
|
result += "\n";
|
|
27120
|
-
if (line.length -
|
|
27121
|
-
result += line.slice(
|
|
27120
|
+
if (line.length - start4 > width && curr > start4) {
|
|
27121
|
+
result += line.slice(start4, curr) + "\n" + line.slice(curr + 1);
|
|
27122
27122
|
} else {
|
|
27123
|
-
result += line.slice(
|
|
27123
|
+
result += line.slice(start4);
|
|
27124
27124
|
}
|
|
27125
27125
|
return result.slice(1);
|
|
27126
27126
|
}
|
|
@@ -28593,7 +28593,7 @@ var require_redact = __commonJS({
|
|
|
28593
28593
|
}
|
|
28594
28594
|
return cloneSelectively(obj, pathStructure);
|
|
28595
28595
|
}
|
|
28596
|
-
function
|
|
28596
|
+
function validatePath2(path) {
|
|
28597
28597
|
if (typeof path !== "string") {
|
|
28598
28598
|
throw new Error("Paths must be (non-empty) strings");
|
|
28599
28599
|
}
|
|
@@ -28637,7 +28637,7 @@ var require_redact = __commonJS({
|
|
|
28637
28637
|
throw new TypeError("paths must be an array");
|
|
28638
28638
|
}
|
|
28639
28639
|
for (const path of paths) {
|
|
28640
|
-
|
|
28640
|
+
validatePath2(path);
|
|
28641
28641
|
}
|
|
28642
28642
|
}
|
|
28643
28643
|
function slowRedact(options = {}) {
|
|
@@ -29101,7 +29101,7 @@ var require_sonic_boom = __commonJS({
|
|
|
29101
29101
|
if (!(this instanceof SonicBoom)) {
|
|
29102
29102
|
return new SonicBoom(opts);
|
|
29103
29103
|
}
|
|
29104
|
-
let { fd, dest, minLength, maxLength, maxWrite, periodicFlush, sync, append: append2 = true, mkdir:
|
|
29104
|
+
let { fd, dest, minLength, maxLength, maxWrite, periodicFlush, sync, append: append2 = true, mkdir: mkdir6, retryEAGAIN, fsync, contentMode, mode } = opts || {};
|
|
29105
29105
|
fd = fd || dest;
|
|
29106
29106
|
this._len = 0;
|
|
29107
29107
|
this.fd = -1;
|
|
@@ -29126,7 +29126,7 @@ var require_sonic_boom = __commonJS({
|
|
|
29126
29126
|
this.append = append2 || false;
|
|
29127
29127
|
this.mode = mode;
|
|
29128
29128
|
this.retryEAGAIN = retryEAGAIN || (() => true);
|
|
29129
|
-
this.mkdir =
|
|
29129
|
+
this.mkdir = mkdir6 || false;
|
|
29130
29130
|
let fsWriteSync;
|
|
29131
29131
|
let fsWrite;
|
|
29132
29132
|
if (contentMode === kContentModeBuffer) {
|
|
@@ -30257,9 +30257,9 @@ var require_transport = __commonJS({
|
|
|
30257
30257
|
"node_modules/pino/lib/transport.js"(exports2, module2) {
|
|
30258
30258
|
"use strict";
|
|
30259
30259
|
var { createRequire } = require("module");
|
|
30260
|
-
var { existsSync:
|
|
30260
|
+
var { existsSync: existsSync16 } = require("node:fs");
|
|
30261
30261
|
var getCallers = require_caller();
|
|
30262
|
-
var { join: join14, isAbsolute, sep } = require("node:path");
|
|
30262
|
+
var { join: join14, isAbsolute: isAbsolute2, sep } = require("node:path");
|
|
30263
30263
|
var { fileURLToPath } = require("node:url");
|
|
30264
30264
|
var sleep = require_atomic_sleep();
|
|
30265
30265
|
var onExit = require_on_exit_leak_free();
|
|
@@ -30331,7 +30331,7 @@ var require_transport = __commonJS({
|
|
|
30331
30331
|
return false;
|
|
30332
30332
|
}
|
|
30333
30333
|
}
|
|
30334
|
-
return
|
|
30334
|
+
return isAbsolute2(path) && !existsSync16(path);
|
|
30335
30335
|
}
|
|
30336
30336
|
function stripQuotes(value) {
|
|
30337
30337
|
const first = value[0];
|
|
@@ -30449,7 +30449,7 @@ var require_transport = __commonJS({
|
|
|
30449
30449
|
return buildStream(fixTarget(target), options, worker, sync, name);
|
|
30450
30450
|
function fixTarget(origin2) {
|
|
30451
30451
|
origin2 = bundlerOverrides[origin2] || origin2;
|
|
30452
|
-
if (
|
|
30452
|
+
if (isAbsolute2(origin2) || origin2.indexOf("file://") === 0) {
|
|
30453
30453
|
return origin2;
|
|
30454
30454
|
}
|
|
30455
30455
|
if (origin2 === "pino/file") {
|
|
@@ -32106,11 +32106,11 @@ var require_pino = __commonJS({
|
|
|
32106
32106
|
depthLimit: 5,
|
|
32107
32107
|
edgeLimit: 100
|
|
32108
32108
|
};
|
|
32109
|
-
var
|
|
32109
|
+
var normalize2 = createArgsNormalizer(defaultOptions);
|
|
32110
32110
|
var serializers = Object.assign(/* @__PURE__ */ Object.create(null), stdSerializers);
|
|
32111
32111
|
function pino2(...args2) {
|
|
32112
32112
|
const instance = {};
|
|
32113
|
-
const { opts, stream: stream4 } =
|
|
32113
|
+
const { opts, stream: stream4 } = normalize2(instance, caller(), ...args2);
|
|
32114
32114
|
if (opts.level && typeof opts.level === "string" && DEFAULT_LEVELS[opts.level.toLowerCase()] !== void 0) opts.level = opts.level.toLowerCase();
|
|
32115
32115
|
const {
|
|
32116
32116
|
redact,
|
|
@@ -32365,22 +32365,22 @@ var init_gateway_manager = __esm({
|
|
|
32365
32365
|
/** 尝试绑定端口,检测端口是否被系统级进程占用 */
|
|
32366
32366
|
checkPortAvailable(port, host) {
|
|
32367
32367
|
if (port < 0 || port > 65535) return Promise.resolve(false);
|
|
32368
|
-
return new Promise((
|
|
32368
|
+
return new Promise((resolve11) => {
|
|
32369
32369
|
const server2 = (0, import_net.createServer)();
|
|
32370
32370
|
server2.once("error", () => {
|
|
32371
32371
|
server2.close();
|
|
32372
|
-
|
|
32372
|
+
resolve11(false);
|
|
32373
32373
|
});
|
|
32374
32374
|
server2.once("listening", () => {
|
|
32375
32375
|
server2.close();
|
|
32376
|
-
|
|
32376
|
+
resolve11(true);
|
|
32377
32377
|
});
|
|
32378
32378
|
server2.listen(port, host);
|
|
32379
32379
|
});
|
|
32380
32380
|
}
|
|
32381
32381
|
/** 从 base 端口开始递增查找空闲端口(上限 65535) */
|
|
32382
32382
|
findFreePort(base, host = "127.0.0.1") {
|
|
32383
|
-
return new Promise((
|
|
32383
|
+
return new Promise((resolve11, reject) => {
|
|
32384
32384
|
const tryPort = (port) => {
|
|
32385
32385
|
if (port > 65535) {
|
|
32386
32386
|
reject(new Error(`No free port found in range ${base}-65535`));
|
|
@@ -32393,7 +32393,7 @@ var init_gateway_manager = __esm({
|
|
|
32393
32393
|
});
|
|
32394
32394
|
server2.once("listening", () => {
|
|
32395
32395
|
server2.close();
|
|
32396
|
-
|
|
32396
|
+
resolve11(port);
|
|
32397
32397
|
});
|
|
32398
32398
|
server2.listen(port, host);
|
|
32399
32399
|
};
|
|
@@ -32574,7 +32574,7 @@ var init_gateway_manager = __esm({
|
|
|
32574
32574
|
const hermesHome = this.profileDir(name);
|
|
32575
32575
|
const url2 = `http://${host}:${port}`;
|
|
32576
32576
|
if (needsRunMode) {
|
|
32577
|
-
return new Promise((
|
|
32577
|
+
return new Promise((resolve11, reject) => {
|
|
32578
32578
|
const env2 = { ...process.env, HERMES_HOME: hermesHome };
|
|
32579
32579
|
const child = (0, import_child_process.spawn)(HERMES_BIN, ["gateway", "run", "--replace"], {
|
|
32580
32580
|
detached: true,
|
|
@@ -32585,7 +32585,7 @@ var init_gateway_manager = __esm({
|
|
|
32585
32585
|
child.unref();
|
|
32586
32586
|
const pid = child.pid ?? 0;
|
|
32587
32587
|
logger.info('Starting gateway for profile "%s" (run mode, PID: %d, port: %d)', name, pid, port);
|
|
32588
|
-
this.waitForReady(name, pid, port, host, url2).then(
|
|
32588
|
+
this.waitForReady(name, pid, port, host, url2).then(resolve11).catch(reject);
|
|
32589
32589
|
});
|
|
32590
32590
|
}
|
|
32591
32591
|
logger.info('Starting gateway for profile "%s" (start mode, port: %d)', name, port);
|
|
@@ -32690,9 +32690,9 @@ var init_gateway_manager = __esm({
|
|
|
32690
32690
|
logger.info("Scanning profiles for running gateways...");
|
|
32691
32691
|
const profiles = await this.listProfiles();
|
|
32692
32692
|
for (const name of profiles) {
|
|
32693
|
-
const
|
|
32694
|
-
if (
|
|
32695
|
-
logger.info("%s: running (PID: %s, port: %d)", name,
|
|
32693
|
+
const status3 = await this.detectStatus(name);
|
|
32694
|
+
if (status3.running) {
|
|
32695
|
+
logger.info("%s: running (PID: %s, port: %d)", name, status3.pid, status3.port);
|
|
32696
32696
|
} else {
|
|
32697
32697
|
logger.debug("%s: stopped", name);
|
|
32698
32698
|
}
|
|
@@ -34852,7 +34852,7 @@ var require_extension = __commonJS({
|
|
|
34852
34852
|
let inQuotes = false;
|
|
34853
34853
|
let extensionName;
|
|
34854
34854
|
let paramName;
|
|
34855
|
-
let
|
|
34855
|
+
let start4 = -1;
|
|
34856
34856
|
let code = -1;
|
|
34857
34857
|
let end = -1;
|
|
34858
34858
|
let i = 0;
|
|
@@ -34860,45 +34860,45 @@ var require_extension = __commonJS({
|
|
|
34860
34860
|
code = header.charCodeAt(i);
|
|
34861
34861
|
if (extensionName === void 0) {
|
|
34862
34862
|
if (end === -1 && tokenChars[code] === 1) {
|
|
34863
|
-
if (
|
|
34863
|
+
if (start4 === -1) start4 = i;
|
|
34864
34864
|
} else if (i !== 0 && (code === 32 || code === 9)) {
|
|
34865
|
-
if (end === -1 &&
|
|
34865
|
+
if (end === -1 && start4 !== -1) end = i;
|
|
34866
34866
|
} else if (code === 59 || code === 44) {
|
|
34867
|
-
if (
|
|
34867
|
+
if (start4 === -1) {
|
|
34868
34868
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
34869
34869
|
}
|
|
34870
34870
|
if (end === -1) end = i;
|
|
34871
|
-
const name = header.slice(
|
|
34871
|
+
const name = header.slice(start4, end);
|
|
34872
34872
|
if (code === 44) {
|
|
34873
34873
|
push(offers, name, params);
|
|
34874
34874
|
params = /* @__PURE__ */ Object.create(null);
|
|
34875
34875
|
} else {
|
|
34876
34876
|
extensionName = name;
|
|
34877
34877
|
}
|
|
34878
|
-
|
|
34878
|
+
start4 = end = -1;
|
|
34879
34879
|
} else {
|
|
34880
34880
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
34881
34881
|
}
|
|
34882
34882
|
} else if (paramName === void 0) {
|
|
34883
34883
|
if (end === -1 && tokenChars[code] === 1) {
|
|
34884
|
-
if (
|
|
34884
|
+
if (start4 === -1) start4 = i;
|
|
34885
34885
|
} else if (code === 32 || code === 9) {
|
|
34886
|
-
if (end === -1 &&
|
|
34886
|
+
if (end === -1 && start4 !== -1) end = i;
|
|
34887
34887
|
} else if (code === 59 || code === 44) {
|
|
34888
|
-
if (
|
|
34888
|
+
if (start4 === -1) {
|
|
34889
34889
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
34890
34890
|
}
|
|
34891
34891
|
if (end === -1) end = i;
|
|
34892
|
-
push(params, header.slice(
|
|
34892
|
+
push(params, header.slice(start4, end), true);
|
|
34893
34893
|
if (code === 44) {
|
|
34894
34894
|
push(offers, extensionName, params);
|
|
34895
34895
|
params = /* @__PURE__ */ Object.create(null);
|
|
34896
34896
|
extensionName = void 0;
|
|
34897
34897
|
}
|
|
34898
|
-
|
|
34899
|
-
} else if (code === 61 &&
|
|
34900
|
-
paramName = header.slice(
|
|
34901
|
-
|
|
34898
|
+
start4 = end = -1;
|
|
34899
|
+
} else if (code === 61 && start4 !== -1 && end === -1) {
|
|
34900
|
+
paramName = header.slice(start4, i);
|
|
34901
|
+
start4 = end = -1;
|
|
34902
34902
|
} else {
|
|
34903
34903
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
34904
34904
|
}
|
|
@@ -34907,13 +34907,13 @@ var require_extension = __commonJS({
|
|
|
34907
34907
|
if (tokenChars[code] !== 1) {
|
|
34908
34908
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
34909
34909
|
}
|
|
34910
|
-
if (
|
|
34910
|
+
if (start4 === -1) start4 = i;
|
|
34911
34911
|
else if (!mustUnescape) mustUnescape = true;
|
|
34912
34912
|
isEscaping = false;
|
|
34913
34913
|
} else if (inQuotes) {
|
|
34914
34914
|
if (tokenChars[code] === 1) {
|
|
34915
|
-
if (
|
|
34916
|
-
} else if (code === 34 &&
|
|
34915
|
+
if (start4 === -1) start4 = i;
|
|
34916
|
+
} else if (code === 34 && start4 !== -1) {
|
|
34917
34917
|
inQuotes = false;
|
|
34918
34918
|
end = i;
|
|
34919
34919
|
} else if (code === 92) {
|
|
@@ -34924,15 +34924,15 @@ var require_extension = __commonJS({
|
|
|
34924
34924
|
} else if (code === 34 && header.charCodeAt(i - 1) === 61) {
|
|
34925
34925
|
inQuotes = true;
|
|
34926
34926
|
} else if (end === -1 && tokenChars[code] === 1) {
|
|
34927
|
-
if (
|
|
34928
|
-
} else if (
|
|
34927
|
+
if (start4 === -1) start4 = i;
|
|
34928
|
+
} else if (start4 !== -1 && (code === 32 || code === 9)) {
|
|
34929
34929
|
if (end === -1) end = i;
|
|
34930
34930
|
} else if (code === 59 || code === 44) {
|
|
34931
|
-
if (
|
|
34931
|
+
if (start4 === -1) {
|
|
34932
34932
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
34933
34933
|
}
|
|
34934
34934
|
if (end === -1) end = i;
|
|
34935
|
-
let value = header.slice(
|
|
34935
|
+
let value = header.slice(start4, end);
|
|
34936
34936
|
if (mustUnescape) {
|
|
34937
34937
|
value = value.replace(/\\/g, "");
|
|
34938
34938
|
mustUnescape = false;
|
|
@@ -34944,17 +34944,17 @@ var require_extension = __commonJS({
|
|
|
34944
34944
|
extensionName = void 0;
|
|
34945
34945
|
}
|
|
34946
34946
|
paramName = void 0;
|
|
34947
|
-
|
|
34947
|
+
start4 = end = -1;
|
|
34948
34948
|
} else {
|
|
34949
34949
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
34950
34950
|
}
|
|
34951
34951
|
}
|
|
34952
34952
|
}
|
|
34953
|
-
if (
|
|
34953
|
+
if (start4 === -1 || inQuotes || code === 32 || code === 9) {
|
|
34954
34954
|
throw new SyntaxError("Unexpected end of input");
|
|
34955
34955
|
}
|
|
34956
34956
|
if (end === -1) end = i;
|
|
34957
|
-
const token = header.slice(
|
|
34957
|
+
const token = header.slice(start4, end);
|
|
34958
34958
|
if (extensionName === void 0) {
|
|
34959
34959
|
push(offers, token, params);
|
|
34960
34960
|
} else {
|
|
@@ -35979,34 +35979,34 @@ var require_subprotocol = __commonJS({
|
|
|
35979
35979
|
var { tokenChars } = require_validation();
|
|
35980
35980
|
function parse2(header) {
|
|
35981
35981
|
const protocols = /* @__PURE__ */ new Set();
|
|
35982
|
-
let
|
|
35982
|
+
let start4 = -1;
|
|
35983
35983
|
let end = -1;
|
|
35984
35984
|
let i = 0;
|
|
35985
35985
|
for (i; i < header.length; i++) {
|
|
35986
35986
|
const code = header.charCodeAt(i);
|
|
35987
35987
|
if (end === -1 && tokenChars[code] === 1) {
|
|
35988
|
-
if (
|
|
35988
|
+
if (start4 === -1) start4 = i;
|
|
35989
35989
|
} else if (i !== 0 && (code === 32 || code === 9)) {
|
|
35990
|
-
if (end === -1 &&
|
|
35990
|
+
if (end === -1 && start4 !== -1) end = i;
|
|
35991
35991
|
} else if (code === 44) {
|
|
35992
|
-
if (
|
|
35992
|
+
if (start4 === -1) {
|
|
35993
35993
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
35994
35994
|
}
|
|
35995
35995
|
if (end === -1) end = i;
|
|
35996
|
-
const protocol2 = header.slice(
|
|
35996
|
+
const protocol2 = header.slice(start4, end);
|
|
35997
35997
|
if (protocols.has(protocol2)) {
|
|
35998
35998
|
throw new SyntaxError(`The "${protocol2}" subprotocol is duplicated`);
|
|
35999
35999
|
}
|
|
36000
36000
|
protocols.add(protocol2);
|
|
36001
|
-
|
|
36001
|
+
start4 = end = -1;
|
|
36002
36002
|
} else {
|
|
36003
36003
|
throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
36004
36004
|
}
|
|
36005
36005
|
}
|
|
36006
|
-
if (
|
|
36006
|
+
if (start4 === -1 || end !== -1) {
|
|
36007
36007
|
throw new SyntaxError("Unexpected end of input");
|
|
36008
36008
|
}
|
|
36009
|
-
const protocol = header.slice(
|
|
36009
|
+
const protocol = header.slice(start4, i);
|
|
36010
36010
|
if (protocols.has(protocol)) {
|
|
36011
36011
|
throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`);
|
|
36012
36012
|
}
|
|
@@ -38365,10 +38365,10 @@ function bindShutdown(server2) {
|
|
|
38365
38365
|
logger.info("Shutting down (%s)...", signal);
|
|
38366
38366
|
try {
|
|
38367
38367
|
if (server2) {
|
|
38368
|
-
await new Promise((
|
|
38368
|
+
await new Promise((resolve11) => {
|
|
38369
38369
|
server2.close(() => {
|
|
38370
38370
|
logger.info("HTTP server closed");
|
|
38371
|
-
|
|
38371
|
+
resolve11();
|
|
38372
38372
|
});
|
|
38373
38373
|
});
|
|
38374
38374
|
}
|
|
@@ -40217,15 +40217,15 @@ function resolveHermesBin() {
|
|
|
40217
40217
|
var HERMES_BIN2 = resolveHermesBin();
|
|
40218
40218
|
function parseSessionExport(stdout) {
|
|
40219
40219
|
const lines = stdout.trim().split("\n").filter(Boolean);
|
|
40220
|
-
const
|
|
40220
|
+
const sessions3 = [];
|
|
40221
40221
|
for (const line of lines) {
|
|
40222
40222
|
try {
|
|
40223
40223
|
const raw = JSON.parse(line);
|
|
40224
|
-
|
|
40224
|
+
sessions3.push(raw);
|
|
40225
40225
|
} catch {
|
|
40226
40226
|
}
|
|
40227
40227
|
}
|
|
40228
|
-
return
|
|
40228
|
+
return sessions3;
|
|
40229
40229
|
}
|
|
40230
40230
|
async function exportSessionsRaw(source) {
|
|
40231
40231
|
const args2 = ["sessions", "export", "-"];
|
|
@@ -40245,7 +40245,7 @@ async function exportSessionsRaw(source) {
|
|
|
40245
40245
|
}
|
|
40246
40246
|
async function listSessions(source, limit) {
|
|
40247
40247
|
const raws = await exportSessionsRaw(source);
|
|
40248
|
-
const
|
|
40248
|
+
const sessions3 = [];
|
|
40249
40249
|
for (const raw of raws) {
|
|
40250
40250
|
let title = raw.title;
|
|
40251
40251
|
if (!title && raw.messages) {
|
|
@@ -40255,7 +40255,7 @@ async function listSessions(source, limit) {
|
|
|
40255
40255
|
title = t + (String(firstUser.content).length > 40 ? "..." : "");
|
|
40256
40256
|
}
|
|
40257
40257
|
}
|
|
40258
|
-
|
|
40258
|
+
sessions3.push({
|
|
40259
40259
|
id: raw.id,
|
|
40260
40260
|
source: raw.source,
|
|
40261
40261
|
user_id: raw.user_id,
|
|
@@ -40277,11 +40277,11 @@ async function listSessions(source, limit) {
|
|
|
40277
40277
|
cost_status: raw.cost_status || ""
|
|
40278
40278
|
});
|
|
40279
40279
|
}
|
|
40280
|
-
|
|
40280
|
+
sessions3.sort((a, b) => b.started_at - a.started_at);
|
|
40281
40281
|
if (limit && limit > 0) {
|
|
40282
|
-
return
|
|
40282
|
+
return sessions3.slice(0, limit);
|
|
40283
40283
|
}
|
|
40284
|
-
return
|
|
40284
|
+
return sessions3;
|
|
40285
40285
|
}
|
|
40286
40286
|
async function getSession(id) {
|
|
40287
40287
|
const args2 = ["sessions", "export", "-", "--session-id", id];
|
|
@@ -40590,11 +40590,11 @@ async function importProfile(archivePath, name) {
|
|
|
40590
40590
|
}
|
|
40591
40591
|
|
|
40592
40592
|
// packages/server/src/controllers/health.ts
|
|
40593
|
-
var LOCAL_VERSION = true ? "0.4.
|
|
40593
|
+
var LOCAL_VERSION = true ? "0.4.4" : (() => {
|
|
40594
40594
|
try {
|
|
40595
|
-
const { readFileSync:
|
|
40596
|
-
const { resolve:
|
|
40597
|
-
return JSON.parse(
|
|
40595
|
+
const { readFileSync: readFileSync12 } = null;
|
|
40596
|
+
const { resolve: resolve11 } = null;
|
|
40597
|
+
return JSON.parse(readFileSync12(resolve11(__dirname, "../../package.json"), "utf-8")).version;
|
|
40598
40598
|
} catch {
|
|
40599
40599
|
return "0.0.0";
|
|
40600
40600
|
}
|
|
@@ -40602,8 +40602,8 @@ var LOCAL_VERSION = true ? "0.4.3" : (() => {
|
|
|
40602
40602
|
var cachedLatestVersion = "";
|
|
40603
40603
|
async function checkLatestVersion() {
|
|
40604
40604
|
try {
|
|
40605
|
-
const { readFileSync:
|
|
40606
|
-
const pkg = JSON.parse(
|
|
40605
|
+
const { readFileSync: readFileSync12 } = require("fs");
|
|
40606
|
+
const pkg = JSON.parse(readFileSync12(resolve6(require("path").join(__dirname, "../../package.json")), "utf-8"));
|
|
40607
40607
|
const name = pkg.name;
|
|
40608
40608
|
const res = await fetch(`https://registry.npmjs.org/${name}/latest`, { signal: AbortSignal.timeout(1e4) });
|
|
40609
40609
|
if (res.ok) {
|
|
@@ -40638,7 +40638,8 @@ async function healthCheck(ctx) {
|
|
|
40638
40638
|
gateway: gatewayOk ? "running" : "stopped",
|
|
40639
40639
|
webui_version: LOCAL_VERSION,
|
|
40640
40640
|
webui_latest: cachedLatestVersion,
|
|
40641
|
-
webui_update_available: cachedLatestVersion && cachedLatestVersion !== LOCAL_VERSION
|
|
40641
|
+
webui_update_available: cachedLatestVersion && cachedLatestVersion !== LOCAL_VERSION,
|
|
40642
|
+
node_version: process.versions.node
|
|
40642
40643
|
};
|
|
40643
40644
|
}
|
|
40644
40645
|
function resolve6(p) {
|
|
@@ -40813,14 +40814,14 @@ async function handleUpload(ctx) {
|
|
|
40813
40814
|
}
|
|
40814
40815
|
function splitMultipart(raw, boundary) {
|
|
40815
40816
|
const parts = [];
|
|
40816
|
-
let
|
|
40817
|
+
let start4 = 0;
|
|
40817
40818
|
while (true) {
|
|
40818
|
-
const idx = raw.indexOf(boundary,
|
|
40819
|
+
const idx = raw.indexOf(boundary, start4);
|
|
40819
40820
|
if (idx === -1) break;
|
|
40820
|
-
if (
|
|
40821
|
-
parts.push(raw.subarray(
|
|
40821
|
+
if (start4 > 0) {
|
|
40822
|
+
parts.push(raw.subarray(start4 + 2, idx));
|
|
40822
40823
|
}
|
|
40823
|
-
|
|
40824
|
+
start4 = idx + boundary.length;
|
|
40824
40825
|
}
|
|
40825
40826
|
return parts;
|
|
40826
40827
|
}
|
|
@@ -41223,14 +41224,14 @@ function normalizeVisibleMessage(message2, session, index) {
|
|
|
41223
41224
|
timestamp: timestamp2
|
|
41224
41225
|
};
|
|
41225
41226
|
}
|
|
41226
|
-
function visibleMessagesForSessions(
|
|
41227
|
-
return
|
|
41227
|
+
function visibleMessagesForSessions(sessions3) {
|
|
41228
|
+
return sessions3.flatMap((session) => sessionMessages(session).map((message2, index) => normalizeVisibleMessage({ ...message2, session_id: safeText(message2.session_id || session.id) }, session, index))).filter((message2) => !!message2).sort((a, b) => {
|
|
41228
41229
|
if (a.timestamp !== b.timestamp) return a.timestamp - b.timestamp;
|
|
41229
41230
|
return String(a.id).localeCompare(String(b.id));
|
|
41230
41231
|
});
|
|
41231
41232
|
}
|
|
41232
|
-
function hasVisibleHumanMessages(
|
|
41233
|
-
return visibleMessagesForSessions(
|
|
41233
|
+
function hasVisibleHumanMessages(sessions3) {
|
|
41234
|
+
return visibleMessagesForSessions(sessions3).length > 0;
|
|
41234
41235
|
}
|
|
41235
41236
|
function toSummary(session) {
|
|
41236
41237
|
return {
|
|
@@ -41308,10 +41309,10 @@ async function loadSessions(source) {
|
|
|
41308
41309
|
async function listConversationSummaries(options = {}) {
|
|
41309
41310
|
const humanOnly = options.humanOnly !== false;
|
|
41310
41311
|
const limit = options.limit && options.limit > 0 ? options.limit : DEFAULT_CONVERSATION_LIMIT;
|
|
41311
|
-
const
|
|
41312
|
-
const byId = new Map(
|
|
41312
|
+
const sessions3 = await loadSessions(options.source);
|
|
41313
|
+
const byId = new Map(sessions3.map((session) => [session.id, session]));
|
|
41313
41314
|
const childrenByParent = /* @__PURE__ */ new Map();
|
|
41314
|
-
for (const session of
|
|
41315
|
+
for (const session of sessions3) {
|
|
41315
41316
|
const key = session.parent_session_id ?? null;
|
|
41316
41317
|
const siblings = childrenByParent.get(key) || [];
|
|
41317
41318
|
siblings.push(session.id);
|
|
@@ -41319,18 +41320,18 @@ async function listConversationSummaries(options = {}) {
|
|
|
41319
41320
|
}
|
|
41320
41321
|
if (!humanOnly) {
|
|
41321
41322
|
return sortByRecency(
|
|
41322
|
-
|
|
41323
|
+
sessions3.filter((session) => session.source !== "tool").map(toSummary)
|
|
41323
41324
|
).slice(0, limit);
|
|
41324
41325
|
}
|
|
41325
|
-
const summaries =
|
|
41326
|
+
const summaries = sessions3.filter((session) => isVisibleRoot(session, byId)).map((session) => aggregateSummary(session.id, byId, childrenByParent)).filter((summary) => !!summary);
|
|
41326
41327
|
return sortByRecency(summaries).slice(0, limit);
|
|
41327
41328
|
}
|
|
41328
41329
|
async function getConversationDetail(sessionId, options = {}) {
|
|
41329
41330
|
const humanOnly = options.humanOnly !== false;
|
|
41330
|
-
const
|
|
41331
|
-
const byId = new Map(
|
|
41331
|
+
const sessions3 = await loadSessions(options.source);
|
|
41332
|
+
const byId = new Map(sessions3.map((session) => [session.id, session]));
|
|
41332
41333
|
const childrenByParent = /* @__PURE__ */ new Map();
|
|
41333
|
-
for (const session of
|
|
41334
|
+
for (const session of sessions3) {
|
|
41334
41335
|
const key = session.parent_session_id ?? null;
|
|
41335
41336
|
const siblings = childrenByParent.get(key) || [];
|
|
41336
41337
|
siblings.push(session.id);
|
|
@@ -41360,13 +41361,34 @@ async function getConversationDetail(sessionId, options = {}) {
|
|
|
41360
41361
|
};
|
|
41361
41362
|
}
|
|
41362
41363
|
|
|
41363
|
-
// packages/server/src/db/hermes/
|
|
41364
|
+
// packages/server/src/db/hermes/conversations-db.ts
|
|
41364
41365
|
init_hermes_profile();
|
|
41365
41366
|
var SQLITE_AVAILABLE2 = (() => {
|
|
41366
41367
|
const [major, minor] = process.versions.node.split(".").map(Number);
|
|
41367
41368
|
return major > 22 || major === 22 && minor >= 5;
|
|
41368
41369
|
})();
|
|
41369
|
-
|
|
41370
|
+
var LINEAGE_TOLERANCE_SECONDS2 = 3;
|
|
41371
|
+
var LIVE_WINDOW_SECONDS2 = 300;
|
|
41372
|
+
var DEFAULT_CONVERSATION_LIMIT2 = 200;
|
|
41373
|
+
var SYNTHETIC_USER_PREFIXES2 = [
|
|
41374
|
+
"[system:",
|
|
41375
|
+
"you've reached the maximum number of tool-calling iterations allowed.",
|
|
41376
|
+
"you have reached the maximum number of tool-calling iterations allowed."
|
|
41377
|
+
];
|
|
41378
|
+
var VISIBLE_HUMAN_MESSAGE_SQL = `
|
|
41379
|
+
m.content IS NOT NULL
|
|
41380
|
+
AND m.content != ''
|
|
41381
|
+
AND (
|
|
41382
|
+
m.role = 'assistant'
|
|
41383
|
+
OR (
|
|
41384
|
+
m.role = 'user'
|
|
41385
|
+
AND LOWER(m.content) NOT LIKE '[system:%'
|
|
41386
|
+
AND LOWER(m.content) NOT LIKE 'you''ve reached the maximum number of tool-calling iterations allowed.%'
|
|
41387
|
+
AND LOWER(m.content) NOT LIKE 'you have reached the maximum number of tool-calling iterations allowed.%'
|
|
41388
|
+
)
|
|
41389
|
+
)
|
|
41390
|
+
`;
|
|
41391
|
+
function conversationDbPath() {
|
|
41370
41392
|
return `${getActiveProfileDir()}/state.db`;
|
|
41371
41393
|
}
|
|
41372
41394
|
function normalizeNumber(value, fallback = 0) {
|
|
@@ -41383,19 +41405,80 @@ function normalizeNullableString(value) {
|
|
|
41383
41405
|
if (value == null || value === "") return null;
|
|
41384
41406
|
return String(value);
|
|
41385
41407
|
}
|
|
41386
|
-
function
|
|
41408
|
+
function safeText2(value) {
|
|
41409
|
+
if (typeof value === "string") return value;
|
|
41410
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
41411
|
+
return "";
|
|
41412
|
+
}
|
|
41413
|
+
function textFromContent2(value) {
|
|
41414
|
+
if (typeof value === "string") {
|
|
41415
|
+
const trimmed = value.trim();
|
|
41416
|
+
if (trimmed && (trimmed.startsWith("{") || trimmed.startsWith("["))) {
|
|
41417
|
+
try {
|
|
41418
|
+
const parsed = JSON.parse(trimmed);
|
|
41419
|
+
const nested = textFromContent2(parsed);
|
|
41420
|
+
if (nested) return nested;
|
|
41421
|
+
} catch {
|
|
41422
|
+
}
|
|
41423
|
+
}
|
|
41424
|
+
return value;
|
|
41425
|
+
}
|
|
41426
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
41427
|
+
if (Array.isArray(value)) {
|
|
41428
|
+
return value.map((item) => textFromContent2(item).trim()).filter(Boolean).join("\n");
|
|
41429
|
+
}
|
|
41430
|
+
if (!value || typeof value !== "object") return "";
|
|
41431
|
+
const record = value;
|
|
41432
|
+
for (const key of ["text", "content", "value"]) {
|
|
41433
|
+
const direct = record[key];
|
|
41434
|
+
if (typeof direct === "string") return direct;
|
|
41435
|
+
if (Array.isArray(direct)) {
|
|
41436
|
+
const nested = textFromContent2(direct);
|
|
41437
|
+
if (nested) return nested;
|
|
41438
|
+
}
|
|
41439
|
+
}
|
|
41440
|
+
for (const key of ["parts", "children", "items"]) {
|
|
41441
|
+
if (Array.isArray(record[key])) {
|
|
41442
|
+
const nested = textFromContent2(record[key]);
|
|
41443
|
+
if (nested) return nested;
|
|
41444
|
+
}
|
|
41445
|
+
}
|
|
41446
|
+
const flattened = Object.values(record).map((entry) => textFromContent2(entry).trim()).filter(Boolean).join("\n");
|
|
41447
|
+
if (flattened) return flattened;
|
|
41448
|
+
try {
|
|
41449
|
+
return JSON.stringify(record);
|
|
41450
|
+
} catch {
|
|
41451
|
+
return "";
|
|
41452
|
+
}
|
|
41453
|
+
}
|
|
41454
|
+
function normalizeText2(value) {
|
|
41455
|
+
return textFromContent2(value).replace(/\s+/g, " ").trim().toLowerCase();
|
|
41456
|
+
}
|
|
41457
|
+
function excerpt2(value, width = 80) {
|
|
41458
|
+
const text = textFromContent2(value).replace(/\s+/g, " ").trim();
|
|
41459
|
+
if (!text) return "";
|
|
41460
|
+
return text.length > width ? `${text.slice(0, width)}\u2026` : text;
|
|
41461
|
+
}
|
|
41462
|
+
function isSyntheticUserText2(content) {
|
|
41463
|
+
const text = normalizeText2(content);
|
|
41464
|
+
return SYNTHETIC_USER_PREFIXES2.some((prefix) => text.startsWith(prefix));
|
|
41465
|
+
}
|
|
41466
|
+
function mapSessionRow(row, nowSeconds) {
|
|
41387
41467
|
const startedAt = normalizeNumber(row.started_at);
|
|
41468
|
+
const endedAt = normalizeNullableNumber(row.ended_at);
|
|
41469
|
+
const preview = excerpt2(row.preview || "");
|
|
41388
41470
|
const rawTitle = normalizeNullableString(row.title);
|
|
41389
|
-
const
|
|
41390
|
-
const
|
|
41471
|
+
const title = rawTitle || (preview ? preview.length > 40 ? `${preview.slice(0, 40)}...` : preview : null);
|
|
41472
|
+
const lastActive = normalizeNumber(row.last_active, startedAt);
|
|
41391
41473
|
return {
|
|
41392
41474
|
id: String(row.id || ""),
|
|
41393
41475
|
source: String(row.source || ""),
|
|
41394
41476
|
user_id: normalizeNullableString(row.user_id),
|
|
41395
41477
|
model: String(row.model || ""),
|
|
41396
41478
|
title,
|
|
41479
|
+
parent_session_id: normalizeNullableString(row.parent_session_id),
|
|
41397
41480
|
started_at: startedAt,
|
|
41398
|
-
ended_at:
|
|
41481
|
+
ended_at: endedAt,
|
|
41399
41482
|
end_reason: normalizeNullableString(row.end_reason),
|
|
41400
41483
|
message_count: normalizeNumber(row.message_count),
|
|
41401
41484
|
tool_call_count: normalizeNumber(row.tool_call_count),
|
|
@@ -41408,8 +41491,338 @@ function mapRow(row) {
|
|
|
41408
41491
|
estimated_cost_usd: normalizeNumber(row.estimated_cost_usd),
|
|
41409
41492
|
actual_cost_usd: normalizeNullableNumber(row.actual_cost_usd),
|
|
41410
41493
|
cost_status: String(row.cost_status || ""),
|
|
41494
|
+
preview,
|
|
41495
|
+
last_active: lastActive,
|
|
41496
|
+
has_visible_messages: !!normalizeNumber(row.has_visible_messages),
|
|
41497
|
+
is_active: endedAt == null && nowSeconds - lastActive <= LIVE_WINDOW_SECONDS2
|
|
41498
|
+
};
|
|
41499
|
+
}
|
|
41500
|
+
function sortByRecency2(items) {
|
|
41501
|
+
return [...items].sort((a, b) => {
|
|
41502
|
+
if (b.last_active !== a.last_active) return b.last_active - a.last_active;
|
|
41503
|
+
if (b.started_at !== a.started_at) return b.started_at - a.started_at;
|
|
41504
|
+
return a.id.localeCompare(b.id);
|
|
41505
|
+
});
|
|
41506
|
+
}
|
|
41507
|
+
function timingMatchesParent2(parent, child) {
|
|
41508
|
+
if (!parent || !child || parent.ended_at == null) return false;
|
|
41509
|
+
return Math.abs(Number(child.started_at || 0) - Number(parent.ended_at || 0)) <= LINEAGE_TOLERANCE_SECONDS2;
|
|
41510
|
+
}
|
|
41511
|
+
function isBranchRoot2(session, byId) {
|
|
41512
|
+
if (!session?.parent_session_id) return false;
|
|
41513
|
+
const parent = byId.get(session.parent_session_id);
|
|
41514
|
+
return !!parent && parent.end_reason === "branched" && timingMatchesParent2(parent, session);
|
|
41515
|
+
}
|
|
41516
|
+
function isVisibleRoot2(session, byId) {
|
|
41517
|
+
if (!session || session.source === "tool") return false;
|
|
41518
|
+
return session.parent_session_id == null || isBranchRoot2(session, byId);
|
|
41519
|
+
}
|
|
41520
|
+
function continuationCandidates2(parent, byId, childrenByParent) {
|
|
41521
|
+
const childIds = childrenByParent.get(parent.id) || [];
|
|
41522
|
+
return childIds.map((childId) => byId.get(childId)).filter((child) => !!child).filter((child) => child.source !== "tool").filter((child) => child.source === parent.source).filter((child) => timingMatchesParent2(parent, child)).sort((a, b) => {
|
|
41523
|
+
const aDelta = Math.abs(Number(a.started_at || 0) - Number(parent.ended_at || 0));
|
|
41524
|
+
const bDelta = Math.abs(Number(b.started_at || 0) - Number(parent.ended_at || 0));
|
|
41525
|
+
if (aDelta !== bDelta) return aDelta - bDelta;
|
|
41526
|
+
return a.id.localeCompare(b.id);
|
|
41527
|
+
});
|
|
41528
|
+
}
|
|
41529
|
+
function nextContinuationChild2(parent, byId, childrenByParent) {
|
|
41530
|
+
if (parent.end_reason !== "compression") return null;
|
|
41531
|
+
const candidates = continuationCandidates2(parent, byId, childrenByParent);
|
|
41532
|
+
if (candidates.length === 1) return candidates[0];
|
|
41533
|
+
const exactPreviewMatches = candidates.filter((child) => {
|
|
41534
|
+
const childPreview = normalizeText2(child.preview);
|
|
41535
|
+
const parentPreview = normalizeText2(parent.preview);
|
|
41536
|
+
return !!childPreview && childPreview === parentPreview;
|
|
41537
|
+
});
|
|
41538
|
+
if (exactPreviewMatches.length === 1) return exactPreviewMatches[0];
|
|
41539
|
+
return null;
|
|
41540
|
+
}
|
|
41541
|
+
function collectConversationChain2(rootId, byId, childrenByParent) {
|
|
41542
|
+
const chain = [];
|
|
41543
|
+
const seen = /* @__PURE__ */ new Set();
|
|
41544
|
+
let current = byId.get(rootId) || null;
|
|
41545
|
+
while (current && !seen.has(current.id)) {
|
|
41546
|
+
chain.push(current);
|
|
41547
|
+
seen.add(current.id);
|
|
41548
|
+
current = nextContinuationChild2(current, byId, childrenByParent);
|
|
41549
|
+
}
|
|
41550
|
+
return chain;
|
|
41551
|
+
}
|
|
41552
|
+
function toSummary2(session) {
|
|
41553
|
+
return {
|
|
41554
|
+
id: session.id,
|
|
41555
|
+
source: safeText2(session.source),
|
|
41556
|
+
model: safeText2(session.model),
|
|
41557
|
+
title: session.title ?? null,
|
|
41558
|
+
started_at: Number(session.started_at || 0),
|
|
41559
|
+
ended_at: session.ended_at ?? null,
|
|
41560
|
+
last_active: session.last_active,
|
|
41561
|
+
message_count: Number(session.message_count || 0),
|
|
41562
|
+
tool_call_count: Number(session.tool_call_count || 0),
|
|
41563
|
+
input_tokens: Number(session.input_tokens || 0),
|
|
41564
|
+
output_tokens: Number(session.output_tokens || 0),
|
|
41565
|
+
cache_read_tokens: Number(session.cache_read_tokens || 0),
|
|
41566
|
+
cache_write_tokens: Number(session.cache_write_tokens || 0),
|
|
41567
|
+
reasoning_tokens: Number(session.reasoning_tokens || 0),
|
|
41568
|
+
billing_provider: session.billing_provider ?? null,
|
|
41569
|
+
estimated_cost_usd: Number(session.estimated_cost_usd || 0),
|
|
41570
|
+
actual_cost_usd: session.actual_cost_usd ?? null,
|
|
41571
|
+
cost_status: safeText2(session.cost_status),
|
|
41572
|
+
preview: session.preview,
|
|
41573
|
+
is_active: session.is_active,
|
|
41574
|
+
thread_session_count: 1
|
|
41575
|
+
};
|
|
41576
|
+
}
|
|
41577
|
+
function aggregateSummary2(rootId, byId, childrenByParent) {
|
|
41578
|
+
const chain = collectConversationChain2(rootId, byId, childrenByParent);
|
|
41579
|
+
if (!chain.length || !chain.some((session) => session.has_visible_messages)) return null;
|
|
41580
|
+
const root = chain[0];
|
|
41581
|
+
const last = chain[chain.length - 1];
|
|
41582
|
+
const firstPreview = chain.map((session) => session.preview).find(Boolean) || "";
|
|
41583
|
+
const costStatuses = Array.from(new Set(chain.map((session) => safeText2(session.cost_status)).filter(Boolean)));
|
|
41584
|
+
return {
|
|
41585
|
+
...toSummary2(root),
|
|
41586
|
+
title: root.title || firstPreview || null,
|
|
41587
|
+
preview: root.preview || firstPreview,
|
|
41588
|
+
model: safeText2(last?.model || root.model),
|
|
41589
|
+
ended_at: last?.ended_at ?? null,
|
|
41590
|
+
last_active: Math.max(...chain.map((session) => session.last_active)),
|
|
41591
|
+
is_active: chain.some((session) => session.is_active),
|
|
41592
|
+
billing_provider: last?.billing_provider ?? root.billing_provider ?? null,
|
|
41593
|
+
cost_status: costStatuses.length === 1 ? costStatuses[0] : "mixed",
|
|
41594
|
+
thread_session_count: chain.length,
|
|
41595
|
+
message_count: chain.reduce((sum, session) => sum + Number(session.message_count || 0), 0),
|
|
41596
|
+
tool_call_count: chain.reduce((sum, session) => sum + Number(session.tool_call_count || 0), 0),
|
|
41597
|
+
input_tokens: chain.reduce((sum, session) => sum + Number(session.input_tokens || 0), 0),
|
|
41598
|
+
output_tokens: chain.reduce((sum, session) => sum + Number(session.output_tokens || 0), 0),
|
|
41599
|
+
cache_read_tokens: chain.reduce((sum, session) => sum + Number(session.cache_read_tokens || 0), 0),
|
|
41600
|
+
cache_write_tokens: chain.reduce((sum, session) => sum + Number(session.cache_write_tokens || 0), 0),
|
|
41601
|
+
reasoning_tokens: chain.reduce((sum, session) => sum + Number(session.reasoning_tokens || 0), 0),
|
|
41602
|
+
estimated_cost_usd: chain.reduce((sum, session) => sum + Number(session.estimated_cost_usd || 0), 0),
|
|
41603
|
+
actual_cost_usd: chain.reduce((sum, session) => {
|
|
41604
|
+
const actual = session.actual_cost_usd;
|
|
41605
|
+
if (actual == null) return sum;
|
|
41606
|
+
return (sum || 0) + Number(actual);
|
|
41607
|
+
}, null)
|
|
41608
|
+
};
|
|
41609
|
+
}
|
|
41610
|
+
function normalizeVisibleMessage2(message2, fallbackTimestamp) {
|
|
41611
|
+
const role = safeText2(message2.role);
|
|
41612
|
+
const content = textFromContent2(message2.content).trim();
|
|
41613
|
+
if (!content) return null;
|
|
41614
|
+
if (role !== "user" && role !== "assistant") return null;
|
|
41615
|
+
if (role === "user" && isSyntheticUserText2(content)) return null;
|
|
41616
|
+
return {
|
|
41617
|
+
id: message2.id,
|
|
41618
|
+
session_id: message2.session_id,
|
|
41619
|
+
role,
|
|
41620
|
+
content,
|
|
41621
|
+
timestamp: Number.isFinite(Number(message2.timestamp)) && Number(message2.timestamp) > 0 ? Number(message2.timestamp) : fallbackTimestamp
|
|
41622
|
+
};
|
|
41623
|
+
}
|
|
41624
|
+
async function openConversationDb() {
|
|
41625
|
+
if (!SQLITE_AVAILABLE2) {
|
|
41626
|
+
throw new Error(`node:sqlite requires Node >= 22.5, current: ${process.versions.node}`);
|
|
41627
|
+
}
|
|
41628
|
+
const { DatabaseSync: DatabaseSync2 } = await import("node:sqlite");
|
|
41629
|
+
return new DatabaseSync2(conversationDbPath(), { open: true, readOnly: true });
|
|
41630
|
+
}
|
|
41631
|
+
function buildConversationSessionSql(source) {
|
|
41632
|
+
const sql = `
|
|
41633
|
+
SELECT
|
|
41634
|
+
s.id,
|
|
41635
|
+
s.source,
|
|
41636
|
+
COALESCE(s.user_id, '') AS user_id,
|
|
41637
|
+
COALESCE(s.model, '') AS model,
|
|
41638
|
+
COALESCE(s.title, '') AS title,
|
|
41639
|
+
s.parent_session_id AS parent_session_id,
|
|
41640
|
+
COALESCE(s.started_at, 0) AS started_at,
|
|
41641
|
+
s.ended_at AS ended_at,
|
|
41642
|
+
COALESCE(s.end_reason, '') AS end_reason,
|
|
41643
|
+
COALESCE(s.message_count, 0) AS message_count,
|
|
41644
|
+
COALESCE(s.tool_call_count, 0) AS tool_call_count,
|
|
41645
|
+
COALESCE(s.input_tokens, 0) AS input_tokens,
|
|
41646
|
+
COALESCE(s.output_tokens, 0) AS output_tokens,
|
|
41647
|
+
COALESCE(s.cache_read_tokens, 0) AS cache_read_tokens,
|
|
41648
|
+
COALESCE(s.cache_write_tokens, 0) AS cache_write_tokens,
|
|
41649
|
+
COALESCE(s.reasoning_tokens, 0) AS reasoning_tokens,
|
|
41650
|
+
COALESCE(s.billing_provider, '') AS billing_provider,
|
|
41651
|
+
COALESCE(s.estimated_cost_usd, 0) AS estimated_cost_usd,
|
|
41652
|
+
s.actual_cost_usd AS actual_cost_usd,
|
|
41653
|
+
COALESCE(s.cost_status, '') AS cost_status,
|
|
41654
|
+
COALESCE(
|
|
41655
|
+
(
|
|
41656
|
+
SELECT SUBSTR(REPLACE(REPLACE(m.content, CHAR(10), ' '), CHAR(13), ' '), 1, 80)
|
|
41657
|
+
FROM messages m
|
|
41658
|
+
WHERE m.session_id = s.id
|
|
41659
|
+
AND ${VISIBLE_HUMAN_MESSAGE_SQL}
|
|
41660
|
+
ORDER BY m.timestamp, m.id
|
|
41661
|
+
LIMIT 1
|
|
41662
|
+
),
|
|
41663
|
+
''
|
|
41664
|
+
) AS preview,
|
|
41665
|
+
COALESCE((SELECT MAX(m2.timestamp) FROM messages m2 WHERE m2.session_id = s.id), s.started_at) AS last_active,
|
|
41666
|
+
CASE WHEN EXISTS (
|
|
41667
|
+
SELECT 1
|
|
41668
|
+
FROM messages m
|
|
41669
|
+
WHERE m.session_id = s.id
|
|
41670
|
+
AND ${VISIBLE_HUMAN_MESSAGE_SQL}
|
|
41671
|
+
) THEN 1 ELSE 0 END AS has_visible_messages
|
|
41672
|
+
FROM sessions s
|
|
41673
|
+
WHERE s.source != 'tool'
|
|
41674
|
+
${source ? "AND s.source = ?" : ""}
|
|
41675
|
+
ORDER BY s.started_at DESC
|
|
41676
|
+
`;
|
|
41677
|
+
return { sql, params: source ? [source] : [] };
|
|
41678
|
+
}
|
|
41679
|
+
async function loadConversationSessions(source) {
|
|
41680
|
+
const db = await openConversationDb();
|
|
41681
|
+
try {
|
|
41682
|
+
const { sql, params } = buildConversationSessionSql(source);
|
|
41683
|
+
const rows = db.prepare(sql).all(...params);
|
|
41684
|
+
const nowSeconds = Date.now() / 1e3;
|
|
41685
|
+
return rows.map((row) => mapSessionRow(row, nowSeconds));
|
|
41686
|
+
} finally {
|
|
41687
|
+
db.close();
|
|
41688
|
+
}
|
|
41689
|
+
}
|
|
41690
|
+
async function listConversationSummariesFromDb(options = {}) {
|
|
41691
|
+
const humanOnly = options.humanOnly !== false;
|
|
41692
|
+
const limit = options.limit && options.limit > 0 ? options.limit : DEFAULT_CONVERSATION_LIMIT2;
|
|
41693
|
+
const sessions3 = await loadConversationSessions(options.source);
|
|
41694
|
+
const byId = new Map(sessions3.map((session) => [session.id, session]));
|
|
41695
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
41696
|
+
for (const session of sessions3) {
|
|
41697
|
+
const key = session.parent_session_id ?? null;
|
|
41698
|
+
const siblings = childrenByParent.get(key) || [];
|
|
41699
|
+
siblings.push(session.id);
|
|
41700
|
+
childrenByParent.set(key, siblings);
|
|
41701
|
+
}
|
|
41702
|
+
if (!humanOnly) {
|
|
41703
|
+
return sortByRecency2(sessions3.map(toSummary2)).slice(0, limit);
|
|
41704
|
+
}
|
|
41705
|
+
const summaries = sessions3.filter((session) => isVisibleRoot2(session, byId)).map((session) => aggregateSummary2(session.id, byId, childrenByParent)).filter((summary) => !!summary);
|
|
41706
|
+
return sortByRecency2(summaries).slice(0, limit);
|
|
41707
|
+
}
|
|
41708
|
+
async function getConversationDetailFromDb(sessionId, options = {}) {
|
|
41709
|
+
const humanOnly = options.humanOnly !== false;
|
|
41710
|
+
const sessions3 = await loadConversationSessions(options.source);
|
|
41711
|
+
const byId = new Map(sessions3.map((session) => [session.id, session]));
|
|
41712
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
41713
|
+
for (const session of sessions3) {
|
|
41714
|
+
const key = session.parent_session_id ?? null;
|
|
41715
|
+
const siblings = childrenByParent.get(key) || [];
|
|
41716
|
+
siblings.push(session.id);
|
|
41717
|
+
childrenByParent.set(key, siblings);
|
|
41718
|
+
}
|
|
41719
|
+
let chain = [];
|
|
41720
|
+
if (!humanOnly) {
|
|
41721
|
+
const session = byId.get(sessionId);
|
|
41722
|
+
if (!session || session.source === "tool") return null;
|
|
41723
|
+
chain = [session];
|
|
41724
|
+
} else {
|
|
41725
|
+
const root = byId.get(sessionId);
|
|
41726
|
+
if (!isVisibleRoot2(root, byId)) return null;
|
|
41727
|
+
chain = collectConversationChain2(sessionId, byId, childrenByParent);
|
|
41728
|
+
}
|
|
41729
|
+
if (!chain.length) return null;
|
|
41730
|
+
const db = await openConversationDb();
|
|
41731
|
+
try {
|
|
41732
|
+
const ids = chain.map((session) => session.id);
|
|
41733
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
41734
|
+
const rows = db.prepare(`
|
|
41735
|
+
SELECT id, session_id, role, content, timestamp
|
|
41736
|
+
FROM messages
|
|
41737
|
+
WHERE session_id IN (${placeholders})
|
|
41738
|
+
AND role IN ('user', 'assistant')
|
|
41739
|
+
AND content IS NOT NULL
|
|
41740
|
+
AND content != ''
|
|
41741
|
+
ORDER BY timestamp, id
|
|
41742
|
+
`).all(...ids);
|
|
41743
|
+
const sessionById = new Map(chain.map((session) => [session.id, session]));
|
|
41744
|
+
const messages = rows.map((row) => {
|
|
41745
|
+
const session = sessionById.get(String(row.session_id || ""));
|
|
41746
|
+
return normalizeVisibleMessage2({
|
|
41747
|
+
id: row.id,
|
|
41748
|
+
session_id: String(row.session_id || ""),
|
|
41749
|
+
role: String(row.role || ""),
|
|
41750
|
+
content: row.content,
|
|
41751
|
+
timestamp: normalizeNumber(row.timestamp)
|
|
41752
|
+
}, session?.last_active || session?.started_at || 0);
|
|
41753
|
+
}).filter((message2) => !!message2).sort((a, b) => {
|
|
41754
|
+
if (a.timestamp !== b.timestamp) return a.timestamp - b.timestamp;
|
|
41755
|
+
return String(a.id).localeCompare(String(b.id));
|
|
41756
|
+
});
|
|
41757
|
+
if (!messages.length) {
|
|
41758
|
+
return humanOnly ? null : {
|
|
41759
|
+
session_id: sessionId,
|
|
41760
|
+
messages: [],
|
|
41761
|
+
visible_count: 0,
|
|
41762
|
+
thread_session_count: chain.length
|
|
41763
|
+
};
|
|
41764
|
+
}
|
|
41765
|
+
return {
|
|
41766
|
+
session_id: sessionId,
|
|
41767
|
+
messages,
|
|
41768
|
+
visible_count: messages.length,
|
|
41769
|
+
thread_session_count: chain.length
|
|
41770
|
+
};
|
|
41771
|
+
} finally {
|
|
41772
|
+
db.close();
|
|
41773
|
+
}
|
|
41774
|
+
}
|
|
41775
|
+
|
|
41776
|
+
// packages/server/src/db/hermes/sessions-db.ts
|
|
41777
|
+
init_hermes_profile();
|
|
41778
|
+
var SQLITE_AVAILABLE3 = (() => {
|
|
41779
|
+
const [major, minor] = process.versions.node.split(".").map(Number);
|
|
41780
|
+
return major > 22 || major === 22 && minor >= 5;
|
|
41781
|
+
})();
|
|
41782
|
+
function sessionDbPath() {
|
|
41783
|
+
return `${getActiveProfileDir()}/state.db`;
|
|
41784
|
+
}
|
|
41785
|
+
function normalizeNumber2(value, fallback = 0) {
|
|
41786
|
+
if (value == null || value === "") return fallback;
|
|
41787
|
+
const num = Number(value);
|
|
41788
|
+
return Number.isFinite(num) ? num : fallback;
|
|
41789
|
+
}
|
|
41790
|
+
function normalizeNullableNumber2(value) {
|
|
41791
|
+
if (value == null || value === "") return null;
|
|
41792
|
+
const num = Number(value);
|
|
41793
|
+
return Number.isFinite(num) ? num : null;
|
|
41794
|
+
}
|
|
41795
|
+
function normalizeNullableString2(value) {
|
|
41796
|
+
if (value == null || value === "") return null;
|
|
41797
|
+
return String(value);
|
|
41798
|
+
}
|
|
41799
|
+
function mapRow(row) {
|
|
41800
|
+
const startedAt = normalizeNumber2(row.started_at);
|
|
41801
|
+
const rawTitle = normalizeNullableString2(row.title);
|
|
41802
|
+
const preview = String(row.preview || "");
|
|
41803
|
+
const title = rawTitle || (preview ? preview.length > 40 ? preview.slice(0, 40) + "..." : preview : null);
|
|
41804
|
+
return {
|
|
41805
|
+
id: String(row.id || ""),
|
|
41806
|
+
source: String(row.source || ""),
|
|
41807
|
+
user_id: normalizeNullableString2(row.user_id),
|
|
41808
|
+
model: String(row.model || ""),
|
|
41809
|
+
title,
|
|
41810
|
+
started_at: startedAt,
|
|
41811
|
+
ended_at: normalizeNullableNumber2(row.ended_at),
|
|
41812
|
+
end_reason: normalizeNullableString2(row.end_reason),
|
|
41813
|
+
message_count: normalizeNumber2(row.message_count),
|
|
41814
|
+
tool_call_count: normalizeNumber2(row.tool_call_count),
|
|
41815
|
+
input_tokens: normalizeNumber2(row.input_tokens),
|
|
41816
|
+
output_tokens: normalizeNumber2(row.output_tokens),
|
|
41817
|
+
cache_read_tokens: normalizeNumber2(row.cache_read_tokens),
|
|
41818
|
+
cache_write_tokens: normalizeNumber2(row.cache_write_tokens),
|
|
41819
|
+
reasoning_tokens: normalizeNumber2(row.reasoning_tokens),
|
|
41820
|
+
billing_provider: normalizeNullableString2(row.billing_provider),
|
|
41821
|
+
estimated_cost_usd: normalizeNumber2(row.estimated_cost_usd),
|
|
41822
|
+
actual_cost_usd: normalizeNullableNumber2(row.actual_cost_usd),
|
|
41823
|
+
cost_status: String(row.cost_status || ""),
|
|
41411
41824
|
preview: String(row.preview || ""),
|
|
41412
|
-
last_active:
|
|
41825
|
+
last_active: normalizeNumber2(row.last_active, startedAt)
|
|
41413
41826
|
};
|
|
41414
41827
|
}
|
|
41415
41828
|
var SESSION_SELECT = `
|
|
@@ -41472,6 +41885,35 @@ function containsCjk(text) {
|
|
|
41472
41885
|
}
|
|
41473
41886
|
return false;
|
|
41474
41887
|
}
|
|
41888
|
+
function isNumericQuery(text) {
|
|
41889
|
+
return /^\d+(?:\s+\d+)*$/.test(text.trim());
|
|
41890
|
+
}
|
|
41891
|
+
function hasUnsafeChars(text) {
|
|
41892
|
+
return /[^\w\s\u4e00-\u9fff\u3400-\u4dbf\u3000-\u303f\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/.test(text);
|
|
41893
|
+
}
|
|
41894
|
+
function runLikeContentSearch(db, source, query) {
|
|
41895
|
+
const likeBase = buildBaseSessionSql(source);
|
|
41896
|
+
const likeSql = `
|
|
41897
|
+
WITH base AS (
|
|
41898
|
+
${likeBase.sql}
|
|
41899
|
+
)
|
|
41900
|
+
SELECT
|
|
41901
|
+
base.*,
|
|
41902
|
+
m.id AS matched_message_id,
|
|
41903
|
+
substr(
|
|
41904
|
+
m.content,
|
|
41905
|
+
max(1, instr(m.content, ?) - 40),
|
|
41906
|
+
120
|
|
41907
|
+
) AS snippet,
|
|
41908
|
+
0 AS rank
|
|
41909
|
+
FROM base
|
|
41910
|
+
JOIN messages m ON m.session_id = base.id
|
|
41911
|
+
WHERE m.content LIKE ?
|
|
41912
|
+
ORDER BY base.last_active DESC, m.timestamp DESC
|
|
41913
|
+
`;
|
|
41914
|
+
const likeStatement = db.prepare(likeSql);
|
|
41915
|
+
return likeStatement.all(...likeBase.params, query, `%${query}%`);
|
|
41916
|
+
}
|
|
41475
41917
|
function sanitizeFtsQuery(query) {
|
|
41476
41918
|
const quotedParts = [];
|
|
41477
41919
|
const preserved = query.replace(/"[^"]*"/g, (match) => {
|
|
@@ -41502,13 +41944,13 @@ function toPrefixQuery(query) {
|
|
|
41502
41944
|
function mapSearchRow(row) {
|
|
41503
41945
|
return {
|
|
41504
41946
|
...mapRow(row),
|
|
41505
|
-
matched_message_id:
|
|
41947
|
+
matched_message_id: normalizeNullableNumber2(row.matched_message_id),
|
|
41506
41948
|
snippet: String(row.snippet || row.preview || ""),
|
|
41507
41949
|
rank: Number.isFinite(Number(row.rank)) ? Number(row.rank) : 0
|
|
41508
41950
|
};
|
|
41509
41951
|
}
|
|
41510
41952
|
async function listSessionSummaries(source, limit = 2e3) {
|
|
41511
|
-
if (!
|
|
41953
|
+
if (!SQLITE_AVAILABLE3) {
|
|
41512
41954
|
throw new Error(`node:sqlite requires Node >= 22.5, current: ${process.versions.node}`);
|
|
41513
41955
|
}
|
|
41514
41956
|
const { DatabaseSync: DatabaseSync2 } = await import("node:sqlite");
|
|
@@ -41523,7 +41965,7 @@ async function listSessionSummaries(source, limit = 2e3) {
|
|
|
41523
41965
|
}
|
|
41524
41966
|
}
|
|
41525
41967
|
async function searchSessionSummaries(query, source, limit = 20) {
|
|
41526
|
-
if (!
|
|
41968
|
+
if (!SQLITE_AVAILABLE3) {
|
|
41527
41969
|
throw new Error(`node:sqlite requires Node >= 22.5, current: ${process.versions.node}`);
|
|
41528
41970
|
}
|
|
41529
41971
|
const trimmed = query.trim();
|
|
@@ -41540,6 +41982,7 @@ async function searchSessionSummaries(query, source, limit = 20) {
|
|
|
41540
41982
|
const db = new DatabaseSync2(sessionDbPath(), { open: true, readOnly: true });
|
|
41541
41983
|
const normalized = sanitizeFtsQuery(trimmed);
|
|
41542
41984
|
const prefixQuery = toPrefixQuery(normalized);
|
|
41985
|
+
let titleRows = [];
|
|
41543
41986
|
try {
|
|
41544
41987
|
const titleBase = buildBaseSessionSql(source);
|
|
41545
41988
|
const contentBase = buildBaseSessionSql(source);
|
|
@@ -41561,7 +42004,7 @@ async function searchSessionSummaries(query, source, limit = 20) {
|
|
|
41561
42004
|
LIMIT ?
|
|
41562
42005
|
`;
|
|
41563
42006
|
const titleStatement = db.prepare(titleSql);
|
|
41564
|
-
|
|
42007
|
+
titleRows = titleStatement.all(...titleBase.params, `%${trimmed.toLowerCase()}%`, limit);
|
|
41565
42008
|
const contentSql = `
|
|
41566
42009
|
WITH base AS (
|
|
41567
42010
|
${contentBase.sql}
|
|
@@ -41597,28 +42040,9 @@ async function searchSessionSummaries(query, source, limit = 20) {
|
|
|
41597
42040
|
});
|
|
41598
42041
|
return items.slice(0, limit);
|
|
41599
42042
|
} catch (err) {
|
|
42043
|
+
const message2 = err instanceof Error ? err.message : String(err);
|
|
41600
42044
|
if (containsCjk(normalized)) {
|
|
41601
|
-
const
|
|
41602
|
-
const likeSql = `
|
|
41603
|
-
WITH base AS (
|
|
41604
|
-
${likeBase.sql}
|
|
41605
|
-
)
|
|
41606
|
-
SELECT
|
|
41607
|
-
base.*,
|
|
41608
|
-
m.id AS matched_message_id,
|
|
41609
|
-
substr(
|
|
41610
|
-
m.content,
|
|
41611
|
-
max(1, instr(m.content, ?) - 40),
|
|
41612
|
-
120
|
|
41613
|
-
) AS snippet,
|
|
41614
|
-
0 AS rank
|
|
41615
|
-
FROM base
|
|
41616
|
-
JOIN messages m ON m.session_id = base.id
|
|
41617
|
-
WHERE m.content LIKE ?
|
|
41618
|
-
ORDER BY base.last_active DESC, m.timestamp DESC
|
|
41619
|
-
`;
|
|
41620
|
-
const likeStatement = db.prepare(likeSql);
|
|
41621
|
-
const likeRows = likeStatement.all(...likeBase.params, trimmed, `%${trimmed}%`);
|
|
42045
|
+
const likeRows = runLikeContentSearch(db, source, trimmed);
|
|
41622
42046
|
const merged = /* @__PURE__ */ new Map();
|
|
41623
42047
|
for (const row of likeRows) {
|
|
41624
42048
|
const mapped = mapSearchRow(row);
|
|
@@ -41628,7 +42052,21 @@ async function searchSessionSummaries(query, source, limit = 20) {
|
|
|
41628
42052
|
}
|
|
41629
42053
|
return [...merged.values()].slice(0, limit);
|
|
41630
42054
|
}
|
|
41631
|
-
|
|
42055
|
+
if (isNumericQuery(trimmed) || hasUnsafeChars(trimmed)) {
|
|
42056
|
+
const likeRows = runLikeContentSearch(db, source, trimmed);
|
|
42057
|
+
const merged = /* @__PURE__ */ new Map();
|
|
42058
|
+
for (const row of titleRows) {
|
|
42059
|
+
const mapped = mapSearchRow(row);
|
|
42060
|
+
merged.set(mapped.id, mapped);
|
|
42061
|
+
}
|
|
42062
|
+
for (const row of likeRows) {
|
|
42063
|
+
const mapped = mapSearchRow(row);
|
|
42064
|
+
if (!merged.has(mapped.id)) {
|
|
42065
|
+
merged.set(mapped.id, mapped);
|
|
42066
|
+
}
|
|
42067
|
+
}
|
|
42068
|
+
return [...merged.values()].slice(0, limit);
|
|
42069
|
+
}
|
|
41632
42070
|
throw new Error(`Failed to search sessions: ${message2}`);
|
|
41633
42071
|
} finally {
|
|
41634
42072
|
db.close();
|
|
@@ -41721,12 +42159,31 @@ async function listConversations(ctx) {
|
|
|
41721
42159
|
const source = ctx.query.source || void 0;
|
|
41722
42160
|
const humanOnly = parseHumanOnly(ctx.query.humanOnly);
|
|
41723
42161
|
const limit = parseLimit(ctx.query.limit);
|
|
41724
|
-
|
|
41725
|
-
|
|
42162
|
+
try {
|
|
42163
|
+
const sessions4 = await listConversationSummariesFromDb({ source, humanOnly, limit });
|
|
42164
|
+
ctx.body = { sessions: sessions4 };
|
|
42165
|
+
return;
|
|
42166
|
+
} catch (err) {
|
|
42167
|
+
logger.warn(err, "Hermes Conversation DB: summary query failed, falling back to CLI export");
|
|
42168
|
+
}
|
|
42169
|
+
const sessions3 = await listConversationSummaries({ source, humanOnly, limit });
|
|
42170
|
+
ctx.body = { sessions: sessions3 };
|
|
41726
42171
|
}
|
|
41727
42172
|
async function getConversationMessages(ctx) {
|
|
41728
42173
|
const source = ctx.query.source || void 0;
|
|
41729
42174
|
const humanOnly = parseHumanOnly(ctx.query.humanOnly);
|
|
42175
|
+
try {
|
|
42176
|
+
const detail2 = await getConversationDetailFromDb(ctx.params.id, { source, humanOnly });
|
|
42177
|
+
if (!detail2) {
|
|
42178
|
+
ctx.status = 404;
|
|
42179
|
+
ctx.body = { error: "Conversation not found" };
|
|
42180
|
+
return;
|
|
42181
|
+
}
|
|
42182
|
+
ctx.body = detail2;
|
|
42183
|
+
return;
|
|
42184
|
+
} catch (err) {
|
|
42185
|
+
logger.warn(err, "Hermes Conversation DB: detail query failed, falling back to CLI export");
|
|
42186
|
+
}
|
|
41730
42187
|
const detail = await getConversationDetail(ctx.params.id, { source, humanOnly });
|
|
41731
42188
|
if (!detail) {
|
|
41732
42189
|
ctx.status = 404;
|
|
@@ -41739,14 +42196,14 @@ async function list(ctx) {
|
|
|
41739
42196
|
const source = ctx.query.source || void 0;
|
|
41740
42197
|
const limit = ctx.query.limit ? parseInt(ctx.query.limit, 10) : void 0;
|
|
41741
42198
|
try {
|
|
41742
|
-
const
|
|
41743
|
-
ctx.body = { sessions:
|
|
42199
|
+
const sessions4 = await listSessionSummaries(source, limit && limit > 0 ? limit : 2e3);
|
|
42200
|
+
ctx.body = { sessions: sessions4 };
|
|
41744
42201
|
return;
|
|
41745
42202
|
} catch (err) {
|
|
41746
42203
|
logger.warn(err, "Hermes Session DB: summary query failed, falling back to CLI");
|
|
41747
42204
|
}
|
|
41748
|
-
const
|
|
41749
|
-
ctx.body = { sessions:
|
|
42205
|
+
const sessions3 = await listSessions(source, limit);
|
|
42206
|
+
ctx.body = { sessions: sessions3 };
|
|
41750
42207
|
}
|
|
41751
42208
|
async function search(ctx) {
|
|
41752
42209
|
const q = typeof ctx.query.q === "string" ? ctx.query.q : "";
|
|
@@ -42081,6 +42538,8 @@ var PROVIDER_ENV_MAP = {
|
|
|
42081
42538
|
"opencode-go": { api_key_env: "OPENCODE_API_KEY", base_url_env: "" },
|
|
42082
42539
|
huggingface: { api_key_env: "HF_TOKEN", base_url_env: "" },
|
|
42083
42540
|
arcee: { api_key_env: "ARCEE_API_KEY", base_url_env: "" },
|
|
42541
|
+
stepfun: { api_key_env: "STEPFUN_API_KEY", base_url_env: "" },
|
|
42542
|
+
nous: { api_key_env: "", base_url_env: "" },
|
|
42084
42543
|
"openai-codex": { api_key_env: "", base_url_env: "" }
|
|
42085
42544
|
};
|
|
42086
42545
|
var configPath = () => getActiveConfigPath();
|
|
@@ -42193,7 +42652,7 @@ async function listFilesRecursive(dir, prefix) {
|
|
|
42193
42652
|
}
|
|
42194
42653
|
async function fetchProviderModels(baseUrl, apiKey) {
|
|
42195
42654
|
const base = baseUrl.replace(/\/+$/, "");
|
|
42196
|
-
const modelsUrl = base
|
|
42655
|
+
const modelsUrl = /\/v\d+\/?$/.test(base) ? `${base}/models` : `${base}/v1/models`;
|
|
42197
42656
|
try {
|
|
42198
42657
|
const res = await fetch(modelsUrl, {
|
|
42199
42658
|
headers: { Authorization: `Bearer ${apiKey}` },
|
|
@@ -42463,6 +42922,7 @@ var PROVIDER_PRESETS = [
|
|
|
42463
42922
|
base_url: "https://api.kimi.com/coding/v1",
|
|
42464
42923
|
models: [
|
|
42465
42924
|
"kimi-for-coding",
|
|
42925
|
+
"kimi-k2.6",
|
|
42466
42926
|
"kimi-k2.5",
|
|
42467
42927
|
"kimi-k2-thinking",
|
|
42468
42928
|
"kimi-k2-turbo-preview",
|
|
@@ -42475,6 +42935,7 @@ var PROVIDER_PRESETS = [
|
|
|
42475
42935
|
builtin: true,
|
|
42476
42936
|
base_url: "https://api.moonshot.cn/v1",
|
|
42477
42937
|
models: [
|
|
42938
|
+
"kimi-k2.6",
|
|
42478
42939
|
"kimi-k2.5",
|
|
42479
42940
|
"kimi-k2-thinking",
|
|
42480
42941
|
"kimi-k2-turbo-preview",
|
|
@@ -42638,6 +43099,50 @@ var PROVIDER_PRESETS = [
|
|
|
42638
43099
|
base_url: "https://api.arcee.ai/v1",
|
|
42639
43100
|
models: ["trinity-large-thinking", "trinity-large-preview", "trinity-mini"]
|
|
42640
43101
|
},
|
|
43102
|
+
{
|
|
43103
|
+
label: "Nous Portal",
|
|
43104
|
+
value: "nous",
|
|
43105
|
+
builtin: true,
|
|
43106
|
+
base_url: "https://inference-api.nousresearch.com/v1",
|
|
43107
|
+
models: [
|
|
43108
|
+
"moonshotai/kimi-k2.6",
|
|
43109
|
+
"xiaomi/mimo-v2.5-pro",
|
|
43110
|
+
"xiaomi/mimo-v2.5",
|
|
43111
|
+
"anthropic/claude-opus-4.7",
|
|
43112
|
+
"anthropic/claude-opus-4.6",
|
|
43113
|
+
"anthropic/claude-sonnet-4.6",
|
|
43114
|
+
"anthropic/claude-sonnet-4.5",
|
|
43115
|
+
"anthropic/claude-haiku-4.5",
|
|
43116
|
+
"openai/gpt-5.4",
|
|
43117
|
+
"openai/gpt-5.4-mini",
|
|
43118
|
+
"openai/gpt-5.3-codex",
|
|
43119
|
+
"google/gemini-3-pro-preview",
|
|
43120
|
+
"google/gemini-3-flash-preview",
|
|
43121
|
+
"google/gemini-3.1-pro-preview",
|
|
43122
|
+
"google/gemini-3.1-flash-lite-preview",
|
|
43123
|
+
"qwen/qwen3.5-plus-02-15",
|
|
43124
|
+
"qwen/qwen3.5-35b-a3b",
|
|
43125
|
+
"stepfun/step-3.5-flash",
|
|
43126
|
+
"minimax/minimax-m2.7",
|
|
43127
|
+
"minimax/minimax-m2.5",
|
|
43128
|
+
"minimax/minimax-m2.5:free",
|
|
43129
|
+
"z-ai/glm-5.1",
|
|
43130
|
+
"z-ai/glm-5v-turbo",
|
|
43131
|
+
"z-ai/glm-5-turbo",
|
|
43132
|
+
"x-ai/grok-4.20-beta",
|
|
43133
|
+
"nvidia/nemotron-3-super-120b-a12b",
|
|
43134
|
+
"arcee-ai/trinity-large-thinking",
|
|
43135
|
+
"openai/gpt-5.4-pro",
|
|
43136
|
+
"openai/gpt-5.4-nano"
|
|
43137
|
+
]
|
|
43138
|
+
},
|
|
43139
|
+
{
|
|
43140
|
+
label: "StepFun",
|
|
43141
|
+
value: "stepfun",
|
|
43142
|
+
builtin: true,
|
|
43143
|
+
base_url: "https://api.stepfun.ai/step_plan/v1",
|
|
43144
|
+
models: ["step-3.5-flash", "step-3.5-flash-2603"]
|
|
43145
|
+
},
|
|
42641
43146
|
{
|
|
42642
43147
|
label: "OpenRouter",
|
|
42643
43148
|
value: "openrouter",
|
|
@@ -42700,7 +43205,9 @@ async function getAvailable(ctx) {
|
|
|
42700
43205
|
const authPath = getActiveAuthPath();
|
|
42701
43206
|
if (!(0, import_fs11.existsSync)(authPath)) return false;
|
|
42702
43207
|
const auth = JSON.parse((0, import_fs11.readFileSync)(authPath, "utf-8"));
|
|
42703
|
-
|
|
43208
|
+
const provider = auth.providers?.[providerKey];
|
|
43209
|
+
if (!provider) return false;
|
|
43210
|
+
return !!(provider.tokens?.access_token || provider.access_token);
|
|
42704
43211
|
} catch {
|
|
42705
43212
|
return false;
|
|
42706
43213
|
}
|
|
@@ -43372,7 +43879,7 @@ async function codexLoginWorker(session, authPath) {
|
|
|
43372
43879
|
const startTime = Date.now();
|
|
43373
43880
|
const interval = POLL_DEFAULT_INTERVAL;
|
|
43374
43881
|
while (Date.now() - startTime < POLL_MAX_DURATION) {
|
|
43375
|
-
await new Promise((
|
|
43882
|
+
await new Promise((resolve11) => setTimeout(resolve11, interval));
|
|
43376
43883
|
if (session.status !== "pending") return;
|
|
43377
43884
|
try {
|
|
43378
43885
|
const pollRes = await fetch(CODEX_DEVICE_TOKEN_URL, {
|
|
@@ -43533,6 +44040,232 @@ codexAuthRoutes.post("/api/hermes/auth/codex/start", start);
|
|
|
43533
44040
|
codexAuthRoutes.get("/api/hermes/auth/codex/poll/:sessionId", poll);
|
|
43534
44041
|
codexAuthRoutes.get("/api/hermes/auth/codex/status", status);
|
|
43535
44042
|
|
|
44043
|
+
// packages/server/src/controllers/hermes/nous-auth.ts
|
|
44044
|
+
var import_crypto4 = require("crypto");
|
|
44045
|
+
var import_fs15 = require("fs");
|
|
44046
|
+
init_hermes_profile();
|
|
44047
|
+
init_logger();
|
|
44048
|
+
var NOUS_PORTAL_URL = "https://portal.nousresearch.com";
|
|
44049
|
+
var NOUS_CLIENT_ID = "hermes-cli";
|
|
44050
|
+
var NOUS_SCOPE = "inference:mint_agent_key";
|
|
44051
|
+
var POLL_MAX_DURATION2 = 15 * 60 * 1e3;
|
|
44052
|
+
var POLL_DEFAULT_INTERVAL2 = 5e3;
|
|
44053
|
+
var sessions2 = /* @__PURE__ */ new Map();
|
|
44054
|
+
function cleanupExpiredSessions2() {
|
|
44055
|
+
const now = Date.now();
|
|
44056
|
+
sessions2.forEach((s, id) => {
|
|
44057
|
+
if (now - s.createdAt > POLL_MAX_DURATION2 + 6e4) sessions2.delete(id);
|
|
44058
|
+
});
|
|
44059
|
+
}
|
|
44060
|
+
function loadAuthJson2(authPath) {
|
|
44061
|
+
try {
|
|
44062
|
+
return JSON.parse((0, import_fs15.readFileSync)(authPath, "utf-8"));
|
|
44063
|
+
} catch {
|
|
44064
|
+
return { version: 1 };
|
|
44065
|
+
}
|
|
44066
|
+
}
|
|
44067
|
+
function saveAuthJson2(authPath, data) {
|
|
44068
|
+
data.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
44069
|
+
const dir = authPath.substring(0, authPath.lastIndexOf("/"));
|
|
44070
|
+
if (!(0, import_fs15.existsSync)(dir)) (0, import_fs15.mkdirSync)(dir, { recursive: true });
|
|
44071
|
+
(0, import_fs15.writeFileSync)(authPath, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
|
|
44072
|
+
}
|
|
44073
|
+
async function nousLoginWorker(session, authPath) {
|
|
44074
|
+
const startTime = Date.now();
|
|
44075
|
+
let interval = session.interval || POLL_DEFAULT_INTERVAL2;
|
|
44076
|
+
while (Date.now() - startTime < POLL_MAX_DURATION2) {
|
|
44077
|
+
await new Promise((resolve11) => setTimeout(resolve11, interval));
|
|
44078
|
+
if (session.status !== "pending") return;
|
|
44079
|
+
try {
|
|
44080
|
+
const res = await fetch(`${NOUS_PORTAL_URL}/api/oauth/token`, {
|
|
44081
|
+
method: "POST",
|
|
44082
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
44083
|
+
body: new URLSearchParams({
|
|
44084
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
44085
|
+
client_id: NOUS_CLIENT_ID,
|
|
44086
|
+
device_code: session.deviceCode
|
|
44087
|
+
}).toString(),
|
|
44088
|
+
signal: AbortSignal.timeout(15e3)
|
|
44089
|
+
});
|
|
44090
|
+
if (res.ok) {
|
|
44091
|
+
const tokenData = await res.json();
|
|
44092
|
+
const inferenceBaseUrl = tokenData.inference_base_url || "https://inference-api.nousresearch.com/v1";
|
|
44093
|
+
let agentKey = "";
|
|
44094
|
+
let agentKeyExpiresAt = "";
|
|
44095
|
+
try {
|
|
44096
|
+
const mintRes = await fetch(`${NOUS_PORTAL_URL}/api/oauth/agent-key`, {
|
|
44097
|
+
method: "POST",
|
|
44098
|
+
headers: {
|
|
44099
|
+
"Authorization": `Bearer ${tokenData.access_token}`,
|
|
44100
|
+
"Content-Type": "application/json"
|
|
44101
|
+
},
|
|
44102
|
+
body: JSON.stringify({ min_ttl_seconds: 1800 }),
|
|
44103
|
+
signal: AbortSignal.timeout(15e3)
|
|
44104
|
+
});
|
|
44105
|
+
if (mintRes.ok) {
|
|
44106
|
+
const mintData = await mintRes.json();
|
|
44107
|
+
agentKey = mintData.api_key;
|
|
44108
|
+
agentKeyExpiresAt = mintData.expires_at;
|
|
44109
|
+
if (mintData.inference_base_url) {
|
|
44110
|
+
void mintData.inference_base_url;
|
|
44111
|
+
}
|
|
44112
|
+
}
|
|
44113
|
+
} catch (err) {
|
|
44114
|
+
logger.warn(err, "Nous agent key minting failed, proceeding without");
|
|
44115
|
+
}
|
|
44116
|
+
const auth = loadAuthJson2(authPath);
|
|
44117
|
+
if (!auth.providers) auth.providers = {};
|
|
44118
|
+
const now = /* @__PURE__ */ new Date();
|
|
44119
|
+
auth.providers["nous"] = {
|
|
44120
|
+
portal_base_url: NOUS_PORTAL_URL,
|
|
44121
|
+
inference_base_url: inferenceBaseUrl,
|
|
44122
|
+
client_id: NOUS_CLIENT_ID,
|
|
44123
|
+
scope: NOUS_SCOPE,
|
|
44124
|
+
token_type: "Bearer",
|
|
44125
|
+
access_token: tokenData.access_token,
|
|
44126
|
+
refresh_token: tokenData.refresh_token || null,
|
|
44127
|
+
obtained_at: now.toISOString(),
|
|
44128
|
+
expires_at: tokenData.expires_in ? new Date(now.getTime() + tokenData.expires_in * 1e3).toISOString() : null,
|
|
44129
|
+
agent_key: agentKey || null,
|
|
44130
|
+
agent_key_expires_at: agentKeyExpiresAt || null,
|
|
44131
|
+
agent_key_obtained_at: agentKey ? now.toISOString() : null
|
|
44132
|
+
};
|
|
44133
|
+
if (!auth.credential_pool) auth.credential_pool = {};
|
|
44134
|
+
auth.credential_pool["nous"] = [{
|
|
44135
|
+
id: `nous-${Date.now()}`,
|
|
44136
|
+
label: "Nous Portal",
|
|
44137
|
+
auth_type: "oauth",
|
|
44138
|
+
source: "device_code",
|
|
44139
|
+
priority: 0,
|
|
44140
|
+
access_token: tokenData.access_token,
|
|
44141
|
+
refresh_token: tokenData.refresh_token || null,
|
|
44142
|
+
portal_base_url: NOUS_PORTAL_URL,
|
|
44143
|
+
inference_base_url: inferenceBaseUrl,
|
|
44144
|
+
agent_key: agentKey || null,
|
|
44145
|
+
agent_key_expires_at: agentKeyExpiresAt || null,
|
|
44146
|
+
base_url: inferenceBaseUrl
|
|
44147
|
+
}];
|
|
44148
|
+
saveAuthJson2(authPath, auth);
|
|
44149
|
+
session.status = "approved";
|
|
44150
|
+
logger.info("Nous login successful");
|
|
44151
|
+
return;
|
|
44152
|
+
}
|
|
44153
|
+
const errData = await res.json().catch(() => ({}));
|
|
44154
|
+
const errorCode = errData.error;
|
|
44155
|
+
if (errorCode === "authorization_pending") {
|
|
44156
|
+
continue;
|
|
44157
|
+
}
|
|
44158
|
+
if (errorCode === "slow_down") {
|
|
44159
|
+
interval = Math.min(interval + 1e3, 3e4);
|
|
44160
|
+
continue;
|
|
44161
|
+
}
|
|
44162
|
+
if (errorCode === "access_denied" || errorCode === "expired_token") {
|
|
44163
|
+
session.status = errorCode === "access_denied" ? "denied" : "expired";
|
|
44164
|
+
return;
|
|
44165
|
+
}
|
|
44166
|
+
logger.error("Nous poll error: %s %s", res.status, errorCode);
|
|
44167
|
+
session.status = "error";
|
|
44168
|
+
session.error = `OAuth error: ${errorCode}`;
|
|
44169
|
+
return;
|
|
44170
|
+
} catch (err) {
|
|
44171
|
+
if (err.name === "TimeoutError" || err.name === "AbortError") continue;
|
|
44172
|
+
logger.error(err, "Nous poll error");
|
|
44173
|
+
session.status = "error";
|
|
44174
|
+
session.error = err.message;
|
|
44175
|
+
return;
|
|
44176
|
+
}
|
|
44177
|
+
}
|
|
44178
|
+
session.status = "expired";
|
|
44179
|
+
}
|
|
44180
|
+
async function start2(ctx) {
|
|
44181
|
+
try {
|
|
44182
|
+
cleanupExpiredSessions2();
|
|
44183
|
+
const res = await fetch(`${NOUS_PORTAL_URL}/api/oauth/device/code`, {
|
|
44184
|
+
method: "POST",
|
|
44185
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json" },
|
|
44186
|
+
body: new URLSearchParams({
|
|
44187
|
+
client_id: NOUS_CLIENT_ID,
|
|
44188
|
+
scope: NOUS_SCOPE
|
|
44189
|
+
}).toString(),
|
|
44190
|
+
signal: AbortSignal.timeout(15e3)
|
|
44191
|
+
});
|
|
44192
|
+
if (!res.ok) {
|
|
44193
|
+
let errorBody = null;
|
|
44194
|
+
try {
|
|
44195
|
+
errorBody = await res.json();
|
|
44196
|
+
} catch {
|
|
44197
|
+
}
|
|
44198
|
+
logger.error("Nous device code request failed: %d %s", res.status, errorBody);
|
|
44199
|
+
ctx.status = 502;
|
|
44200
|
+
ctx.body = { error: `Nous Portal error: ${res.status}` };
|
|
44201
|
+
return;
|
|
44202
|
+
}
|
|
44203
|
+
const data = await res.json();
|
|
44204
|
+
const sessionId = (0, import_crypto4.randomUUID)();
|
|
44205
|
+
const session = {
|
|
44206
|
+
id: sessionId,
|
|
44207
|
+
deviceCode: data.device_code,
|
|
44208
|
+
userCode: data.user_code,
|
|
44209
|
+
verificationUrl: data.verification_uri,
|
|
44210
|
+
verificationUrlComplete: data.verification_uri_complete,
|
|
44211
|
+
expiresIn: data.expires_in,
|
|
44212
|
+
interval: data.interval,
|
|
44213
|
+
status: "pending",
|
|
44214
|
+
createdAt: Date.now()
|
|
44215
|
+
};
|
|
44216
|
+
sessions2.set(sessionId, session);
|
|
44217
|
+
const authPath = getActiveAuthPath();
|
|
44218
|
+
nousLoginWorker(session, authPath).catch((err) => {
|
|
44219
|
+
logger.error(err, "Nous login worker error");
|
|
44220
|
+
session.status = "error";
|
|
44221
|
+
session.error = err.message;
|
|
44222
|
+
});
|
|
44223
|
+
ctx.body = {
|
|
44224
|
+
session_id: sessionId,
|
|
44225
|
+
user_code: data.user_code,
|
|
44226
|
+
verification_url: data.verification_uri_complete,
|
|
44227
|
+
expires_in: data.expires_in
|
|
44228
|
+
};
|
|
44229
|
+
} catch (err) {
|
|
44230
|
+
if (err.name === "TimeoutError" || err.name === "AbortError") {
|
|
44231
|
+
ctx.status = 504;
|
|
44232
|
+
ctx.body = { error: "Nous Portal timeout" };
|
|
44233
|
+
return;
|
|
44234
|
+
}
|
|
44235
|
+
ctx.status = 500;
|
|
44236
|
+
ctx.body = { error: err.message };
|
|
44237
|
+
}
|
|
44238
|
+
}
|
|
44239
|
+
async function poll2(ctx) {
|
|
44240
|
+
const session = sessions2.get(ctx.params.sessionId);
|
|
44241
|
+
if (!session) {
|
|
44242
|
+
ctx.status = 404;
|
|
44243
|
+
ctx.body = { error: "Session not found" };
|
|
44244
|
+
return;
|
|
44245
|
+
}
|
|
44246
|
+
ctx.body = { status: session.status, error: session.error || null };
|
|
44247
|
+
}
|
|
44248
|
+
async function status2(ctx) {
|
|
44249
|
+
try {
|
|
44250
|
+
const authPath = getActiveAuthPath();
|
|
44251
|
+
const auth = loadAuthJson2(authPath);
|
|
44252
|
+
const nousProvider = auth.providers?.["nous"];
|
|
44253
|
+
if (!nousProvider?.access_token) {
|
|
44254
|
+
ctx.body = { authenticated: false };
|
|
44255
|
+
return;
|
|
44256
|
+
}
|
|
44257
|
+
ctx.body = { authenticated: true };
|
|
44258
|
+
} catch {
|
|
44259
|
+
ctx.body = { authenticated: false };
|
|
44260
|
+
}
|
|
44261
|
+
}
|
|
44262
|
+
|
|
44263
|
+
// packages/server/src/routes/hermes/nous-auth.ts
|
|
44264
|
+
var nousAuthRoutes = new router_default();
|
|
44265
|
+
nousAuthRoutes.post("/api/hermes/auth/nous/start", start2);
|
|
44266
|
+
nousAuthRoutes.get("/api/hermes/auth/nous/poll/:sessionId", poll2);
|
|
44267
|
+
nousAuthRoutes.get("/api/hermes/auth/nous/status", status2);
|
|
44268
|
+
|
|
43536
44269
|
// packages/server/src/controllers/hermes/gateways.ts
|
|
43537
44270
|
async function list5(ctx) {
|
|
43538
44271
|
const mgr = getGatewayManagerInstance();
|
|
@@ -43544,7 +44277,7 @@ async function list5(ctx) {
|
|
|
43544
44277
|
const gateways = await mgr.listAll();
|
|
43545
44278
|
ctx.body = { gateways };
|
|
43546
44279
|
}
|
|
43547
|
-
async function
|
|
44280
|
+
async function start3(ctx) {
|
|
43548
44281
|
const mgr = getGatewayManagerInstance();
|
|
43549
44282
|
if (!mgr) {
|
|
43550
44283
|
ctx.status = 503;
|
|
@@ -43552,8 +44285,8 @@ async function start2(ctx) {
|
|
|
43552
44285
|
return;
|
|
43553
44286
|
}
|
|
43554
44287
|
try {
|
|
43555
|
-
const
|
|
43556
|
-
ctx.body = { success: true, gateway:
|
|
44288
|
+
const status3 = await mgr.start(ctx.params.name);
|
|
44289
|
+
ctx.body = { success: true, gateway: status3 };
|
|
43557
44290
|
} catch (err) {
|
|
43558
44291
|
ctx.status = 500;
|
|
43559
44292
|
ctx.body = { error: err.message };
|
|
@@ -43581,14 +44314,14 @@ async function health(ctx) {
|
|
|
43581
44314
|
ctx.body = { error: "GatewayManager not initialized" };
|
|
43582
44315
|
return;
|
|
43583
44316
|
}
|
|
43584
|
-
const
|
|
43585
|
-
ctx.body = { gateway:
|
|
44317
|
+
const status3 = await mgr.detectStatus(ctx.params.name);
|
|
44318
|
+
ctx.body = { gateway: status3 };
|
|
43586
44319
|
}
|
|
43587
44320
|
|
|
43588
44321
|
// packages/server/src/routes/hermes/gateways.ts
|
|
43589
44322
|
var gatewayRoutes = new router_default();
|
|
43590
44323
|
gatewayRoutes.get("/api/hermes/gateways", list5);
|
|
43591
|
-
gatewayRoutes.post("/api/hermes/gateways/:name/start",
|
|
44324
|
+
gatewayRoutes.post("/api/hermes/gateways/:name/start", start3);
|
|
43592
44325
|
gatewayRoutes.post("/api/hermes/gateways/:name/stop", stop);
|
|
43593
44326
|
gatewayRoutes.get("/api/hermes/gateways/:name/health", health);
|
|
43594
44327
|
|
|
@@ -44363,7 +45096,7 @@ var import_url2 = __toESM(require("url"), 1);
|
|
|
44363
45096
|
var URLSearchParams_default = import_url2.default.URLSearchParams;
|
|
44364
45097
|
|
|
44365
45098
|
// node_modules/axios/lib/platform/node/index.js
|
|
44366
|
-
var
|
|
45099
|
+
var import_crypto5 = __toESM(require("crypto"), 1);
|
|
44367
45100
|
var ALPHA = "abcdefghijklmnopqrstuvwxyz";
|
|
44368
45101
|
var DIGIT = "0123456789";
|
|
44369
45102
|
var ALPHABET = {
|
|
@@ -44375,7 +45108,7 @@ var generateString = (size = 16, alphabet = ALPHABET.ALPHA_DIGIT) => {
|
|
|
44375
45108
|
let str2 = "";
|
|
44376
45109
|
const { length } = alphabet;
|
|
44377
45110
|
const randomValues = new Uint32Array(size);
|
|
44378
|
-
|
|
45111
|
+
import_crypto5.default.randomFillSync(randomValues);
|
|
44379
45112
|
for (let i = 0; i < size; i++) {
|
|
44380
45113
|
str2 += alphabet[randomValues[i] % length];
|
|
44381
45114
|
}
|
|
@@ -44582,8 +45315,8 @@ var defaults = {
|
|
|
44582
45315
|
FormData: platform_default.classes.FormData,
|
|
44583
45316
|
Blob: platform_default.classes.Blob
|
|
44584
45317
|
},
|
|
44585
|
-
validateStatus: function validateStatus(
|
|
44586
|
-
return
|
|
45318
|
+
validateStatus: function validateStatus(status3) {
|
|
45319
|
+
return status3 >= 200 && status3 < 300;
|
|
44587
45320
|
},
|
|
44588
45321
|
headers: {
|
|
44589
45322
|
common: {
|
|
@@ -44941,10 +45674,10 @@ var CanceledError = class extends AxiosError_default {
|
|
|
44941
45674
|
var CanceledError_default = CanceledError;
|
|
44942
45675
|
|
|
44943
45676
|
// node_modules/axios/lib/core/settle.js
|
|
44944
|
-
function settle(
|
|
45677
|
+
function settle(resolve11, reject, response) {
|
|
44945
45678
|
const validateStatus2 = response.config.validateStatus;
|
|
44946
45679
|
if (!response.status || !validateStatus2 || validateStatus2(response.status)) {
|
|
44947
|
-
|
|
45680
|
+
resolve11(response);
|
|
44948
45681
|
} else {
|
|
44949
45682
|
reject(
|
|
44950
45683
|
new AxiosError_default(
|
|
@@ -45731,7 +46464,7 @@ function setProxy(options, configProxy, location) {
|
|
|
45731
46464
|
}
|
|
45732
46465
|
var isHttpAdapterSupported = typeof process !== "undefined" && utils_default.kindOf(process) === "process";
|
|
45733
46466
|
var wrapAsync = (asyncExecutor) => {
|
|
45734
|
-
return new Promise((
|
|
46467
|
+
return new Promise((resolve11, reject) => {
|
|
45735
46468
|
let onDone;
|
|
45736
46469
|
let isDone;
|
|
45737
46470
|
const done = (value, isRejected) => {
|
|
@@ -45741,7 +46474,7 @@ var wrapAsync = (asyncExecutor) => {
|
|
|
45741
46474
|
};
|
|
45742
46475
|
const _resolve = (value) => {
|
|
45743
46476
|
done(value);
|
|
45744
|
-
|
|
46477
|
+
resolve11(value);
|
|
45745
46478
|
};
|
|
45746
46479
|
const _reject = (reason) => {
|
|
45747
46480
|
done(reason, true);
|
|
@@ -45778,17 +46511,17 @@ var http2Transport = {
|
|
|
45778
46511
|
req.once("response", (responseHeaders) => {
|
|
45779
46512
|
const response = req;
|
|
45780
46513
|
responseHeaders = Object.assign({}, responseHeaders);
|
|
45781
|
-
const
|
|
46514
|
+
const status3 = responseHeaders[HTTP2_HEADER_STATUS];
|
|
45782
46515
|
delete responseHeaders[HTTP2_HEADER_STATUS];
|
|
45783
46516
|
response.headers = responseHeaders;
|
|
45784
|
-
response.statusCode = +
|
|
46517
|
+
response.statusCode = +status3;
|
|
45785
46518
|
cb(response);
|
|
45786
46519
|
});
|
|
45787
46520
|
return req;
|
|
45788
46521
|
}
|
|
45789
46522
|
};
|
|
45790
46523
|
var http_default = isHttpAdapterSupported && function httpAdapter(config2) {
|
|
45791
|
-
return wrapAsync(async function dispatchHttpRequest(
|
|
46524
|
+
return wrapAsync(async function dispatchHttpRequest(resolve11, reject, onDone) {
|
|
45792
46525
|
let { data, lookup, family, httpVersion = 1, http2Options } = config2;
|
|
45793
46526
|
const { responseType, responseEncoding } = config2;
|
|
45794
46527
|
const method = config2.method.toUpperCase();
|
|
@@ -45878,7 +46611,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config2) {
|
|
|
45878
46611
|
}
|
|
45879
46612
|
let convertedData;
|
|
45880
46613
|
if (method !== "GET") {
|
|
45881
|
-
return settle(
|
|
46614
|
+
return settle(resolve11, reject, {
|
|
45882
46615
|
status: 405,
|
|
45883
46616
|
statusText: "method not allowed",
|
|
45884
46617
|
headers: {},
|
|
@@ -45900,7 +46633,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config2) {
|
|
|
45900
46633
|
} else if (responseType === "stream") {
|
|
45901
46634
|
convertedData = import_stream5.default.Readable.from(convertedData);
|
|
45902
46635
|
}
|
|
45903
|
-
return settle(
|
|
46636
|
+
return settle(resolve11, reject, {
|
|
45904
46637
|
data: convertedData,
|
|
45905
46638
|
status: 200,
|
|
45906
46639
|
statusText: "OK",
|
|
@@ -46141,7 +46874,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config2) {
|
|
|
46141
46874
|
};
|
|
46142
46875
|
if (responseType === "stream") {
|
|
46143
46876
|
response.data = responseStream;
|
|
46144
|
-
settle(
|
|
46877
|
+
settle(resolve11, reject, response);
|
|
46145
46878
|
} else {
|
|
46146
46879
|
const responseBuffer = [];
|
|
46147
46880
|
let totalResponseBytes = 0;
|
|
@@ -46191,7 +46924,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config2) {
|
|
|
46191
46924
|
} catch (err) {
|
|
46192
46925
|
return reject(AxiosError_default.from(err, null, config2, response.request, response));
|
|
46193
46926
|
}
|
|
46194
|
-
settle(
|
|
46927
|
+
settle(resolve11, reject, response);
|
|
46195
46928
|
});
|
|
46196
46929
|
}
|
|
46197
46930
|
abortEmitter.once("abort", (err) => {
|
|
@@ -46452,7 +47185,7 @@ var resolveConfig_default = (config2) => {
|
|
|
46452
47185
|
// node_modules/axios/lib/adapters/xhr.js
|
|
46453
47186
|
var isXHRAdapterSupported = typeof XMLHttpRequest !== "undefined";
|
|
46454
47187
|
var xhr_default = isXHRAdapterSupported && function(config2) {
|
|
46455
|
-
return new Promise(function dispatchXhrRequest(
|
|
47188
|
+
return new Promise(function dispatchXhrRequest(resolve11, reject) {
|
|
46456
47189
|
const _config = resolveConfig_default(config2);
|
|
46457
47190
|
let requestData = _config.data;
|
|
46458
47191
|
const requestHeaders = AxiosHeaders_default.from(_config.headers).normalize();
|
|
@@ -46487,7 +47220,7 @@ var xhr_default = isXHRAdapterSupported && function(config2) {
|
|
|
46487
47220
|
};
|
|
46488
47221
|
settle(
|
|
46489
47222
|
function _resolve(value) {
|
|
46490
|
-
|
|
47223
|
+
resolve11(value);
|
|
46491
47224
|
done();
|
|
46492
47225
|
},
|
|
46493
47226
|
function _reject(err) {
|
|
@@ -46518,7 +47251,7 @@ var xhr_default = isXHRAdapterSupported && function(config2) {
|
|
|
46518
47251
|
reject(new AxiosError_default("Request aborted", AxiosError_default.ECONNABORTED, config2, request));
|
|
46519
47252
|
request = null;
|
|
46520
47253
|
};
|
|
46521
|
-
request.onerror = function
|
|
47254
|
+
request.onerror = function handleError2(event) {
|
|
46522
47255
|
const msg = event && event.message ? event.message : "Network Error";
|
|
46523
47256
|
const err = new AxiosError_default(msg, AxiosError_default.ERR_NETWORK, config2, request);
|
|
46524
47257
|
err.event = event || null;
|
|
@@ -46887,8 +47620,8 @@ var factory = (env) => {
|
|
|
46887
47620
|
config2
|
|
46888
47621
|
);
|
|
46889
47622
|
!isStreamResponse && unsubscribe && unsubscribe();
|
|
46890
|
-
return await new Promise((
|
|
46891
|
-
settle(
|
|
47623
|
+
return await new Promise((resolve11, reject) => {
|
|
47624
|
+
settle(resolve11, reject, {
|
|
46892
47625
|
data: responseData,
|
|
46893
47626
|
headers: AxiosHeaders_default.from(response.headers),
|
|
46894
47627
|
status: response.status,
|
|
@@ -47314,8 +48047,8 @@ var CancelToken = class _CancelToken {
|
|
|
47314
48047
|
throw new TypeError("executor must be a function.");
|
|
47315
48048
|
}
|
|
47316
48049
|
let resolvePromise;
|
|
47317
|
-
this.promise = new Promise(function promiseExecutor(
|
|
47318
|
-
resolvePromise =
|
|
48050
|
+
this.promise = new Promise(function promiseExecutor(resolve11) {
|
|
48051
|
+
resolvePromise = resolve11;
|
|
47319
48052
|
});
|
|
47320
48053
|
const token = this;
|
|
47321
48054
|
this.promise.then((cancel) => {
|
|
@@ -47328,9 +48061,9 @@ var CancelToken = class _CancelToken {
|
|
|
47328
48061
|
});
|
|
47329
48062
|
this.promise.then = (onfulfilled) => {
|
|
47330
48063
|
let _resolve;
|
|
47331
|
-
const promise = new Promise((
|
|
47332
|
-
token.subscribe(
|
|
47333
|
-
_resolve =
|
|
48064
|
+
const promise = new Promise((resolve11) => {
|
|
48065
|
+
token.subscribe(resolve11);
|
|
48066
|
+
_resolve = resolve11;
|
|
47334
48067
|
}).then(onfulfilled);
|
|
47335
48068
|
promise.cancel = function reject() {
|
|
47336
48069
|
token.unsubscribe(_resolve);
|
|
@@ -47577,11 +48310,11 @@ async function pollStatus(ctx) {
|
|
|
47577
48310
|
try {
|
|
47578
48311
|
const res = await axios_default.get(`${ILINK_BASE}/ilink/bot/get_qrcode_status`, { params: { qrcode }, timeout: 35e3 });
|
|
47579
48312
|
const data = res.data;
|
|
47580
|
-
const
|
|
47581
|
-
if (
|
|
48313
|
+
const status3 = data?.status || "wait";
|
|
48314
|
+
if (status3 === "confirmed") {
|
|
47582
48315
|
ctx.body = { status: "confirmed", account_id: data.ilink_bot_id, token: data.bot_token, base_url: data.baseurl };
|
|
47583
48316
|
} else {
|
|
47584
|
-
ctx.body = { status:
|
|
48317
|
+
ctx.body = { status: status3 };
|
|
47585
48318
|
}
|
|
47586
48319
|
} catch (err) {
|
|
47587
48320
|
ctx.status = 500;
|
|
@@ -47650,6 +48383,1073 @@ weixinRoutes.get("/api/hermes/weixin/qrcode", getQrcode);
|
|
|
47650
48383
|
weixinRoutes.get("/api/hermes/weixin/qrcode/status", pollStatus);
|
|
47651
48384
|
weixinRoutes.post("/api/hermes/weixin/save", save2);
|
|
47652
48385
|
|
|
48386
|
+
// packages/server/src/services/hermes/file-provider.ts
|
|
48387
|
+
var import_promises14 = require("fs/promises");
|
|
48388
|
+
var import_path17 = require("path");
|
|
48389
|
+
var import_child_process5 = require("child_process");
|
|
48390
|
+
var import_util5 = require("util");
|
|
48391
|
+
var import_fs16 = require("fs");
|
|
48392
|
+
init_js_yaml();
|
|
48393
|
+
init_hermes_profile();
|
|
48394
|
+
var execFileAsync3 = (0, import_util5.promisify)(import_child_process5.execFile);
|
|
48395
|
+
var MAX_DOWNLOAD_SIZE = parseInt(process.env.MAX_DOWNLOAD_SIZE || "", 10) || 100 * 1024 * 1024;
|
|
48396
|
+
var BACKEND_TIMEOUT = 3e4;
|
|
48397
|
+
var MAX_EDIT_SIZE = parseInt(process.env.MAX_EDIT_SIZE || "", 10) || 10 * 1024 * 1024;
|
|
48398
|
+
var SENSITIVE_FILES = /* @__PURE__ */ new Set([".env", "auth.json"]);
|
|
48399
|
+
function validatePath(filePath) {
|
|
48400
|
+
if (!filePath) throw Object.assign(new Error("Missing file path"), { code: "missing_path" });
|
|
48401
|
+
const resolved = (0, import_path17.resolve)(filePath);
|
|
48402
|
+
const normalized = (0, import_path17.normalize)(resolved);
|
|
48403
|
+
if (normalized.includes("..")) {
|
|
48404
|
+
throw Object.assign(new Error("Invalid file path"), { code: "invalid_path" });
|
|
48405
|
+
}
|
|
48406
|
+
if (!(0, import_path17.isAbsolute)(normalized)) {
|
|
48407
|
+
throw Object.assign(new Error("Path must be absolute"), { code: "invalid_path" });
|
|
48408
|
+
}
|
|
48409
|
+
return normalized;
|
|
48410
|
+
}
|
|
48411
|
+
function isInUploadDir(filePath) {
|
|
48412
|
+
const normalized = (0, import_path17.normalize)((0, import_path17.resolve)(filePath));
|
|
48413
|
+
const uploadNormalized = (0, import_path17.normalize)((0, import_path17.resolve)(config.uploadDir));
|
|
48414
|
+
return normalized.startsWith(uploadNormalized + "/") || normalized.startsWith(uploadNormalized + "\\") || normalized === uploadNormalized;
|
|
48415
|
+
}
|
|
48416
|
+
function isSensitivePath(relativePath) {
|
|
48417
|
+
const parts = relativePath.replace(/\\/g, "/").split("/");
|
|
48418
|
+
const fileName = parts[parts.length - 1];
|
|
48419
|
+
return SENSITIVE_FILES.has(fileName);
|
|
48420
|
+
}
|
|
48421
|
+
function resolveHermesPath(relativePath) {
|
|
48422
|
+
const homeDir = getActiveProfileDir();
|
|
48423
|
+
if (!relativePath || relativePath === "." || relativePath === "/") {
|
|
48424
|
+
return homeDir;
|
|
48425
|
+
}
|
|
48426
|
+
const normalized = (0, import_path17.normalize)(relativePath).replace(/\\/g, "/");
|
|
48427
|
+
if (normalized.startsWith("..") || normalized.includes("/../") || normalized.startsWith("/")) {
|
|
48428
|
+
throw Object.assign(new Error("Invalid file path"), { code: "invalid_path" });
|
|
48429
|
+
}
|
|
48430
|
+
const resolved = (0, import_path17.resolve)(homeDir, normalized);
|
|
48431
|
+
if (!resolved.startsWith(homeDir)) {
|
|
48432
|
+
throw Object.assign(new Error("Path traversal detected"), { code: "invalid_path" });
|
|
48433
|
+
}
|
|
48434
|
+
return resolved;
|
|
48435
|
+
}
|
|
48436
|
+
var LocalFileProvider = class {
|
|
48437
|
+
type = "local";
|
|
48438
|
+
async readFile(filePath) {
|
|
48439
|
+
const p = validatePath(filePath);
|
|
48440
|
+
const s = await (0, import_promises14.stat)(p);
|
|
48441
|
+
if (!s.isFile()) throw Object.assign(new Error("Not a file"), { code: "not_found" });
|
|
48442
|
+
if (s.size > MAX_DOWNLOAD_SIZE) {
|
|
48443
|
+
throw Object.assign(new Error(`File too large: ${s.size} bytes`), { code: "file_too_large" });
|
|
48444
|
+
}
|
|
48445
|
+
return (0, import_promises14.readFile)(p);
|
|
48446
|
+
}
|
|
48447
|
+
async exists(filePath) {
|
|
48448
|
+
try {
|
|
48449
|
+
const p = validatePath(filePath);
|
|
48450
|
+
const s = await (0, import_promises14.stat)(p);
|
|
48451
|
+
return s.isFile();
|
|
48452
|
+
} catch {
|
|
48453
|
+
return false;
|
|
48454
|
+
}
|
|
48455
|
+
}
|
|
48456
|
+
async listDir(dirPath) {
|
|
48457
|
+
const p = validatePath(dirPath);
|
|
48458
|
+
const homeDir = getActiveProfileDir();
|
|
48459
|
+
const entries = await (0, import_promises14.readdir)(p, { withFileTypes: true });
|
|
48460
|
+
const results = [];
|
|
48461
|
+
for (const entry of entries) {
|
|
48462
|
+
try {
|
|
48463
|
+
const fullPath = (0, import_path17.resolve)(p, entry.name);
|
|
48464
|
+
const s = await (0, import_promises14.stat)(fullPath);
|
|
48465
|
+
const relPath = fullPath.startsWith(homeDir) ? fullPath.slice(homeDir.length + 1) : entry.name;
|
|
48466
|
+
results.push({
|
|
48467
|
+
name: entry.name,
|
|
48468
|
+
path: relPath,
|
|
48469
|
+
isDir: s.isDirectory(),
|
|
48470
|
+
size: s.size,
|
|
48471
|
+
modTime: s.mtime.toISOString()
|
|
48472
|
+
});
|
|
48473
|
+
} catch {
|
|
48474
|
+
}
|
|
48475
|
+
}
|
|
48476
|
+
return results;
|
|
48477
|
+
}
|
|
48478
|
+
async stat(filePath) {
|
|
48479
|
+
const p = validatePath(filePath);
|
|
48480
|
+
const homeDir = getActiveProfileDir();
|
|
48481
|
+
const s = await (0, import_promises14.stat)(p);
|
|
48482
|
+
const relPath = p.startsWith(homeDir) ? p.slice(homeDir.length + 1) : (0, import_path17.basename)(p);
|
|
48483
|
+
return {
|
|
48484
|
+
name: (0, import_path17.basename)(p),
|
|
48485
|
+
path: relPath || (0, import_path17.basename)(p),
|
|
48486
|
+
isDir: s.isDirectory(),
|
|
48487
|
+
size: s.size,
|
|
48488
|
+
modTime: s.mtime.toISOString()
|
|
48489
|
+
};
|
|
48490
|
+
}
|
|
48491
|
+
async writeFile(filePath, content) {
|
|
48492
|
+
const p = validatePath(filePath);
|
|
48493
|
+
await (0, import_promises14.writeFile)(p, content);
|
|
48494
|
+
}
|
|
48495
|
+
async deleteFile(filePath) {
|
|
48496
|
+
const p = validatePath(filePath);
|
|
48497
|
+
const s = await (0, import_promises14.stat)(p);
|
|
48498
|
+
if (!s.isFile()) throw Object.assign(new Error("Not a file"), { code: "not_found" });
|
|
48499
|
+
await (0, import_promises14.rm)(p);
|
|
48500
|
+
}
|
|
48501
|
+
async deleteDir(dirPath) {
|
|
48502
|
+
const p = validatePath(dirPath);
|
|
48503
|
+
const s = await (0, import_promises14.stat)(p);
|
|
48504
|
+
if (!s.isDirectory()) throw Object.assign(new Error("Not a directory"), { code: "not_found" });
|
|
48505
|
+
await (0, import_promises14.rm)(p, { recursive: true });
|
|
48506
|
+
}
|
|
48507
|
+
async renameFile(oldPath, newPath) {
|
|
48508
|
+
const op = validatePath(oldPath);
|
|
48509
|
+
const np = validatePath(newPath);
|
|
48510
|
+
await (0, import_promises14.rename)(op, np);
|
|
48511
|
+
}
|
|
48512
|
+
async mkDir(dirPath) {
|
|
48513
|
+
const p = validatePath(dirPath);
|
|
48514
|
+
await (0, import_promises14.mkdir)(p, { recursive: true });
|
|
48515
|
+
}
|
|
48516
|
+
async copyFile(srcPath, destPath) {
|
|
48517
|
+
const sp = validatePath(srcPath);
|
|
48518
|
+
const dp = validatePath(destPath);
|
|
48519
|
+
await (0, import_promises14.copyFile)(sp, dp);
|
|
48520
|
+
}
|
|
48521
|
+
};
|
|
48522
|
+
function parseLsOutput(output, parentRelPath) {
|
|
48523
|
+
const entries = [];
|
|
48524
|
+
for (const line of output.split("\n")) {
|
|
48525
|
+
const trimmed = line.trim();
|
|
48526
|
+
if (!trimmed || trimmed.startsWith("total ")) continue;
|
|
48527
|
+
const parts = trimmed.split(/\s+/);
|
|
48528
|
+
if (parts.length < 7) continue;
|
|
48529
|
+
const permissions = parts[0];
|
|
48530
|
+
const size = parseInt(parts[4], 10) || 0;
|
|
48531
|
+
const modTime = parts[5];
|
|
48532
|
+
const name = parts.slice(6).join(" ");
|
|
48533
|
+
if (name === "." || name === "..") continue;
|
|
48534
|
+
const isDir = permissions.startsWith("d");
|
|
48535
|
+
const relPath = parentRelPath ? `${parentRelPath}/${name}` : name;
|
|
48536
|
+
entries.push({ name, path: relPath, isDir, size, modTime: modTime.includes("T") ? modTime : new Date(modTime).toISOString() });
|
|
48537
|
+
}
|
|
48538
|
+
return entries;
|
|
48539
|
+
}
|
|
48540
|
+
function parseStatOutput(output, relativePath) {
|
|
48541
|
+
const parts = output.trim().split("|");
|
|
48542
|
+
if (parts.length < 4) throw Object.assign(new Error("Failed to parse stat output"), { code: "backend_error" });
|
|
48543
|
+
const name = (0, import_path17.basename)(parts[0]);
|
|
48544
|
+
const fileType = parts[1].toLowerCase();
|
|
48545
|
+
const size = parseInt(parts[2], 10) || 0;
|
|
48546
|
+
const modEpoch = parseInt(parts[3], 10) || 0;
|
|
48547
|
+
const isDir = fileType.includes("directory");
|
|
48548
|
+
return {
|
|
48549
|
+
name,
|
|
48550
|
+
path: relativePath,
|
|
48551
|
+
isDir,
|
|
48552
|
+
size,
|
|
48553
|
+
modTime: new Date(modEpoch * 1e3).toISOString()
|
|
48554
|
+
};
|
|
48555
|
+
}
|
|
48556
|
+
var DockerFileProvider = class {
|
|
48557
|
+
type = "docker";
|
|
48558
|
+
containerName;
|
|
48559
|
+
constructor(containerName) {
|
|
48560
|
+
this.containerName = containerName;
|
|
48561
|
+
}
|
|
48562
|
+
async readFile(filePath) {
|
|
48563
|
+
const p = validatePath(filePath);
|
|
48564
|
+
try {
|
|
48565
|
+
const { stdout } = await execFileAsync3("docker", [
|
|
48566
|
+
"exec",
|
|
48567
|
+
this.containerName,
|
|
48568
|
+
"cat",
|
|
48569
|
+
p
|
|
48570
|
+
], { maxBuffer: MAX_DOWNLOAD_SIZE, timeout: BACKEND_TIMEOUT, encoding: "buffer" });
|
|
48571
|
+
return stdout;
|
|
48572
|
+
} catch (err) {
|
|
48573
|
+
if (err.code === "ETIMEDOUT" || err.killed) {
|
|
48574
|
+
throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48575
|
+
}
|
|
48576
|
+
if (err.stderr && /no such file/i.test(String(err.stderr))) {
|
|
48577
|
+
throw Object.assign(new Error("File not found in container"), { code: "not_found" });
|
|
48578
|
+
}
|
|
48579
|
+
throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
|
|
48580
|
+
}
|
|
48581
|
+
}
|
|
48582
|
+
async exists(filePath) {
|
|
48583
|
+
const p = validatePath(filePath);
|
|
48584
|
+
try {
|
|
48585
|
+
await execFileAsync3("docker", [
|
|
48586
|
+
"exec",
|
|
48587
|
+
this.containerName,
|
|
48588
|
+
"test",
|
|
48589
|
+
"-f",
|
|
48590
|
+
p
|
|
48591
|
+
], { timeout: 5e3 });
|
|
48592
|
+
return true;
|
|
48593
|
+
} catch {
|
|
48594
|
+
return false;
|
|
48595
|
+
}
|
|
48596
|
+
}
|
|
48597
|
+
async listDir(dirPath) {
|
|
48598
|
+
const p = validatePath(dirPath);
|
|
48599
|
+
try {
|
|
48600
|
+
const { stdout } = await execFileAsync3("docker", [
|
|
48601
|
+
"exec",
|
|
48602
|
+
this.containerName,
|
|
48603
|
+
"ls",
|
|
48604
|
+
"-la",
|
|
48605
|
+
"--time-style=+%Y-%m-%dT%H:%M:%S",
|
|
48606
|
+
p
|
|
48607
|
+
], { maxBuffer: 10 * 1024 * 1024, timeout: BACKEND_TIMEOUT });
|
|
48608
|
+
const homeDir = getActiveProfileDir();
|
|
48609
|
+
const relParent = p.startsWith(homeDir) ? p.slice(homeDir.length + 1).replace(/\\/g, "/") : "";
|
|
48610
|
+
return parseLsOutput(stdout, relParent);
|
|
48611
|
+
} catch (err) {
|
|
48612
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48613
|
+
if (err.stderr && /no such file|not a directory/i.test(String(err.stderr)))
|
|
48614
|
+
throw Object.assign(new Error("Directory not found"), { code: "not_found" });
|
|
48615
|
+
throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
|
|
48616
|
+
}
|
|
48617
|
+
}
|
|
48618
|
+
async stat(filePath) {
|
|
48619
|
+
const p = validatePath(filePath);
|
|
48620
|
+
try {
|
|
48621
|
+
const { stdout } = await execFileAsync3("docker", [
|
|
48622
|
+
"exec",
|
|
48623
|
+
this.containerName,
|
|
48624
|
+
"stat",
|
|
48625
|
+
"-c",
|
|
48626
|
+
"%n|%F|%s|%Y",
|
|
48627
|
+
p
|
|
48628
|
+
], { timeout: BACKEND_TIMEOUT });
|
|
48629
|
+
const homeDir = getActiveProfileDir();
|
|
48630
|
+
const relPath = p.startsWith(homeDir) ? p.slice(homeDir.length + 1).replace(/\\/g, "/") : (0, import_path17.basename)(p);
|
|
48631
|
+
return parseStatOutput(stdout, relPath);
|
|
48632
|
+
} catch (err) {
|
|
48633
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48634
|
+
if (err.stderr && /no such file/i.test(String(err.stderr))) throw Object.assign(new Error("Not found"), { code: "not_found" });
|
|
48635
|
+
throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
|
|
48636
|
+
}
|
|
48637
|
+
}
|
|
48638
|
+
async writeFile(filePath, content) {
|
|
48639
|
+
const p = validatePath(filePath);
|
|
48640
|
+
try {
|
|
48641
|
+
await execFileAsync3("docker", [
|
|
48642
|
+
"exec",
|
|
48643
|
+
"-i",
|
|
48644
|
+
this.containerName,
|
|
48645
|
+
"sh",
|
|
48646
|
+
"-c",
|
|
48647
|
+
`cat > '${p.replace(/'/g, "'\\''")}'`
|
|
48648
|
+
], { timeout: BACKEND_TIMEOUT, input: content });
|
|
48649
|
+
} catch (err) {
|
|
48650
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48651
|
+
throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
|
|
48652
|
+
}
|
|
48653
|
+
}
|
|
48654
|
+
async deleteFile(filePath) {
|
|
48655
|
+
const p = validatePath(filePath);
|
|
48656
|
+
try {
|
|
48657
|
+
await execFileAsync3("docker", ["exec", this.containerName, "rm", p], { timeout: BACKEND_TIMEOUT });
|
|
48658
|
+
} catch (err) {
|
|
48659
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48660
|
+
throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
|
|
48661
|
+
}
|
|
48662
|
+
}
|
|
48663
|
+
async deleteDir(dirPath) {
|
|
48664
|
+
const p = validatePath(dirPath);
|
|
48665
|
+
try {
|
|
48666
|
+
await execFileAsync3("docker", ["exec", this.containerName, "rm", "-rf", p], { timeout: BACKEND_TIMEOUT });
|
|
48667
|
+
} catch (err) {
|
|
48668
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48669
|
+
throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
|
|
48670
|
+
}
|
|
48671
|
+
}
|
|
48672
|
+
async renameFile(oldPath, newPath) {
|
|
48673
|
+
const op = validatePath(oldPath);
|
|
48674
|
+
const np = validatePath(newPath);
|
|
48675
|
+
try {
|
|
48676
|
+
await execFileAsync3("docker", ["exec", this.containerName, "mv", op, np], { timeout: BACKEND_TIMEOUT });
|
|
48677
|
+
} catch (err) {
|
|
48678
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48679
|
+
throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
|
|
48680
|
+
}
|
|
48681
|
+
}
|
|
48682
|
+
async mkDir(dirPath) {
|
|
48683
|
+
const p = validatePath(dirPath);
|
|
48684
|
+
try {
|
|
48685
|
+
await execFileAsync3("docker", ["exec", this.containerName, "mkdir", "-p", p], { timeout: BACKEND_TIMEOUT });
|
|
48686
|
+
} catch (err) {
|
|
48687
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48688
|
+
throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
|
|
48689
|
+
}
|
|
48690
|
+
}
|
|
48691
|
+
async copyFile(srcPath, destPath) {
|
|
48692
|
+
const sp = validatePath(srcPath);
|
|
48693
|
+
const dp = validatePath(destPath);
|
|
48694
|
+
try {
|
|
48695
|
+
await execFileAsync3("docker", ["exec", this.containerName, "cp", sp, dp], { timeout: BACKEND_TIMEOUT });
|
|
48696
|
+
} catch (err) {
|
|
48697
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48698
|
+
throw Object.assign(new Error(`Docker error: ${err.message}`), { code: "backend_error" });
|
|
48699
|
+
}
|
|
48700
|
+
}
|
|
48701
|
+
};
|
|
48702
|
+
var SSHFileProvider = class {
|
|
48703
|
+
type = "ssh";
|
|
48704
|
+
host;
|
|
48705
|
+
user;
|
|
48706
|
+
keyPath;
|
|
48707
|
+
constructor(host, user, keyPath) {
|
|
48708
|
+
this.host = host;
|
|
48709
|
+
this.user = user;
|
|
48710
|
+
this.keyPath = keyPath;
|
|
48711
|
+
}
|
|
48712
|
+
sshArgs() {
|
|
48713
|
+
const args2 = ["-o", "StrictHostKeyChecking=no", "-o", "BatchMode=yes"];
|
|
48714
|
+
if (this.keyPath) args2.push("-i", this.keyPath);
|
|
48715
|
+
args2.push(`${this.user}@${this.host}`);
|
|
48716
|
+
return args2;
|
|
48717
|
+
}
|
|
48718
|
+
/**
|
|
48719
|
+
* Shell-escape a string for safe use in a remote SSH command.
|
|
48720
|
+
* Wraps in single quotes and escapes embedded single quotes.
|
|
48721
|
+
*/
|
|
48722
|
+
shellEscape(s) {
|
|
48723
|
+
return "'" + s.replace(/'/g, "'\\''") + "'";
|
|
48724
|
+
}
|
|
48725
|
+
async readFile(filePath) {
|
|
48726
|
+
const p = validatePath(filePath);
|
|
48727
|
+
try {
|
|
48728
|
+
const { stdout } = await execFileAsync3("ssh", [
|
|
48729
|
+
...this.sshArgs(),
|
|
48730
|
+
`cat ${this.shellEscape(p)}`
|
|
48731
|
+
], { maxBuffer: MAX_DOWNLOAD_SIZE, timeout: BACKEND_TIMEOUT, encoding: "buffer" });
|
|
48732
|
+
return stdout;
|
|
48733
|
+
} catch (err) {
|
|
48734
|
+
if (err.code === "ETIMEDOUT" || err.killed) {
|
|
48735
|
+
throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48736
|
+
}
|
|
48737
|
+
if (err.stderr && /no such file/i.test(String(err.stderr))) {
|
|
48738
|
+
throw Object.assign(new Error("File not found on remote"), { code: "not_found" });
|
|
48739
|
+
}
|
|
48740
|
+
throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
|
|
48741
|
+
}
|
|
48742
|
+
}
|
|
48743
|
+
async exists(filePath) {
|
|
48744
|
+
const p = validatePath(filePath);
|
|
48745
|
+
try {
|
|
48746
|
+
await execFileAsync3("ssh", [
|
|
48747
|
+
...this.sshArgs(),
|
|
48748
|
+
`test -f ${this.shellEscape(p)}`
|
|
48749
|
+
], { timeout: 5e3 });
|
|
48750
|
+
return true;
|
|
48751
|
+
} catch {
|
|
48752
|
+
return false;
|
|
48753
|
+
}
|
|
48754
|
+
}
|
|
48755
|
+
async listDir(dirPath) {
|
|
48756
|
+
const p = validatePath(dirPath);
|
|
48757
|
+
try {
|
|
48758
|
+
const { stdout } = await execFileAsync3("ssh", [
|
|
48759
|
+
...this.sshArgs(),
|
|
48760
|
+
`ls -la --time-style=+%Y-%m-%dT%H:%M:%S ${this.shellEscape(p)}`
|
|
48761
|
+
], { maxBuffer: 10 * 1024 * 1024, timeout: BACKEND_TIMEOUT });
|
|
48762
|
+
const homeDir = getActiveProfileDir();
|
|
48763
|
+
const relParent = p.startsWith(homeDir) ? p.slice(homeDir.length + 1).replace(/\\/g, "/") : "";
|
|
48764
|
+
return parseLsOutput(stdout, relParent);
|
|
48765
|
+
} catch (err) {
|
|
48766
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48767
|
+
if (err.stderr && /no such file|not a directory/i.test(String(err.stderr)))
|
|
48768
|
+
throw Object.assign(new Error("Directory not found"), { code: "not_found" });
|
|
48769
|
+
throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
|
|
48770
|
+
}
|
|
48771
|
+
}
|
|
48772
|
+
async stat(filePath) {
|
|
48773
|
+
const p = validatePath(filePath);
|
|
48774
|
+
try {
|
|
48775
|
+
const { stdout } = await execFileAsync3("ssh", [
|
|
48776
|
+
...this.sshArgs(),
|
|
48777
|
+
`stat -c '%n|%F|%s|%Y' ${this.shellEscape(p)}`
|
|
48778
|
+
], { timeout: BACKEND_TIMEOUT });
|
|
48779
|
+
const homeDir = getActiveProfileDir();
|
|
48780
|
+
const relPath = p.startsWith(homeDir) ? p.slice(homeDir.length + 1).replace(/\\/g, "/") : (0, import_path17.basename)(p);
|
|
48781
|
+
return parseStatOutput(stdout, relPath);
|
|
48782
|
+
} catch (err) {
|
|
48783
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48784
|
+
if (err.stderr && /no such file/i.test(String(err.stderr))) throw Object.assign(new Error("Not found"), { code: "not_found" });
|
|
48785
|
+
throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
|
|
48786
|
+
}
|
|
48787
|
+
}
|
|
48788
|
+
async writeFile(filePath, content) {
|
|
48789
|
+
const p = validatePath(filePath);
|
|
48790
|
+
try {
|
|
48791
|
+
await execFileAsync3("ssh", [
|
|
48792
|
+
...this.sshArgs(),
|
|
48793
|
+
`cat > ${this.shellEscape(p)}`
|
|
48794
|
+
], { timeout: BACKEND_TIMEOUT, input: content });
|
|
48795
|
+
} catch (err) {
|
|
48796
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48797
|
+
throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
|
|
48798
|
+
}
|
|
48799
|
+
}
|
|
48800
|
+
async deleteFile(filePath) {
|
|
48801
|
+
const p = validatePath(filePath);
|
|
48802
|
+
try {
|
|
48803
|
+
await execFileAsync3("ssh", [...this.sshArgs(), `rm ${this.shellEscape(p)}`], { timeout: BACKEND_TIMEOUT });
|
|
48804
|
+
} catch (err) {
|
|
48805
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48806
|
+
throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
|
|
48807
|
+
}
|
|
48808
|
+
}
|
|
48809
|
+
async deleteDir(dirPath) {
|
|
48810
|
+
const p = validatePath(dirPath);
|
|
48811
|
+
try {
|
|
48812
|
+
await execFileAsync3("ssh", [...this.sshArgs(), `rm -rf ${this.shellEscape(p)}`], { timeout: BACKEND_TIMEOUT });
|
|
48813
|
+
} catch (err) {
|
|
48814
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48815
|
+
throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
|
|
48816
|
+
}
|
|
48817
|
+
}
|
|
48818
|
+
async renameFile(oldPath, newPath) {
|
|
48819
|
+
const op = validatePath(oldPath);
|
|
48820
|
+
const np = validatePath(newPath);
|
|
48821
|
+
try {
|
|
48822
|
+
await execFileAsync3("ssh", [...this.sshArgs(), `mv ${this.shellEscape(op)} ${this.shellEscape(np)}`], { timeout: BACKEND_TIMEOUT });
|
|
48823
|
+
} catch (err) {
|
|
48824
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48825
|
+
throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
|
|
48826
|
+
}
|
|
48827
|
+
}
|
|
48828
|
+
async mkDir(dirPath) {
|
|
48829
|
+
const p = validatePath(dirPath);
|
|
48830
|
+
try {
|
|
48831
|
+
await execFileAsync3("ssh", [...this.sshArgs(), `mkdir -p ${this.shellEscape(p)}`], { timeout: BACKEND_TIMEOUT });
|
|
48832
|
+
} catch (err) {
|
|
48833
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48834
|
+
throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
|
|
48835
|
+
}
|
|
48836
|
+
}
|
|
48837
|
+
async copyFile(srcPath, destPath) {
|
|
48838
|
+
const sp = validatePath(srcPath);
|
|
48839
|
+
const dp = validatePath(destPath);
|
|
48840
|
+
try {
|
|
48841
|
+
await execFileAsync3("ssh", [...this.sshArgs(), `cp ${this.shellEscape(sp)} ${this.shellEscape(dp)}`], { timeout: BACKEND_TIMEOUT });
|
|
48842
|
+
} catch (err) {
|
|
48843
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48844
|
+
throw Object.assign(new Error(`SSH error: ${err.message}`), { code: "backend_error" });
|
|
48845
|
+
}
|
|
48846
|
+
}
|
|
48847
|
+
};
|
|
48848
|
+
var SingularityFileProvider = class {
|
|
48849
|
+
type = "singularity";
|
|
48850
|
+
imagePath;
|
|
48851
|
+
constructor(imagePath) {
|
|
48852
|
+
this.imagePath = imagePath;
|
|
48853
|
+
}
|
|
48854
|
+
async readFile(filePath) {
|
|
48855
|
+
const p = validatePath(filePath);
|
|
48856
|
+
try {
|
|
48857
|
+
const { stdout } = await execFileAsync3("singularity", [
|
|
48858
|
+
"exec",
|
|
48859
|
+
this.imagePath,
|
|
48860
|
+
"cat",
|
|
48861
|
+
p
|
|
48862
|
+
], { maxBuffer: MAX_DOWNLOAD_SIZE, timeout: BACKEND_TIMEOUT, encoding: "buffer" });
|
|
48863
|
+
return stdout;
|
|
48864
|
+
} catch (err) {
|
|
48865
|
+
if (err.code === "ETIMEDOUT" || err.killed) {
|
|
48866
|
+
throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48867
|
+
}
|
|
48868
|
+
if (err.stderr && /no such file/i.test(String(err.stderr))) {
|
|
48869
|
+
throw Object.assign(new Error("File not found in container"), { code: "not_found" });
|
|
48870
|
+
}
|
|
48871
|
+
throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
|
|
48872
|
+
}
|
|
48873
|
+
}
|
|
48874
|
+
async exists(filePath) {
|
|
48875
|
+
const p = validatePath(filePath);
|
|
48876
|
+
try {
|
|
48877
|
+
await execFileAsync3("singularity", [
|
|
48878
|
+
"exec",
|
|
48879
|
+
this.imagePath,
|
|
48880
|
+
"test",
|
|
48881
|
+
"-f",
|
|
48882
|
+
p
|
|
48883
|
+
], { timeout: 5e3 });
|
|
48884
|
+
return true;
|
|
48885
|
+
} catch {
|
|
48886
|
+
return false;
|
|
48887
|
+
}
|
|
48888
|
+
}
|
|
48889
|
+
async listDir(dirPath) {
|
|
48890
|
+
const p = validatePath(dirPath);
|
|
48891
|
+
try {
|
|
48892
|
+
const { stdout } = await execFileAsync3("singularity", [
|
|
48893
|
+
"exec",
|
|
48894
|
+
this.imagePath,
|
|
48895
|
+
"ls",
|
|
48896
|
+
"-la",
|
|
48897
|
+
"--time-style=+%Y-%m-%dT%H:%M:%S",
|
|
48898
|
+
p
|
|
48899
|
+
], { maxBuffer: 10 * 1024 * 1024, timeout: BACKEND_TIMEOUT });
|
|
48900
|
+
const homeDir = getActiveProfileDir();
|
|
48901
|
+
const relParent = p.startsWith(homeDir) ? p.slice(homeDir.length + 1).replace(/\\/g, "/") : "";
|
|
48902
|
+
return parseLsOutput(stdout, relParent);
|
|
48903
|
+
} catch (err) {
|
|
48904
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48905
|
+
if (err.stderr && /no such file|not a directory/i.test(String(err.stderr)))
|
|
48906
|
+
throw Object.assign(new Error("Directory not found"), { code: "not_found" });
|
|
48907
|
+
throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
|
|
48908
|
+
}
|
|
48909
|
+
}
|
|
48910
|
+
async stat(filePath) {
|
|
48911
|
+
const p = validatePath(filePath);
|
|
48912
|
+
try {
|
|
48913
|
+
const { stdout } = await execFileAsync3("singularity", [
|
|
48914
|
+
"exec",
|
|
48915
|
+
this.imagePath,
|
|
48916
|
+
"stat",
|
|
48917
|
+
"-c",
|
|
48918
|
+
"%n|%F|%s|%Y",
|
|
48919
|
+
p
|
|
48920
|
+
], { timeout: BACKEND_TIMEOUT });
|
|
48921
|
+
const homeDir = getActiveProfileDir();
|
|
48922
|
+
const relPath = p.startsWith(homeDir) ? p.slice(homeDir.length + 1).replace(/\\/g, "/") : (0, import_path17.basename)(p);
|
|
48923
|
+
return parseStatOutput(stdout, relPath);
|
|
48924
|
+
} catch (err) {
|
|
48925
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48926
|
+
if (err.stderr && /no such file/i.test(String(err.stderr))) throw Object.assign(new Error("Not found"), { code: "not_found" });
|
|
48927
|
+
throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
|
|
48928
|
+
}
|
|
48929
|
+
}
|
|
48930
|
+
async writeFile(filePath, content) {
|
|
48931
|
+
const p = validatePath(filePath);
|
|
48932
|
+
try {
|
|
48933
|
+
await execFileAsync3("singularity", [
|
|
48934
|
+
"exec",
|
|
48935
|
+
this.imagePath,
|
|
48936
|
+
"sh",
|
|
48937
|
+
"-c",
|
|
48938
|
+
`cat > '${p.replace(/'/g, "'\\''")}'`
|
|
48939
|
+
], { timeout: BACKEND_TIMEOUT, input: content });
|
|
48940
|
+
} catch (err) {
|
|
48941
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48942
|
+
throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
|
|
48943
|
+
}
|
|
48944
|
+
}
|
|
48945
|
+
async deleteFile(filePath) {
|
|
48946
|
+
const p = validatePath(filePath);
|
|
48947
|
+
try {
|
|
48948
|
+
await execFileAsync3("singularity", ["exec", this.imagePath, "rm", p], { timeout: BACKEND_TIMEOUT });
|
|
48949
|
+
} catch (err) {
|
|
48950
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48951
|
+
throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
|
|
48952
|
+
}
|
|
48953
|
+
}
|
|
48954
|
+
async deleteDir(dirPath) {
|
|
48955
|
+
const p = validatePath(dirPath);
|
|
48956
|
+
try {
|
|
48957
|
+
await execFileAsync3("singularity", ["exec", this.imagePath, "rm", "-rf", p], { timeout: BACKEND_TIMEOUT });
|
|
48958
|
+
} catch (err) {
|
|
48959
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48960
|
+
throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
|
|
48961
|
+
}
|
|
48962
|
+
}
|
|
48963
|
+
async renameFile(oldPath, newPath) {
|
|
48964
|
+
const op = validatePath(oldPath);
|
|
48965
|
+
const np = validatePath(newPath);
|
|
48966
|
+
try {
|
|
48967
|
+
await execFileAsync3("singularity", ["exec", this.imagePath, "mv", op, np], { timeout: BACKEND_TIMEOUT });
|
|
48968
|
+
} catch (err) {
|
|
48969
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48970
|
+
throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
|
|
48971
|
+
}
|
|
48972
|
+
}
|
|
48973
|
+
async mkDir(dirPath) {
|
|
48974
|
+
const p = validatePath(dirPath);
|
|
48975
|
+
try {
|
|
48976
|
+
await execFileAsync3("singularity", ["exec", this.imagePath, "mkdir", "-p", p], { timeout: BACKEND_TIMEOUT });
|
|
48977
|
+
} catch (err) {
|
|
48978
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48979
|
+
throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
|
|
48980
|
+
}
|
|
48981
|
+
}
|
|
48982
|
+
async copyFile(srcPath, destPath) {
|
|
48983
|
+
const sp = validatePath(srcPath);
|
|
48984
|
+
const dp = validatePath(destPath);
|
|
48985
|
+
try {
|
|
48986
|
+
await execFileAsync3("singularity", ["exec", this.imagePath, "cp", sp, dp], { timeout: BACKEND_TIMEOUT });
|
|
48987
|
+
} catch (err) {
|
|
48988
|
+
if (err.code === "ETIMEDOUT" || err.killed) throw Object.assign(new Error("Backend timeout"), { code: "backend_timeout" });
|
|
48989
|
+
throw Object.assign(new Error(`Singularity error: ${err.message}`), { code: "backend_error" });
|
|
48990
|
+
}
|
|
48991
|
+
}
|
|
48992
|
+
};
|
|
48993
|
+
function getTerminalConfig() {
|
|
48994
|
+
try {
|
|
48995
|
+
const configPath3 = `${getActiveProfileDir()}/config.yaml`;
|
|
48996
|
+
if (!(0, import_fs16.existsSync)(configPath3)) return { backend: "local" };
|
|
48997
|
+
const raw = (0, import_fs16.readFileSync)(configPath3, "utf-8");
|
|
48998
|
+
const doc = jsYaml.load(raw);
|
|
48999
|
+
const t = doc?.terminal || {};
|
|
49000
|
+
return {
|
|
49001
|
+
backend: t.backend || "local",
|
|
49002
|
+
docker_image: t.docker_image,
|
|
49003
|
+
docker_container_name: t.docker_container_name,
|
|
49004
|
+
cwd: t.cwd,
|
|
49005
|
+
singularity_image: t.singularity_image
|
|
49006
|
+
};
|
|
49007
|
+
} catch {
|
|
49008
|
+
return { backend: "local" };
|
|
49009
|
+
}
|
|
49010
|
+
}
|
|
49011
|
+
function getSSHEnvVars() {
|
|
49012
|
+
try {
|
|
49013
|
+
const envPath3 = getActiveEnvPath();
|
|
49014
|
+
if (!(0, import_fs16.existsSync)(envPath3)) return {};
|
|
49015
|
+
const raw = (0, import_fs16.readFileSync)(envPath3, "utf-8");
|
|
49016
|
+
const vars = {};
|
|
49017
|
+
for (const line of raw.split("\n")) {
|
|
49018
|
+
const trimmed = line.trim();
|
|
49019
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
49020
|
+
const eqIdx = trimmed.indexOf("=");
|
|
49021
|
+
if (eqIdx === -1) continue;
|
|
49022
|
+
let value = trimmed.slice(eqIdx + 1).trim();
|
|
49023
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
49024
|
+
value = value.slice(1, -1);
|
|
49025
|
+
}
|
|
49026
|
+
vars[trimmed.slice(0, eqIdx).trim()] = value;
|
|
49027
|
+
}
|
|
49028
|
+
return {
|
|
49029
|
+
host: vars.TERMINAL_SSH_HOST,
|
|
49030
|
+
user: vars.TERMINAL_SSH_USER,
|
|
49031
|
+
key: vars.TERMINAL_SSH_KEY
|
|
49032
|
+
};
|
|
49033
|
+
} catch {
|
|
49034
|
+
return {};
|
|
49035
|
+
}
|
|
49036
|
+
}
|
|
49037
|
+
async function resolveDockerContainer(cfg) {
|
|
49038
|
+
if (cfg.docker_container_name) return cfg.docker_container_name;
|
|
49039
|
+
if (cfg.docker_image) {
|
|
49040
|
+
try {
|
|
49041
|
+
const { stdout } = await execFileAsync3("docker", [
|
|
49042
|
+
"ps",
|
|
49043
|
+
"-q",
|
|
49044
|
+
"--filter",
|
|
49045
|
+
`ancestor=${cfg.docker_image}`,
|
|
49046
|
+
"--latest"
|
|
49047
|
+
], { timeout: 5e3 });
|
|
49048
|
+
const id = stdout.trim();
|
|
49049
|
+
if (id) return id;
|
|
49050
|
+
} catch {
|
|
49051
|
+
}
|
|
49052
|
+
}
|
|
49053
|
+
throw Object.assign(
|
|
49054
|
+
new Error("Cannot determine Docker container. Set terminal.docker_container_name in hermes config."),
|
|
49055
|
+
{ code: "backend_error" }
|
|
49056
|
+
);
|
|
49057
|
+
}
|
|
49058
|
+
var cachedProvider = null;
|
|
49059
|
+
var cachedAt = 0;
|
|
49060
|
+
var CACHE_TTL = 1e4;
|
|
49061
|
+
function _resetFileProviderCache() {
|
|
49062
|
+
cachedProvider = null;
|
|
49063
|
+
cachedAt = 0;
|
|
49064
|
+
}
|
|
49065
|
+
async function createFileProvider() {
|
|
49066
|
+
const now = Date.now();
|
|
49067
|
+
if (cachedProvider && now - cachedAt < CACHE_TTL) return cachedProvider;
|
|
49068
|
+
const cfg = getTerminalConfig();
|
|
49069
|
+
let provider;
|
|
49070
|
+
switch (cfg.backend) {
|
|
49071
|
+
case "docker": {
|
|
49072
|
+
const container = await resolveDockerContainer(cfg);
|
|
49073
|
+
provider = new DockerFileProvider(container);
|
|
49074
|
+
break;
|
|
49075
|
+
}
|
|
49076
|
+
case "ssh": {
|
|
49077
|
+
const ssh = getSSHEnvVars();
|
|
49078
|
+
if (!ssh.host || !ssh.user) {
|
|
49079
|
+
throw Object.assign(
|
|
49080
|
+
new Error("SSH backend requires TERMINAL_SSH_HOST and TERMINAL_SSH_USER in .env"),
|
|
49081
|
+
{ code: "backend_error" }
|
|
49082
|
+
);
|
|
49083
|
+
}
|
|
49084
|
+
provider = new SSHFileProvider(ssh.host, ssh.user, ssh.key);
|
|
49085
|
+
break;
|
|
49086
|
+
}
|
|
49087
|
+
case "singularity": {
|
|
49088
|
+
if (!cfg.singularity_image) {
|
|
49089
|
+
throw Object.assign(
|
|
49090
|
+
new Error("Singularity backend requires terminal.singularity_image in config"),
|
|
49091
|
+
{ code: "backend_error" }
|
|
49092
|
+
);
|
|
49093
|
+
}
|
|
49094
|
+
provider = new SingularityFileProvider(cfg.singularity_image);
|
|
49095
|
+
break;
|
|
49096
|
+
}
|
|
49097
|
+
case "modal":
|
|
49098
|
+
case "daytona":
|
|
49099
|
+
throw Object.assign(
|
|
49100
|
+
new Error(`File download not yet supported for '${cfg.backend}' backend`),
|
|
49101
|
+
{ code: "unsupported_backend" }
|
|
49102
|
+
);
|
|
49103
|
+
default:
|
|
49104
|
+
provider = new LocalFileProvider();
|
|
49105
|
+
}
|
|
49106
|
+
cachedProvider = provider;
|
|
49107
|
+
cachedAt = now;
|
|
49108
|
+
return provider;
|
|
49109
|
+
}
|
|
49110
|
+
var localProvider = new LocalFileProvider();
|
|
49111
|
+
|
|
49112
|
+
// packages/server/src/routes/hermes/files.ts
|
|
49113
|
+
var fileRoutes = new router_default();
|
|
49114
|
+
function handleError(ctx, err) {
|
|
49115
|
+
const code = err.code || "unknown";
|
|
49116
|
+
const statusMap = {
|
|
49117
|
+
missing_path: 400,
|
|
49118
|
+
invalid_path: 400,
|
|
49119
|
+
not_found: 404,
|
|
49120
|
+
ENOENT: 404,
|
|
49121
|
+
already_exists: 409,
|
|
49122
|
+
permission_denied: 403,
|
|
49123
|
+
file_too_large: 413,
|
|
49124
|
+
not_a_directory: 400,
|
|
49125
|
+
not_a_file: 400,
|
|
49126
|
+
unsupported_backend: 501,
|
|
49127
|
+
backend_error: 502,
|
|
49128
|
+
backend_timeout: 504
|
|
49129
|
+
};
|
|
49130
|
+
ctx.status = statusMap[code] || 500;
|
|
49131
|
+
ctx.body = { error: err.message, code };
|
|
49132
|
+
}
|
|
49133
|
+
fileRoutes.get("/api/hermes/files/list", async (ctx) => {
|
|
49134
|
+
const relativePath = ctx.query.path || "";
|
|
49135
|
+
try {
|
|
49136
|
+
const absPath = resolveHermesPath(relativePath);
|
|
49137
|
+
const provider = await createFileProvider();
|
|
49138
|
+
const entries = await provider.listDir(absPath);
|
|
49139
|
+
entries.sort((a, b) => {
|
|
49140
|
+
if (a.isDir !== b.isDir) return a.isDir ? -1 : 1;
|
|
49141
|
+
return a.name.localeCompare(b.name);
|
|
49142
|
+
});
|
|
49143
|
+
ctx.body = { entries, path: relativePath };
|
|
49144
|
+
} catch (err) {
|
|
49145
|
+
handleError(ctx, err);
|
|
49146
|
+
}
|
|
49147
|
+
});
|
|
49148
|
+
fileRoutes.get("/api/hermes/files/stat", async (ctx) => {
|
|
49149
|
+
const relativePath = ctx.query.path;
|
|
49150
|
+
if (!relativePath) {
|
|
49151
|
+
ctx.status = 400;
|
|
49152
|
+
ctx.body = { error: "Missing path parameter", code: "missing_path" };
|
|
49153
|
+
return;
|
|
49154
|
+
}
|
|
49155
|
+
try {
|
|
49156
|
+
const absPath = resolveHermesPath(relativePath);
|
|
49157
|
+
const provider = await createFileProvider();
|
|
49158
|
+
const info = await provider.stat(absPath);
|
|
49159
|
+
ctx.body = info;
|
|
49160
|
+
} catch (err) {
|
|
49161
|
+
handleError(ctx, err);
|
|
49162
|
+
}
|
|
49163
|
+
});
|
|
49164
|
+
fileRoutes.get("/api/hermes/files/read", async (ctx) => {
|
|
49165
|
+
const relativePath = ctx.query.path;
|
|
49166
|
+
if (!relativePath) {
|
|
49167
|
+
ctx.status = 400;
|
|
49168
|
+
ctx.body = { error: "Missing path parameter", code: "missing_path" };
|
|
49169
|
+
return;
|
|
49170
|
+
}
|
|
49171
|
+
try {
|
|
49172
|
+
const absPath = resolveHermesPath(relativePath);
|
|
49173
|
+
const provider = await createFileProvider();
|
|
49174
|
+
const data = await provider.readFile(absPath);
|
|
49175
|
+
if (data.length > MAX_EDIT_SIZE) {
|
|
49176
|
+
ctx.status = 413;
|
|
49177
|
+
ctx.body = { error: "File too large to edit", code: "file_too_large" };
|
|
49178
|
+
return;
|
|
49179
|
+
}
|
|
49180
|
+
ctx.body = { content: data.toString("utf-8"), path: relativePath, size: data.length };
|
|
49181
|
+
} catch (err) {
|
|
49182
|
+
handleError(ctx, err);
|
|
49183
|
+
}
|
|
49184
|
+
});
|
|
49185
|
+
fileRoutes.put("/api/hermes/files/write", async (ctx) => {
|
|
49186
|
+
const { path: relativePath, content } = ctx.request.body;
|
|
49187
|
+
if (!relativePath) {
|
|
49188
|
+
ctx.status = 400;
|
|
49189
|
+
ctx.body = { error: "Missing path parameter", code: "missing_path" };
|
|
49190
|
+
return;
|
|
49191
|
+
}
|
|
49192
|
+
if (isSensitivePath(relativePath)) {
|
|
49193
|
+
ctx.status = 403;
|
|
49194
|
+
ctx.body = { error: "Cannot modify sensitive file", code: "permission_denied" };
|
|
49195
|
+
return;
|
|
49196
|
+
}
|
|
49197
|
+
try {
|
|
49198
|
+
const buf = Buffer.from(content || "", "utf-8");
|
|
49199
|
+
if (buf.length > MAX_EDIT_SIZE) {
|
|
49200
|
+
ctx.status = 413;
|
|
49201
|
+
ctx.body = { error: "Content too large", code: "file_too_large" };
|
|
49202
|
+
return;
|
|
49203
|
+
}
|
|
49204
|
+
const absPath = resolveHermesPath(relativePath);
|
|
49205
|
+
const provider = await createFileProvider();
|
|
49206
|
+
await provider.writeFile(absPath, buf);
|
|
49207
|
+
ctx.body = { ok: true, path: relativePath };
|
|
49208
|
+
} catch (err) {
|
|
49209
|
+
handleError(ctx, err);
|
|
49210
|
+
}
|
|
49211
|
+
});
|
|
49212
|
+
fileRoutes.delete("/api/hermes/files/delete", async (ctx) => {
|
|
49213
|
+
const { path: relativePath, recursive } = ctx.request.body;
|
|
49214
|
+
if (!relativePath) {
|
|
49215
|
+
ctx.status = 400;
|
|
49216
|
+
ctx.body = { error: "Missing path parameter", code: "missing_path" };
|
|
49217
|
+
return;
|
|
49218
|
+
}
|
|
49219
|
+
if (isSensitivePath(relativePath)) {
|
|
49220
|
+
ctx.status = 403;
|
|
49221
|
+
ctx.body = { error: "Cannot delete sensitive file", code: "permission_denied" };
|
|
49222
|
+
return;
|
|
49223
|
+
}
|
|
49224
|
+
try {
|
|
49225
|
+
const absPath = resolveHermesPath(relativePath);
|
|
49226
|
+
const provider = await createFileProvider();
|
|
49227
|
+
if (recursive) {
|
|
49228
|
+
await provider.deleteDir(absPath);
|
|
49229
|
+
} else {
|
|
49230
|
+
await provider.deleteFile(absPath);
|
|
49231
|
+
}
|
|
49232
|
+
ctx.body = { ok: true };
|
|
49233
|
+
} catch (err) {
|
|
49234
|
+
handleError(ctx, err);
|
|
49235
|
+
}
|
|
49236
|
+
});
|
|
49237
|
+
fileRoutes.post("/api/hermes/files/rename", async (ctx) => {
|
|
49238
|
+
const { oldPath, newPath } = ctx.request.body;
|
|
49239
|
+
if (!oldPath || !newPath) {
|
|
49240
|
+
ctx.status = 400;
|
|
49241
|
+
ctx.body = { error: "Missing oldPath or newPath", code: "missing_path" };
|
|
49242
|
+
return;
|
|
49243
|
+
}
|
|
49244
|
+
if (isSensitivePath(oldPath)) {
|
|
49245
|
+
ctx.status = 403;
|
|
49246
|
+
ctx.body = { error: "Cannot rename sensitive file", code: "permission_denied" };
|
|
49247
|
+
return;
|
|
49248
|
+
}
|
|
49249
|
+
try {
|
|
49250
|
+
const absOld = resolveHermesPath(oldPath);
|
|
49251
|
+
const absNew = resolveHermesPath(newPath);
|
|
49252
|
+
const provider = await createFileProvider();
|
|
49253
|
+
await provider.renameFile(absOld, absNew);
|
|
49254
|
+
ctx.body = { ok: true };
|
|
49255
|
+
} catch (err) {
|
|
49256
|
+
handleError(ctx, err);
|
|
49257
|
+
}
|
|
49258
|
+
});
|
|
49259
|
+
fileRoutes.post("/api/hermes/files/mkdir", async (ctx) => {
|
|
49260
|
+
const { path: relativePath } = ctx.request.body;
|
|
49261
|
+
if (!relativePath) {
|
|
49262
|
+
ctx.status = 400;
|
|
49263
|
+
ctx.body = { error: "Missing path parameter", code: "missing_path" };
|
|
49264
|
+
return;
|
|
49265
|
+
}
|
|
49266
|
+
try {
|
|
49267
|
+
const absPath = resolveHermesPath(relativePath);
|
|
49268
|
+
const provider = await createFileProvider();
|
|
49269
|
+
await provider.mkDir(absPath);
|
|
49270
|
+
ctx.body = { ok: true };
|
|
49271
|
+
} catch (err) {
|
|
49272
|
+
handleError(ctx, err);
|
|
49273
|
+
}
|
|
49274
|
+
});
|
|
49275
|
+
fileRoutes.post("/api/hermes/files/copy", async (ctx) => {
|
|
49276
|
+
const { srcPath, destPath } = ctx.request.body;
|
|
49277
|
+
if (!srcPath || !destPath) {
|
|
49278
|
+
ctx.status = 400;
|
|
49279
|
+
ctx.body = { error: "Missing srcPath or destPath", code: "missing_path" };
|
|
49280
|
+
return;
|
|
49281
|
+
}
|
|
49282
|
+
try {
|
|
49283
|
+
const absSrc = resolveHermesPath(srcPath);
|
|
49284
|
+
const absDest = resolveHermesPath(destPath);
|
|
49285
|
+
const provider = await createFileProvider();
|
|
49286
|
+
await provider.copyFile(absSrc, absDest);
|
|
49287
|
+
ctx.body = { ok: true };
|
|
49288
|
+
} catch (err) {
|
|
49289
|
+
handleError(ctx, err);
|
|
49290
|
+
}
|
|
49291
|
+
});
|
|
49292
|
+
fileRoutes.post("/api/hermes/files/upload", async (ctx) => {
|
|
49293
|
+
const targetDir = ctx.query.path || "";
|
|
49294
|
+
const contentType = ctx.get("content-type") || "";
|
|
49295
|
+
if (!contentType.startsWith("multipart/form-data")) {
|
|
49296
|
+
ctx.status = 400;
|
|
49297
|
+
ctx.body = { error: "Expected multipart/form-data", code: "invalid_request" };
|
|
49298
|
+
return;
|
|
49299
|
+
}
|
|
49300
|
+
const boundary = "--" + contentType.split("boundary=")[1];
|
|
49301
|
+
if (!boundary || boundary === "--undefined") {
|
|
49302
|
+
ctx.status = 400;
|
|
49303
|
+
ctx.body = { error: "Missing boundary", code: "invalid_request" };
|
|
49304
|
+
return;
|
|
49305
|
+
}
|
|
49306
|
+
const chunks = [];
|
|
49307
|
+
for await (const chunk of ctx.req) chunks.push(chunk);
|
|
49308
|
+
const raw = Buffer.concat(chunks);
|
|
49309
|
+
const boundaryBuf = Buffer.from(boundary);
|
|
49310
|
+
const parts = splitMultipart2(raw, boundaryBuf);
|
|
49311
|
+
const provider = await createFileProvider();
|
|
49312
|
+
const results = [];
|
|
49313
|
+
for (const part of parts) {
|
|
49314
|
+
const headerEnd = part.indexOf(Buffer.from("\r\n\r\n"));
|
|
49315
|
+
if (headerEnd === -1) continue;
|
|
49316
|
+
const headerBuf = part.subarray(0, headerEnd);
|
|
49317
|
+
const header = headerBuf.toString("utf-8");
|
|
49318
|
+
const data = part.subarray(headerEnd + 4, part.length - 2);
|
|
49319
|
+
let filename = "";
|
|
49320
|
+
const filenameStarMatch = header.match(/filename\*=UTF-8''(.+)/i);
|
|
49321
|
+
if (filenameStarMatch) {
|
|
49322
|
+
filename = decodeURIComponent(filenameStarMatch[1]);
|
|
49323
|
+
} else {
|
|
49324
|
+
const filenameMatch = header.match(/filename="([^"]+)"/);
|
|
49325
|
+
if (!filenameMatch) continue;
|
|
49326
|
+
filename = filenameMatch[1];
|
|
49327
|
+
}
|
|
49328
|
+
if (data.length > MAX_EDIT_SIZE) {
|
|
49329
|
+
ctx.status = 413;
|
|
49330
|
+
ctx.body = { error: `File ${filename} too large`, code: "file_too_large" };
|
|
49331
|
+
return;
|
|
49332
|
+
}
|
|
49333
|
+
const filePath = targetDir ? `${targetDir}/${filename}` : filename;
|
|
49334
|
+
if (isSensitivePath(filePath)) {
|
|
49335
|
+
ctx.status = 403;
|
|
49336
|
+
ctx.body = { error: `Cannot overwrite sensitive file: ${filename}`, code: "permission_denied" };
|
|
49337
|
+
return;
|
|
49338
|
+
}
|
|
49339
|
+
const absPath = resolveHermesPath(filePath);
|
|
49340
|
+
await provider.writeFile(absPath, data);
|
|
49341
|
+
results.push({ name: filename, path: filePath });
|
|
49342
|
+
}
|
|
49343
|
+
ctx.body = { files: results };
|
|
49344
|
+
});
|
|
49345
|
+
function splitMultipart2(raw, boundary) {
|
|
49346
|
+
const parts = [];
|
|
49347
|
+
let start4 = 0;
|
|
49348
|
+
while (true) {
|
|
49349
|
+
const idx = raw.indexOf(boundary, start4);
|
|
49350
|
+
if (idx === -1) break;
|
|
49351
|
+
if (start4 > 0) {
|
|
49352
|
+
const partStart = start4 + 2;
|
|
49353
|
+
parts.push(raw.subarray(partStart, idx));
|
|
49354
|
+
}
|
|
49355
|
+
start4 = idx + boundary.length;
|
|
49356
|
+
}
|
|
49357
|
+
return parts;
|
|
49358
|
+
}
|
|
49359
|
+
|
|
49360
|
+
// packages/server/src/routes/hermes/download.ts
|
|
49361
|
+
var import_path18 = require("path");
|
|
49362
|
+
var downloadRoutes = new router_default();
|
|
49363
|
+
var MIME_MAP = {
|
|
49364
|
+
".txt": "text/plain",
|
|
49365
|
+
".html": "text/html",
|
|
49366
|
+
".htm": "text/html",
|
|
49367
|
+
".css": "text/css",
|
|
49368
|
+
".js": "application/javascript",
|
|
49369
|
+
".json": "application/json",
|
|
49370
|
+
".xml": "application/xml",
|
|
49371
|
+
".csv": "text/csv",
|
|
49372
|
+
".md": "text/markdown",
|
|
49373
|
+
".pdf": "application/pdf",
|
|
49374
|
+
".zip": "application/zip",
|
|
49375
|
+
".gz": "application/gzip",
|
|
49376
|
+
".tar": "application/x-tar",
|
|
49377
|
+
".png": "image/png",
|
|
49378
|
+
".jpg": "image/jpeg",
|
|
49379
|
+
".jpeg": "image/jpeg",
|
|
49380
|
+
".gif": "image/gif",
|
|
49381
|
+
".svg": "image/svg+xml",
|
|
49382
|
+
".webp": "image/webp",
|
|
49383
|
+
".mp3": "audio/mpeg",
|
|
49384
|
+
".wav": "audio/wav",
|
|
49385
|
+
".mp4": "video/mp4",
|
|
49386
|
+
".webm": "video/webm",
|
|
49387
|
+
".doc": "application/msword",
|
|
49388
|
+
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
49389
|
+
".xls": "application/vnd.ms-excel",
|
|
49390
|
+
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
49391
|
+
".ppt": "application/vnd.ms-powerpoint",
|
|
49392
|
+
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
49393
|
+
".py": "text/x-python",
|
|
49394
|
+
".ts": "text/typescript",
|
|
49395
|
+
".tsx": "text/typescript",
|
|
49396
|
+
".rs": "text/x-rust",
|
|
49397
|
+
".go": "text/x-go",
|
|
49398
|
+
".java": "text/x-java",
|
|
49399
|
+
".c": "text/x-c",
|
|
49400
|
+
".cpp": "text/x-c++",
|
|
49401
|
+
".h": "text/x-c",
|
|
49402
|
+
".sh": "text/x-shellscript",
|
|
49403
|
+
".yaml": "text/yaml",
|
|
49404
|
+
".yml": "text/yaml",
|
|
49405
|
+
".toml": "text/toml",
|
|
49406
|
+
".log": "text/plain"
|
|
49407
|
+
};
|
|
49408
|
+
function getMimeType(fileName) {
|
|
49409
|
+
const ext = (0, import_path18.extname)(fileName).toLowerCase();
|
|
49410
|
+
return MIME_MAP[ext] || "application/octet-stream";
|
|
49411
|
+
}
|
|
49412
|
+
downloadRoutes.get("/api/hermes/download", async (ctx) => {
|
|
49413
|
+
const filePath = ctx.query.path;
|
|
49414
|
+
const fileName = ctx.query.name;
|
|
49415
|
+
if (!filePath) {
|
|
49416
|
+
ctx.status = 400;
|
|
49417
|
+
ctx.body = { error: "Missing path parameter", code: "missing_path" };
|
|
49418
|
+
return;
|
|
49419
|
+
}
|
|
49420
|
+
try {
|
|
49421
|
+
const validPath = filePath.startsWith("/") ? validatePath(filePath) : resolveHermesPath(filePath);
|
|
49422
|
+
let data;
|
|
49423
|
+
if (isInUploadDir(validPath)) {
|
|
49424
|
+
data = await localProvider.readFile(validPath);
|
|
49425
|
+
} else {
|
|
49426
|
+
const provider = await createFileProvider();
|
|
49427
|
+
data = await provider.readFile(validPath);
|
|
49428
|
+
}
|
|
49429
|
+
const name = fileName || (0, import_path18.basename)(validPath);
|
|
49430
|
+
const mime = getMimeType(name);
|
|
49431
|
+
ctx.set("Content-Type", mime);
|
|
49432
|
+
ctx.set("Content-Disposition", `attachment; filename="${encodeURIComponent(name)}"; filename*=UTF-8''${encodeURIComponent(name)}`);
|
|
49433
|
+
ctx.set("Content-Length", String(data.length));
|
|
49434
|
+
ctx.set("Cache-Control", "no-cache");
|
|
49435
|
+
ctx.body = data;
|
|
49436
|
+
} catch (err) {
|
|
49437
|
+
const code = err.code || "unknown";
|
|
49438
|
+
const statusMap = {
|
|
49439
|
+
missing_path: 400,
|
|
49440
|
+
invalid_path: 400,
|
|
49441
|
+
not_found: 404,
|
|
49442
|
+
ENOENT: 404,
|
|
49443
|
+
file_too_large: 413,
|
|
49444
|
+
unsupported_backend: 501,
|
|
49445
|
+
backend_error: 502,
|
|
49446
|
+
backend_timeout: 504
|
|
49447
|
+
};
|
|
49448
|
+
ctx.status = statusMap[code] || 500;
|
|
49449
|
+
ctx.body = { error: err.message, code };
|
|
49450
|
+
}
|
|
49451
|
+
});
|
|
49452
|
+
|
|
47653
49453
|
// packages/server/src/routes/hermes/proxy-handler.ts
|
|
47654
49454
|
init_usage_store();
|
|
47655
49455
|
function getGatewayManager() {
|
|
@@ -47680,7 +49480,7 @@ async function waitForGatewayReady(upstream, timeoutMs = 5e3) {
|
|
|
47680
49480
|
if (res.ok) return true;
|
|
47681
49481
|
} catch {
|
|
47682
49482
|
}
|
|
47683
|
-
await new Promise((
|
|
49483
|
+
await new Promise((resolve11) => setTimeout(resolve11, 250));
|
|
47684
49484
|
}
|
|
47685
49485
|
return false;
|
|
47686
49486
|
}
|
|
@@ -47883,8 +49683,11 @@ function registerRoutes(app, requireAuth2) {
|
|
|
47883
49683
|
app.use(configRoutes.routes());
|
|
47884
49684
|
app.use(logRoutes.routes());
|
|
47885
49685
|
app.use(codexAuthRoutes.routes());
|
|
49686
|
+
app.use(nousAuthRoutes.routes());
|
|
47886
49687
|
app.use(gatewayRoutes.routes());
|
|
47887
49688
|
app.use(weixinRoutes.routes());
|
|
49689
|
+
app.use(fileRoutes.routes());
|
|
49690
|
+
app.use(downloadRoutes.routes());
|
|
47888
49691
|
app.use(proxyRoutes.routes());
|
|
47889
49692
|
return proxyMiddleware;
|
|
47890
49693
|
}
|
|
@@ -47894,13 +49697,13 @@ var import_cors = __toESM(require_cors());
|
|
|
47894
49697
|
var import_koa_static = __toESM(require_koa_static());
|
|
47895
49698
|
var import_koa_send = __toESM(require_koa_send());
|
|
47896
49699
|
var import_os12 = __toESM(require("os"));
|
|
47897
|
-
var
|
|
47898
|
-
var
|
|
47899
|
-
var
|
|
49700
|
+
var import_path19 = require("path");
|
|
49701
|
+
var import_promises15 = require("fs/promises");
|
|
49702
|
+
var import_fs17 = require("fs");
|
|
47900
49703
|
init_logger();
|
|
47901
|
-
var APP_VERSION = true ? "0.4.
|
|
49704
|
+
var APP_VERSION = true ? "0.4.4" : (() => {
|
|
47902
49705
|
try {
|
|
47903
|
-
return JSON.parse(
|
|
49706
|
+
return JSON.parse(readFileSync11((0, import_path19.resolve)(__dirname, "../../package.json"), "utf-8")).version;
|
|
47904
49707
|
} catch {
|
|
47905
49708
|
return "dev";
|
|
47906
49709
|
}
|
|
@@ -47915,8 +49718,8 @@ process.on("unhandledRejection", (reason) => {
|
|
|
47915
49718
|
var server = null;
|
|
47916
49719
|
async function bootstrap() {
|
|
47917
49720
|
console.log(`hermes-web-ui v${APP_VERSION} starting...`);
|
|
47918
|
-
await (0,
|
|
47919
|
-
await (0,
|
|
49721
|
+
await (0, import_promises15.mkdir)(config.uploadDir, { recursive: true });
|
|
49722
|
+
await (0, import_promises15.mkdir)(config.dataDir, { recursive: true });
|
|
47920
49723
|
const authToken = await getToken();
|
|
47921
49724
|
const app = new koa_default();
|
|
47922
49725
|
await initGatewayManager();
|
|
@@ -47934,7 +49737,7 @@ async function bootstrap() {
|
|
|
47934
49737
|
console.log(`Auth enabled \u2014 token: ${authToken}`);
|
|
47935
49738
|
logger.info("Auth enabled \u2014 token: %s", authToken);
|
|
47936
49739
|
}
|
|
47937
|
-
const distDir = (0,
|
|
49740
|
+
const distDir = (0, import_path19.resolve)(__dirname, "..", "client");
|
|
47938
49741
|
app.use((0, import_koa_static.default)(distDir));
|
|
47939
49742
|
app.use(async (ctx) => {
|
|
47940
49743
|
if (!ctx.path.startsWith("/api") && ctx.path !== "/health" && ctx.path !== "/upload" && ctx.path !== "/webhook") {
|