meshy-node 0.0.9 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dashboard/assets/DashboardPage-9aRkE566.js +210 -0
- package/dashboard/assets/{DiffTab-DHa2twrY.js → DiffTab-BIU9YkOP.js} +4 -4
- package/dashboard/assets/FilesTab-DlIJQ12D.js +34 -0
- package/dashboard/assets/PreviewTab-Czs-1ywX.js +16 -0
- package/dashboard/assets/{folder-0eOoupgZ.js → folder-D1IG8qWX.js} +1 -1
- package/dashboard/assets/index-BzyFj1ix.css +1 -0
- package/dashboard/assets/{index-CRdTxsjS.js → index-vjxaNl7B.js} +10 -10
- package/dashboard/index.html +2 -2
- package/main.cjs +912 -883
- package/package.json +1 -1
- package/dashboard/assets/DashboardPage-D5VZZBFL.js +0 -200
- package/dashboard/assets/FilesTab-DI35HxWK.js +0 -11
- package/dashboard/assets/PreviewTab-CAEInFgg.js +0 -6
- package/dashboard/assets/index-Bx5CT0VB.css +0 -1
package/main.cjs
CHANGED
|
@@ -1460,8 +1460,8 @@ var require_node = __commonJS({
|
|
|
1460
1460
|
}
|
|
1461
1461
|
break;
|
|
1462
1462
|
case "FILE":
|
|
1463
|
-
var
|
|
1464
|
-
stream2 = new
|
|
1463
|
+
var fs16 = require("fs");
|
|
1464
|
+
stream2 = new fs16.SyncWriteStream(fd2, { autoClose: false });
|
|
1465
1465
|
stream2._type = "fs";
|
|
1466
1466
|
break;
|
|
1467
1467
|
case "PIPE":
|
|
@@ -14251,11 +14251,11 @@ var require_mime_types = __commonJS({
|
|
|
14251
14251
|
}
|
|
14252
14252
|
return exts[0];
|
|
14253
14253
|
}
|
|
14254
|
-
function lookup(
|
|
14255
|
-
if (!
|
|
14254
|
+
function lookup(path16) {
|
|
14255
|
+
if (!path16 || typeof path16 !== "string") {
|
|
14256
14256
|
return false;
|
|
14257
14257
|
}
|
|
14258
|
-
var extension2 = extname3("x." +
|
|
14258
|
+
var extension2 = extname3("x." + path16).toLowerCase().substr(1);
|
|
14259
14259
|
if (!extension2) {
|
|
14260
14260
|
return false;
|
|
14261
14261
|
}
|
|
@@ -17773,7 +17773,7 @@ var require_path_to_regexp = __commonJS({
|
|
|
17773
17773
|
"use strict";
|
|
17774
17774
|
module2.exports = pathToRegexp;
|
|
17775
17775
|
var MATCHING_GROUP_REGEXP = /\\.|\((?:\?<(.*?)>)?(?!\?)/g;
|
|
17776
|
-
function pathToRegexp(
|
|
17776
|
+
function pathToRegexp(path16, keys, options) {
|
|
17777
17777
|
options = options || {};
|
|
17778
17778
|
keys = keys || [];
|
|
17779
17779
|
var strict = options.strict;
|
|
@@ -17787,8 +17787,8 @@ var require_path_to_regexp = __commonJS({
|
|
|
17787
17787
|
var pos = 0;
|
|
17788
17788
|
var backtrack = "";
|
|
17789
17789
|
var m;
|
|
17790
|
-
if (
|
|
17791
|
-
while (m = MATCHING_GROUP_REGEXP.exec(
|
|
17790
|
+
if (path16 instanceof RegExp) {
|
|
17791
|
+
while (m = MATCHING_GROUP_REGEXP.exec(path16.source)) {
|
|
17792
17792
|
if (m[0][0] === "\\") continue;
|
|
17793
17793
|
keys.push({
|
|
17794
17794
|
name: m[1] || name++,
|
|
@@ -17796,18 +17796,18 @@ var require_path_to_regexp = __commonJS({
|
|
|
17796
17796
|
offset: m.index
|
|
17797
17797
|
});
|
|
17798
17798
|
}
|
|
17799
|
-
return
|
|
17799
|
+
return path16;
|
|
17800
17800
|
}
|
|
17801
|
-
if (Array.isArray(
|
|
17802
|
-
|
|
17801
|
+
if (Array.isArray(path16)) {
|
|
17802
|
+
path16 = path16.map(function(value) {
|
|
17803
17803
|
return pathToRegexp(value, keys, options).source;
|
|
17804
17804
|
});
|
|
17805
|
-
return new RegExp(
|
|
17805
|
+
return new RegExp(path16.join("|"), flags);
|
|
17806
17806
|
}
|
|
17807
|
-
if (typeof
|
|
17807
|
+
if (typeof path16 !== "string") {
|
|
17808
17808
|
throw new TypeError("path must be a string, array of strings, or regular expression");
|
|
17809
17809
|
}
|
|
17810
|
-
|
|
17810
|
+
path16 = path16.replace(
|
|
17811
17811
|
/\\.|(\/)?(\.)?:(\w+)(\(.*?\))?(\*)?(\?)?|[.*]|\/\(/g,
|
|
17812
17812
|
function(match, slash, format, key, capture, star, optional, offset) {
|
|
17813
17813
|
if (match[0] === "\\") {
|
|
@@ -17824,7 +17824,7 @@ var require_path_to_regexp = __commonJS({
|
|
|
17824
17824
|
if (slash || format) {
|
|
17825
17825
|
backtrack = "";
|
|
17826
17826
|
} else {
|
|
17827
|
-
backtrack +=
|
|
17827
|
+
backtrack += path16.slice(pos, offset);
|
|
17828
17828
|
}
|
|
17829
17829
|
pos = offset + match.length;
|
|
17830
17830
|
if (match === "*") {
|
|
@@ -17854,7 +17854,7 @@ var require_path_to_regexp = __commonJS({
|
|
|
17854
17854
|
return result;
|
|
17855
17855
|
}
|
|
17856
17856
|
);
|
|
17857
|
-
while (m = MATCHING_GROUP_REGEXP.exec(
|
|
17857
|
+
while (m = MATCHING_GROUP_REGEXP.exec(path16)) {
|
|
17858
17858
|
if (m[0][0] === "\\") continue;
|
|
17859
17859
|
if (keysOffset + i === keys.length || keys[keysOffset + i].offset > m.index) {
|
|
17860
17860
|
keys.splice(keysOffset + i, 0, {
|
|
@@ -17866,13 +17866,13 @@ var require_path_to_regexp = __commonJS({
|
|
|
17866
17866
|
}
|
|
17867
17867
|
i++;
|
|
17868
17868
|
}
|
|
17869
|
-
|
|
17869
|
+
path16 += strict ? "" : path16[path16.length - 1] === "/" ? "?" : "/?";
|
|
17870
17870
|
if (end) {
|
|
17871
|
-
|
|
17872
|
-
} else if (
|
|
17873
|
-
|
|
17871
|
+
path16 += "$";
|
|
17872
|
+
} else if (path16[path16.length - 1] !== "/") {
|
|
17873
|
+
path16 += lookahead ? "(?=/|$)" : "(?:/|$)";
|
|
17874
17874
|
}
|
|
17875
|
-
return new RegExp("^" +
|
|
17875
|
+
return new RegExp("^" + path16, flags);
|
|
17876
17876
|
}
|
|
17877
17877
|
}
|
|
17878
17878
|
});
|
|
@@ -17885,19 +17885,19 @@ var require_layer = __commonJS({
|
|
|
17885
17885
|
var debug = require_src()("express:router:layer");
|
|
17886
17886
|
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
17887
17887
|
module2.exports = Layer;
|
|
17888
|
-
function Layer(
|
|
17888
|
+
function Layer(path16, options, fn) {
|
|
17889
17889
|
if (!(this instanceof Layer)) {
|
|
17890
|
-
return new Layer(
|
|
17890
|
+
return new Layer(path16, options, fn);
|
|
17891
17891
|
}
|
|
17892
|
-
debug("new %o",
|
|
17892
|
+
debug("new %o", path16);
|
|
17893
17893
|
var opts = options || {};
|
|
17894
17894
|
this.handle = fn;
|
|
17895
17895
|
this.name = fn.name || "<anonymous>";
|
|
17896
17896
|
this.params = void 0;
|
|
17897
17897
|
this.path = void 0;
|
|
17898
|
-
this.regexp = pathRegexp(
|
|
17899
|
-
this.regexp.fast_star =
|
|
17900
|
-
this.regexp.fast_slash =
|
|
17898
|
+
this.regexp = pathRegexp(path16, this.keys = [], opts);
|
|
17899
|
+
this.regexp.fast_star = path16 === "*";
|
|
17900
|
+
this.regexp.fast_slash = path16 === "/" && opts.end === false;
|
|
17901
17901
|
}
|
|
17902
17902
|
Layer.prototype.handle_error = function handle_error(error, req, res, next) {
|
|
17903
17903
|
var fn = this.handle;
|
|
@@ -17921,20 +17921,20 @@ var require_layer = __commonJS({
|
|
|
17921
17921
|
next(err);
|
|
17922
17922
|
}
|
|
17923
17923
|
};
|
|
17924
|
-
Layer.prototype.match = function match(
|
|
17924
|
+
Layer.prototype.match = function match(path16) {
|
|
17925
17925
|
var match2;
|
|
17926
|
-
if (
|
|
17926
|
+
if (path16 != null) {
|
|
17927
17927
|
if (this.regexp.fast_slash) {
|
|
17928
17928
|
this.params = {};
|
|
17929
17929
|
this.path = "";
|
|
17930
17930
|
return true;
|
|
17931
17931
|
}
|
|
17932
17932
|
if (this.regexp.fast_star) {
|
|
17933
|
-
this.params = { "0": decode_param(
|
|
17934
|
-
this.path =
|
|
17933
|
+
this.params = { "0": decode_param(path16) };
|
|
17934
|
+
this.path = path16;
|
|
17935
17935
|
return true;
|
|
17936
17936
|
}
|
|
17937
|
-
match2 = this.regexp.exec(
|
|
17937
|
+
match2 = this.regexp.exec(path16);
|
|
17938
17938
|
}
|
|
17939
17939
|
if (!match2) {
|
|
17940
17940
|
this.params = void 0;
|
|
@@ -17976,10 +17976,10 @@ var require_layer = __commonJS({
|
|
|
17976
17976
|
var require_methods = __commonJS({
|
|
17977
17977
|
"../../node_modules/.pnpm/methods@1.1.2/node_modules/methods/index.js"(exports2, module2) {
|
|
17978
17978
|
"use strict";
|
|
17979
|
-
var
|
|
17979
|
+
var http3 = require("http");
|
|
17980
17980
|
module2.exports = getCurrentNodeMethods() || getBasicNodeMethods();
|
|
17981
17981
|
function getCurrentNodeMethods() {
|
|
17982
|
-
return
|
|
17982
|
+
return http3.METHODS && http3.METHODS.map(function lowerCaseMethod(method) {
|
|
17983
17983
|
return method.toLowerCase();
|
|
17984
17984
|
});
|
|
17985
17985
|
}
|
|
@@ -18027,10 +18027,10 @@ var require_route = __commonJS({
|
|
|
18027
18027
|
var slice = Array.prototype.slice;
|
|
18028
18028
|
var toString = Object.prototype.toString;
|
|
18029
18029
|
module2.exports = Route;
|
|
18030
|
-
function Route(
|
|
18031
|
-
this.path =
|
|
18030
|
+
function Route(path16) {
|
|
18031
|
+
this.path = path16;
|
|
18032
18032
|
this.stack = [];
|
|
18033
|
-
debug("new %o",
|
|
18033
|
+
debug("new %o", path16);
|
|
18034
18034
|
this.methods = {};
|
|
18035
18035
|
}
|
|
18036
18036
|
Route.prototype._handles_method = function _handles_method(method) {
|
|
@@ -18243,8 +18243,8 @@ var require_router = __commonJS({
|
|
|
18243
18243
|
if (++sync > 100) {
|
|
18244
18244
|
return setImmediate(next, err);
|
|
18245
18245
|
}
|
|
18246
|
-
var
|
|
18247
|
-
if (
|
|
18246
|
+
var path16 = getPathname(req);
|
|
18247
|
+
if (path16 == null) {
|
|
18248
18248
|
return done(layerError);
|
|
18249
18249
|
}
|
|
18250
18250
|
var layer;
|
|
@@ -18252,7 +18252,7 @@ var require_router = __commonJS({
|
|
|
18252
18252
|
var route;
|
|
18253
18253
|
while (match !== true && idx < stack.length) {
|
|
18254
18254
|
layer = stack[idx++];
|
|
18255
|
-
match = matchLayer(layer,
|
|
18255
|
+
match = matchLayer(layer, path16);
|
|
18256
18256
|
route = layer.route;
|
|
18257
18257
|
if (typeof match !== "boolean") {
|
|
18258
18258
|
layerError = layerError || match;
|
|
@@ -18290,18 +18290,18 @@ var require_router = __commonJS({
|
|
|
18290
18290
|
} else if (route) {
|
|
18291
18291
|
layer.handle_request(req, res, next);
|
|
18292
18292
|
} else {
|
|
18293
|
-
trim_prefix(layer, layerError, layerPath,
|
|
18293
|
+
trim_prefix(layer, layerError, layerPath, path16);
|
|
18294
18294
|
}
|
|
18295
18295
|
sync = 0;
|
|
18296
18296
|
});
|
|
18297
18297
|
}
|
|
18298
|
-
function trim_prefix(layer, layerError, layerPath,
|
|
18298
|
+
function trim_prefix(layer, layerError, layerPath, path16) {
|
|
18299
18299
|
if (layerPath.length !== 0) {
|
|
18300
|
-
if (layerPath !==
|
|
18300
|
+
if (layerPath !== path16.slice(0, layerPath.length)) {
|
|
18301
18301
|
next(layerError);
|
|
18302
18302
|
return;
|
|
18303
18303
|
}
|
|
18304
|
-
var c =
|
|
18304
|
+
var c = path16[layerPath.length];
|
|
18305
18305
|
if (c && c !== "/" && c !== ".") return next(layerError);
|
|
18306
18306
|
debug("trim prefix (%s) from url %s", layerPath, req.url);
|
|
18307
18307
|
removed = layerPath;
|
|
@@ -18379,7 +18379,7 @@ var require_router = __commonJS({
|
|
|
18379
18379
|
};
|
|
18380
18380
|
proto.use = function use(fn) {
|
|
18381
18381
|
var offset = 0;
|
|
18382
|
-
var
|
|
18382
|
+
var path16 = "/";
|
|
18383
18383
|
if (typeof fn !== "function") {
|
|
18384
18384
|
var arg = fn;
|
|
18385
18385
|
while (Array.isArray(arg) && arg.length !== 0) {
|
|
@@ -18387,7 +18387,7 @@ var require_router = __commonJS({
|
|
|
18387
18387
|
}
|
|
18388
18388
|
if (typeof arg !== "function") {
|
|
18389
18389
|
offset = 1;
|
|
18390
|
-
|
|
18390
|
+
path16 = fn;
|
|
18391
18391
|
}
|
|
18392
18392
|
}
|
|
18393
18393
|
var callbacks = flatten(slice.call(arguments, offset));
|
|
@@ -18399,8 +18399,8 @@ var require_router = __commonJS({
|
|
|
18399
18399
|
if (typeof fn !== "function") {
|
|
18400
18400
|
throw new TypeError("Router.use() requires a middleware function but got a " + gettype(fn));
|
|
18401
18401
|
}
|
|
18402
|
-
debug("use %o %s",
|
|
18403
|
-
var layer = new Layer(
|
|
18402
|
+
debug("use %o %s", path16, fn.name || "<anonymous>");
|
|
18403
|
+
var layer = new Layer(path16, {
|
|
18404
18404
|
sensitive: this.caseSensitive,
|
|
18405
18405
|
strict: false,
|
|
18406
18406
|
end: false
|
|
@@ -18410,9 +18410,9 @@ var require_router = __commonJS({
|
|
|
18410
18410
|
}
|
|
18411
18411
|
return this;
|
|
18412
18412
|
};
|
|
18413
|
-
proto.route = function route(
|
|
18414
|
-
var route2 = new Route(
|
|
18415
|
-
var layer = new Layer(
|
|
18413
|
+
proto.route = function route(path16) {
|
|
18414
|
+
var route2 = new Route(path16);
|
|
18415
|
+
var layer = new Layer(path16, {
|
|
18416
18416
|
sensitive: this.caseSensitive,
|
|
18417
18417
|
strict: this.strict,
|
|
18418
18418
|
end: true
|
|
@@ -18422,8 +18422,8 @@ var require_router = __commonJS({
|
|
|
18422
18422
|
return route2;
|
|
18423
18423
|
};
|
|
18424
18424
|
methods.concat("all").forEach(function(method) {
|
|
18425
|
-
proto[method] = function(
|
|
18426
|
-
var route = this.route(
|
|
18425
|
+
proto[method] = function(path16) {
|
|
18426
|
+
var route = this.route(path16);
|
|
18427
18427
|
route[method].apply(route, slice.call(arguments, 1));
|
|
18428
18428
|
return this;
|
|
18429
18429
|
};
|
|
@@ -18459,9 +18459,9 @@ var require_router = __commonJS({
|
|
|
18459
18459
|
}
|
|
18460
18460
|
return toString.call(obj).replace(objectRegExp, "$1");
|
|
18461
18461
|
}
|
|
18462
|
-
function matchLayer(layer,
|
|
18462
|
+
function matchLayer(layer, path16) {
|
|
18463
18463
|
try {
|
|
18464
|
-
return layer.match(
|
|
18464
|
+
return layer.match(path16);
|
|
18465
18465
|
} catch (err) {
|
|
18466
18466
|
return err;
|
|
18467
18467
|
}
|
|
@@ -18579,13 +18579,13 @@ var require_view = __commonJS({
|
|
|
18579
18579
|
"../../node_modules/.pnpm/express@4.22.1/node_modules/express/lib/view.js"(exports2, module2) {
|
|
18580
18580
|
"use strict";
|
|
18581
18581
|
var debug = require_src()("express:view");
|
|
18582
|
-
var
|
|
18583
|
-
var
|
|
18584
|
-
var dirname3 =
|
|
18585
|
-
var
|
|
18586
|
-
var extname3 =
|
|
18587
|
-
var join13 =
|
|
18588
|
-
var resolve10 =
|
|
18582
|
+
var path16 = require("path");
|
|
18583
|
+
var fs16 = require("fs");
|
|
18584
|
+
var dirname3 = path16.dirname;
|
|
18585
|
+
var basename3 = path16.basename;
|
|
18586
|
+
var extname3 = path16.extname;
|
|
18587
|
+
var join13 = path16.join;
|
|
18588
|
+
var resolve10 = path16.resolve;
|
|
18589
18589
|
module2.exports = View;
|
|
18590
18590
|
function View(name, options) {
|
|
18591
18591
|
var opts = options || {};
|
|
@@ -18614,17 +18614,17 @@ var require_view = __commonJS({
|
|
|
18614
18614
|
this.path = this.lookup(fileName);
|
|
18615
18615
|
}
|
|
18616
18616
|
View.prototype.lookup = function lookup(name) {
|
|
18617
|
-
var
|
|
18617
|
+
var path17;
|
|
18618
18618
|
var roots = [].concat(this.root);
|
|
18619
18619
|
debug('lookup "%s"', name);
|
|
18620
|
-
for (var i = 0; i < roots.length && !
|
|
18620
|
+
for (var i = 0; i < roots.length && !path17; i++) {
|
|
18621
18621
|
var root = roots[i];
|
|
18622
18622
|
var loc = resolve10(root, name);
|
|
18623
18623
|
var dir = dirname3(loc);
|
|
18624
|
-
var file =
|
|
18625
|
-
|
|
18624
|
+
var file = basename3(loc);
|
|
18625
|
+
path17 = this.resolve(dir, file);
|
|
18626
18626
|
}
|
|
18627
|
-
return
|
|
18627
|
+
return path17;
|
|
18628
18628
|
};
|
|
18629
18629
|
View.prototype.render = function render(options, callback) {
|
|
18630
18630
|
debug('render "%s"', this.path);
|
|
@@ -18632,21 +18632,21 @@ var require_view = __commonJS({
|
|
|
18632
18632
|
};
|
|
18633
18633
|
View.prototype.resolve = function resolve11(dir, file) {
|
|
18634
18634
|
var ext = this.ext;
|
|
18635
|
-
var
|
|
18636
|
-
var stat = tryStat(
|
|
18635
|
+
var path17 = join13(dir, file);
|
|
18636
|
+
var stat = tryStat(path17);
|
|
18637
18637
|
if (stat && stat.isFile()) {
|
|
18638
|
-
return
|
|
18638
|
+
return path17;
|
|
18639
18639
|
}
|
|
18640
|
-
|
|
18641
|
-
stat = tryStat(
|
|
18640
|
+
path17 = join13(dir, basename3(file, ext), "index" + ext);
|
|
18641
|
+
stat = tryStat(path17);
|
|
18642
18642
|
if (stat && stat.isFile()) {
|
|
18643
|
-
return
|
|
18643
|
+
return path17;
|
|
18644
18644
|
}
|
|
18645
18645
|
};
|
|
18646
|
-
function tryStat(
|
|
18647
|
-
debug('stat "%s"',
|
|
18646
|
+
function tryStat(path17) {
|
|
18647
|
+
debug('stat "%s"', path17);
|
|
18648
18648
|
try {
|
|
18649
|
-
return
|
|
18649
|
+
return fs16.statSync(path17);
|
|
18650
18650
|
} catch (e) {
|
|
18651
18651
|
return void 0;
|
|
18652
18652
|
}
|
|
@@ -18719,7 +18719,7 @@ var require_content_disposition = __commonJS({
|
|
|
18719
18719
|
"use strict";
|
|
18720
18720
|
module2.exports = contentDisposition;
|
|
18721
18721
|
module2.exports.parse = parse;
|
|
18722
|
-
var
|
|
18722
|
+
var basename3 = require("path").basename;
|
|
18723
18723
|
var Buffer2 = require_safe_buffer().Buffer;
|
|
18724
18724
|
var ENCODE_URL_ATTR_CHAR_REGEXP = /[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g;
|
|
18725
18725
|
var HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/;
|
|
@@ -18755,9 +18755,9 @@ var require_content_disposition = __commonJS({
|
|
|
18755
18755
|
if (typeof fallback === "string" && NON_LATIN1_REGEXP.test(fallback)) {
|
|
18756
18756
|
throw new TypeError("fallback must be ISO-8859-1 string");
|
|
18757
18757
|
}
|
|
18758
|
-
var name =
|
|
18758
|
+
var name = basename3(filename);
|
|
18759
18759
|
var isQuotedString = TEXT_REGEXP.test(name);
|
|
18760
|
-
var fallbackName = typeof fallback !== "string" ? fallback && getlatin1(name) :
|
|
18760
|
+
var fallbackName = typeof fallback !== "string" ? fallback && getlatin1(name) : basename3(fallback);
|
|
18761
18761
|
var hasFallback = typeof fallbackName === "string" && fallbackName !== name;
|
|
18762
18762
|
if (hasFallback || !isQuotedString || HEX_ESCAPE_REGEXP.test(name)) {
|
|
18763
18763
|
params["filename*"] = name;
|
|
@@ -19002,8 +19002,8 @@ var require_types = __commonJS({
|
|
|
19002
19002
|
var require_mime = __commonJS({
|
|
19003
19003
|
"../../node_modules/.pnpm/mime@1.6.0/node_modules/mime/mime.js"(exports2, module2) {
|
|
19004
19004
|
"use strict";
|
|
19005
|
-
var
|
|
19006
|
-
var
|
|
19005
|
+
var path16 = require("path");
|
|
19006
|
+
var fs16 = require("fs");
|
|
19007
19007
|
function Mime() {
|
|
19008
19008
|
this.types = /* @__PURE__ */ Object.create(null);
|
|
19009
19009
|
this.extensions = /* @__PURE__ */ Object.create(null);
|
|
@@ -19024,7 +19024,7 @@ var require_mime = __commonJS({
|
|
|
19024
19024
|
};
|
|
19025
19025
|
Mime.prototype.load = function(file) {
|
|
19026
19026
|
this._loading = file;
|
|
19027
|
-
var map = {}, content =
|
|
19027
|
+
var map = {}, content = fs16.readFileSync(file, "ascii"), lines = content.split(/[\r\n]+/);
|
|
19028
19028
|
lines.forEach(function(line) {
|
|
19029
19029
|
var fields = line.replace(/\s*#.*|^\s*|\s*$/g, "").split(/\s+/);
|
|
19030
19030
|
map[fields.shift()] = fields;
|
|
@@ -19032,8 +19032,8 @@ var require_mime = __commonJS({
|
|
|
19032
19032
|
this.define(map);
|
|
19033
19033
|
this._loading = null;
|
|
19034
19034
|
};
|
|
19035
|
-
Mime.prototype.lookup = function(
|
|
19036
|
-
var ext =
|
|
19035
|
+
Mime.prototype.lookup = function(path17, fallback) {
|
|
19036
|
+
var ext = path17.replace(/^.*[\.\/\\]/, "").toLowerCase();
|
|
19037
19037
|
return this.types[ext] || fallback || this.default_type;
|
|
19038
19038
|
};
|
|
19039
19039
|
Mime.prototype.extension = function(mimeType) {
|
|
@@ -19263,33 +19263,33 @@ var require_send = __commonJS({
|
|
|
19263
19263
|
var escapeHtml = require_escape_html();
|
|
19264
19264
|
var etag = require_etag();
|
|
19265
19265
|
var fresh = require_fresh();
|
|
19266
|
-
var
|
|
19266
|
+
var fs16 = require("fs");
|
|
19267
19267
|
var mime = require_mime();
|
|
19268
19268
|
var ms = require_ms2();
|
|
19269
19269
|
var onFinished = require_on_finished();
|
|
19270
19270
|
var parseRange = require_range_parser();
|
|
19271
|
-
var
|
|
19271
|
+
var path16 = require("path");
|
|
19272
19272
|
var statuses = require_statuses();
|
|
19273
19273
|
var Stream = require("stream");
|
|
19274
19274
|
var util2 = require("util");
|
|
19275
|
-
var extname3 =
|
|
19276
|
-
var join13 =
|
|
19277
|
-
var normalize =
|
|
19278
|
-
var resolve10 =
|
|
19279
|
-
var sep3 =
|
|
19275
|
+
var extname3 = path16.extname;
|
|
19276
|
+
var join13 = path16.join;
|
|
19277
|
+
var normalize = path16.normalize;
|
|
19278
|
+
var resolve10 = path16.resolve;
|
|
19279
|
+
var sep3 = path16.sep;
|
|
19280
19280
|
var BYTES_RANGE_REGEXP = /^ *bytes=/;
|
|
19281
19281
|
var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1e3;
|
|
19282
19282
|
var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
|
|
19283
19283
|
module2.exports = send;
|
|
19284
19284
|
module2.exports.mime = mime;
|
|
19285
|
-
function send(req,
|
|
19286
|
-
return new SendStream(req,
|
|
19285
|
+
function send(req, path17, options) {
|
|
19286
|
+
return new SendStream(req, path17, options);
|
|
19287
19287
|
}
|
|
19288
|
-
function SendStream(req,
|
|
19288
|
+
function SendStream(req, path17, options) {
|
|
19289
19289
|
Stream.call(this);
|
|
19290
19290
|
var opts = options || {};
|
|
19291
19291
|
this.options = opts;
|
|
19292
|
-
this.path =
|
|
19292
|
+
this.path = path17;
|
|
19293
19293
|
this.req = req;
|
|
19294
19294
|
this._acceptRanges = opts.acceptRanges !== void 0 ? Boolean(opts.acceptRanges) : true;
|
|
19295
19295
|
this._cacheControl = opts.cacheControl !== void 0 ? Boolean(opts.cacheControl) : true;
|
|
@@ -19335,8 +19335,8 @@ var require_send = __commonJS({
|
|
|
19335
19335
|
this._index = index2;
|
|
19336
19336
|
return this;
|
|
19337
19337
|
}, "send.index: pass index as option");
|
|
19338
|
-
SendStream.prototype.root = function root(
|
|
19339
|
-
this._root = resolve10(String(
|
|
19338
|
+
SendStream.prototype.root = function root(path17) {
|
|
19339
|
+
this._root = resolve10(String(path17));
|
|
19340
19340
|
debug("root %s", this._root);
|
|
19341
19341
|
return this;
|
|
19342
19342
|
};
|
|
@@ -19449,10 +19449,10 @@ var require_send = __commonJS({
|
|
|
19449
19449
|
var lastModified = this.res.getHeader("Last-Modified");
|
|
19450
19450
|
return parseHttpDate(lastModified) <= parseHttpDate(ifRange);
|
|
19451
19451
|
};
|
|
19452
|
-
SendStream.prototype.redirect = function redirect(
|
|
19452
|
+
SendStream.prototype.redirect = function redirect(path17) {
|
|
19453
19453
|
var res = this.res;
|
|
19454
19454
|
if (hasListeners(this, "directory")) {
|
|
19455
|
-
this.emit("directory", res,
|
|
19455
|
+
this.emit("directory", res, path17);
|
|
19456
19456
|
return;
|
|
19457
19457
|
}
|
|
19458
19458
|
if (this.hasTrailingSlash()) {
|
|
@@ -19472,42 +19472,42 @@ var require_send = __commonJS({
|
|
|
19472
19472
|
SendStream.prototype.pipe = function pipe(res) {
|
|
19473
19473
|
var root = this._root;
|
|
19474
19474
|
this.res = res;
|
|
19475
|
-
var
|
|
19476
|
-
if (
|
|
19475
|
+
var path17 = decode(this.path);
|
|
19476
|
+
if (path17 === -1) {
|
|
19477
19477
|
this.error(400);
|
|
19478
19478
|
return res;
|
|
19479
19479
|
}
|
|
19480
|
-
if (~
|
|
19480
|
+
if (~path17.indexOf("\0")) {
|
|
19481
19481
|
this.error(400);
|
|
19482
19482
|
return res;
|
|
19483
19483
|
}
|
|
19484
19484
|
var parts;
|
|
19485
19485
|
if (root !== null) {
|
|
19486
|
-
if (
|
|
19487
|
-
|
|
19486
|
+
if (path17) {
|
|
19487
|
+
path17 = normalize("." + sep3 + path17);
|
|
19488
19488
|
}
|
|
19489
|
-
if (UP_PATH_REGEXP.test(
|
|
19490
|
-
debug('malicious path "%s"',
|
|
19489
|
+
if (UP_PATH_REGEXP.test(path17)) {
|
|
19490
|
+
debug('malicious path "%s"', path17);
|
|
19491
19491
|
this.error(403);
|
|
19492
19492
|
return res;
|
|
19493
19493
|
}
|
|
19494
|
-
parts =
|
|
19495
|
-
|
|
19494
|
+
parts = path17.split(sep3);
|
|
19495
|
+
path17 = normalize(join13(root, path17));
|
|
19496
19496
|
} else {
|
|
19497
|
-
if (UP_PATH_REGEXP.test(
|
|
19498
|
-
debug('malicious path "%s"',
|
|
19497
|
+
if (UP_PATH_REGEXP.test(path17)) {
|
|
19498
|
+
debug('malicious path "%s"', path17);
|
|
19499
19499
|
this.error(403);
|
|
19500
19500
|
return res;
|
|
19501
19501
|
}
|
|
19502
|
-
parts = normalize(
|
|
19503
|
-
|
|
19502
|
+
parts = normalize(path17).split(sep3);
|
|
19503
|
+
path17 = resolve10(path17);
|
|
19504
19504
|
}
|
|
19505
19505
|
if (containsDotFile(parts)) {
|
|
19506
19506
|
var access = this._dotfiles;
|
|
19507
19507
|
if (access === void 0) {
|
|
19508
19508
|
access = parts[parts.length - 1][0] === "." ? this._hidden ? "allow" : "ignore" : "allow";
|
|
19509
19509
|
}
|
|
19510
|
-
debug('%s dotfile "%s"', access,
|
|
19510
|
+
debug('%s dotfile "%s"', access, path17);
|
|
19511
19511
|
switch (access) {
|
|
19512
19512
|
case "allow":
|
|
19513
19513
|
break;
|
|
@@ -19521,13 +19521,13 @@ var require_send = __commonJS({
|
|
|
19521
19521
|
}
|
|
19522
19522
|
}
|
|
19523
19523
|
if (this._index.length && this.hasTrailingSlash()) {
|
|
19524
|
-
this.sendIndex(
|
|
19524
|
+
this.sendIndex(path17);
|
|
19525
19525
|
return res;
|
|
19526
19526
|
}
|
|
19527
|
-
this.sendFile(
|
|
19527
|
+
this.sendFile(path17);
|
|
19528
19528
|
return res;
|
|
19529
19529
|
};
|
|
19530
|
-
SendStream.prototype.send = function send2(
|
|
19530
|
+
SendStream.prototype.send = function send2(path17, stat) {
|
|
19531
19531
|
var len = stat.size;
|
|
19532
19532
|
var options = this.options;
|
|
19533
19533
|
var opts = {};
|
|
@@ -19539,9 +19539,9 @@ var require_send = __commonJS({
|
|
|
19539
19539
|
this.headersAlreadySent();
|
|
19540
19540
|
return;
|
|
19541
19541
|
}
|
|
19542
|
-
debug('pipe "%s"',
|
|
19543
|
-
this.setHeader(
|
|
19544
|
-
this.type(
|
|
19542
|
+
debug('pipe "%s"', path17);
|
|
19543
|
+
this.setHeader(path17, stat);
|
|
19544
|
+
this.type(path17);
|
|
19545
19545
|
if (this.isConditionalGET()) {
|
|
19546
19546
|
if (this.isPreconditionFailure()) {
|
|
19547
19547
|
this.error(412);
|
|
@@ -19590,28 +19590,28 @@ var require_send = __commonJS({
|
|
|
19590
19590
|
res.end();
|
|
19591
19591
|
return;
|
|
19592
19592
|
}
|
|
19593
|
-
this.stream(
|
|
19593
|
+
this.stream(path17, opts);
|
|
19594
19594
|
};
|
|
19595
|
-
SendStream.prototype.sendFile = function sendFile(
|
|
19595
|
+
SendStream.prototype.sendFile = function sendFile(path17) {
|
|
19596
19596
|
var i = 0;
|
|
19597
19597
|
var self = this;
|
|
19598
|
-
debug('stat "%s"',
|
|
19599
|
-
|
|
19600
|
-
if (err && err.code === "ENOENT" && !extname3(
|
|
19598
|
+
debug('stat "%s"', path17);
|
|
19599
|
+
fs16.stat(path17, function onstat(err, stat) {
|
|
19600
|
+
if (err && err.code === "ENOENT" && !extname3(path17) && path17[path17.length - 1] !== sep3) {
|
|
19601
19601
|
return next(err);
|
|
19602
19602
|
}
|
|
19603
19603
|
if (err) return self.onStatError(err);
|
|
19604
|
-
if (stat.isDirectory()) return self.redirect(
|
|
19605
|
-
self.emit("file",
|
|
19606
|
-
self.send(
|
|
19604
|
+
if (stat.isDirectory()) return self.redirect(path17);
|
|
19605
|
+
self.emit("file", path17, stat);
|
|
19606
|
+
self.send(path17, stat);
|
|
19607
19607
|
});
|
|
19608
19608
|
function next(err) {
|
|
19609
19609
|
if (self._extensions.length <= i) {
|
|
19610
19610
|
return err ? self.onStatError(err) : self.error(404);
|
|
19611
19611
|
}
|
|
19612
|
-
var p =
|
|
19612
|
+
var p = path17 + "." + self._extensions[i++];
|
|
19613
19613
|
debug('stat "%s"', p);
|
|
19614
|
-
|
|
19614
|
+
fs16.stat(p, function(err2, stat) {
|
|
19615
19615
|
if (err2) return next(err2);
|
|
19616
19616
|
if (stat.isDirectory()) return next();
|
|
19617
19617
|
self.emit("file", p, stat);
|
|
@@ -19619,7 +19619,7 @@ var require_send = __commonJS({
|
|
|
19619
19619
|
});
|
|
19620
19620
|
}
|
|
19621
19621
|
};
|
|
19622
|
-
SendStream.prototype.sendIndex = function sendIndex(
|
|
19622
|
+
SendStream.prototype.sendIndex = function sendIndex(path17) {
|
|
19623
19623
|
var i = -1;
|
|
19624
19624
|
var self = this;
|
|
19625
19625
|
function next(err) {
|
|
@@ -19627,9 +19627,9 @@ var require_send = __commonJS({
|
|
|
19627
19627
|
if (err) return self.onStatError(err);
|
|
19628
19628
|
return self.error(404);
|
|
19629
19629
|
}
|
|
19630
|
-
var p = join13(
|
|
19630
|
+
var p = join13(path17, self._index[i]);
|
|
19631
19631
|
debug('stat "%s"', p);
|
|
19632
|
-
|
|
19632
|
+
fs16.stat(p, function(err2, stat) {
|
|
19633
19633
|
if (err2) return next(err2);
|
|
19634
19634
|
if (stat.isDirectory()) return next();
|
|
19635
19635
|
self.emit("file", p, stat);
|
|
@@ -19638,10 +19638,10 @@ var require_send = __commonJS({
|
|
|
19638
19638
|
}
|
|
19639
19639
|
next();
|
|
19640
19640
|
};
|
|
19641
|
-
SendStream.prototype.stream = function stream(
|
|
19641
|
+
SendStream.prototype.stream = function stream(path17, options) {
|
|
19642
19642
|
var self = this;
|
|
19643
19643
|
var res = this.res;
|
|
19644
|
-
var stream2 =
|
|
19644
|
+
var stream2 = fs16.createReadStream(path17, options);
|
|
19645
19645
|
this.emit("stream", stream2);
|
|
19646
19646
|
stream2.pipe(res);
|
|
19647
19647
|
function cleanup() {
|
|
@@ -19656,10 +19656,10 @@ var require_send = __commonJS({
|
|
|
19656
19656
|
self.emit("end");
|
|
19657
19657
|
});
|
|
19658
19658
|
};
|
|
19659
|
-
SendStream.prototype.type = function type(
|
|
19659
|
+
SendStream.prototype.type = function type(path17) {
|
|
19660
19660
|
var res = this.res;
|
|
19661
19661
|
if (res.getHeader("Content-Type")) return;
|
|
19662
|
-
var type2 = mime.lookup(
|
|
19662
|
+
var type2 = mime.lookup(path17);
|
|
19663
19663
|
if (!type2) {
|
|
19664
19664
|
debug("no content-type");
|
|
19665
19665
|
return;
|
|
@@ -19668,9 +19668,9 @@ var require_send = __commonJS({
|
|
|
19668
19668
|
debug("content-type %s", type2);
|
|
19669
19669
|
res.setHeader("Content-Type", type2 + (charset ? "; charset=" + charset : ""));
|
|
19670
19670
|
};
|
|
19671
|
-
SendStream.prototype.setHeader = function setHeader(
|
|
19671
|
+
SendStream.prototype.setHeader = function setHeader(path17, stat) {
|
|
19672
19672
|
var res = this.res;
|
|
19673
|
-
this.emit("headers", res,
|
|
19673
|
+
this.emit("headers", res, path17, stat);
|
|
19674
19674
|
if (this._acceptRanges && !res.getHeader("Accept-Ranges")) {
|
|
19675
19675
|
debug("accept ranges");
|
|
19676
19676
|
res.setHeader("Accept-Ranges", "bytes");
|
|
@@ -19729,9 +19729,9 @@ var require_send = __commonJS({
|
|
|
19729
19729
|
}
|
|
19730
19730
|
return err instanceof Error ? createError(status, err, { expose: false }) : createError(status, err);
|
|
19731
19731
|
}
|
|
19732
|
-
function decode(
|
|
19732
|
+
function decode(path17) {
|
|
19733
19733
|
try {
|
|
19734
|
-
return decodeURIComponent(
|
|
19734
|
+
return decodeURIComponent(path17);
|
|
19735
19735
|
} catch (err) {
|
|
19736
19736
|
return -1;
|
|
19737
19737
|
}
|
|
@@ -20641,10 +20641,10 @@ var require_utils2 = __commonJS({
|
|
|
20641
20641
|
var querystring = require("querystring");
|
|
20642
20642
|
exports2.etag = createETagGenerator({ weak: false });
|
|
20643
20643
|
exports2.wetag = createETagGenerator({ weak: true });
|
|
20644
|
-
exports2.isAbsolute = function(
|
|
20645
|
-
if ("/" ===
|
|
20646
|
-
if (":" ===
|
|
20647
|
-
if ("\\\\" ===
|
|
20644
|
+
exports2.isAbsolute = function(path16) {
|
|
20645
|
+
if ("/" === path16[0]) return true;
|
|
20646
|
+
if (":" === path16[1] && ("\\" === path16[2] || "/" === path16[2])) return true;
|
|
20647
|
+
if ("\\\\" === path16.substring(0, 2)) return true;
|
|
20648
20648
|
};
|
|
20649
20649
|
exports2.flatten = deprecate.function(
|
|
20650
20650
|
flatten,
|
|
@@ -20767,13 +20767,13 @@ var require_application = __commonJS({
|
|
|
20767
20767
|
"../../node_modules/.pnpm/express@4.22.1/node_modules/express/lib/application.js"(exports2, module2) {
|
|
20768
20768
|
"use strict";
|
|
20769
20769
|
var finalhandler = require_finalhandler();
|
|
20770
|
-
var
|
|
20770
|
+
var Router8 = require_router();
|
|
20771
20771
|
var methods = require_methods();
|
|
20772
20772
|
var middleware = require_init();
|
|
20773
20773
|
var query = require_query();
|
|
20774
20774
|
var debug = require_src()("express:application");
|
|
20775
20775
|
var View = require_view();
|
|
20776
|
-
var
|
|
20776
|
+
var http3 = require("http");
|
|
20777
20777
|
var compileETag = require_utils2().compileETag;
|
|
20778
20778
|
var compileQueryParser = require_utils2().compileQueryParser;
|
|
20779
20779
|
var compileTrust = require_utils2().compileTrust;
|
|
@@ -20832,7 +20832,7 @@ var require_application = __commonJS({
|
|
|
20832
20832
|
};
|
|
20833
20833
|
app.lazyrouter = function lazyrouter() {
|
|
20834
20834
|
if (!this._router) {
|
|
20835
|
-
this._router = new
|
|
20835
|
+
this._router = new Router8({
|
|
20836
20836
|
caseSensitive: this.enabled("case sensitive routing"),
|
|
20837
20837
|
strict: this.enabled("strict routing")
|
|
20838
20838
|
});
|
|
@@ -20855,7 +20855,7 @@ var require_application = __commonJS({
|
|
|
20855
20855
|
};
|
|
20856
20856
|
app.use = function use(fn) {
|
|
20857
20857
|
var offset = 0;
|
|
20858
|
-
var
|
|
20858
|
+
var path16 = "/";
|
|
20859
20859
|
if (typeof fn !== "function") {
|
|
20860
20860
|
var arg = fn;
|
|
20861
20861
|
while (Array.isArray(arg) && arg.length !== 0) {
|
|
@@ -20863,7 +20863,7 @@ var require_application = __commonJS({
|
|
|
20863
20863
|
}
|
|
20864
20864
|
if (typeof arg !== "function") {
|
|
20865
20865
|
offset = 1;
|
|
20866
|
-
|
|
20866
|
+
path16 = fn;
|
|
20867
20867
|
}
|
|
20868
20868
|
}
|
|
20869
20869
|
var fns = flatten(slice.call(arguments, offset));
|
|
@@ -20874,12 +20874,12 @@ var require_application = __commonJS({
|
|
|
20874
20874
|
var router = this._router;
|
|
20875
20875
|
fns.forEach(function(fn2) {
|
|
20876
20876
|
if (!fn2 || !fn2.handle || !fn2.set) {
|
|
20877
|
-
return router.use(
|
|
20877
|
+
return router.use(path16, fn2);
|
|
20878
20878
|
}
|
|
20879
|
-
debug(".use app under %s",
|
|
20880
|
-
fn2.mountpath =
|
|
20879
|
+
debug(".use app under %s", path16);
|
|
20880
|
+
fn2.mountpath = path16;
|
|
20881
20881
|
fn2.parent = this;
|
|
20882
|
-
router.use(
|
|
20882
|
+
router.use(path16, function mounted_app(req, res, next) {
|
|
20883
20883
|
var orig = req.app;
|
|
20884
20884
|
fn2.handle(req, res, function(err) {
|
|
20885
20885
|
setPrototypeOf(req, orig.request);
|
|
@@ -20891,9 +20891,9 @@ var require_application = __commonJS({
|
|
|
20891
20891
|
}, this);
|
|
20892
20892
|
return this;
|
|
20893
20893
|
};
|
|
20894
|
-
app.route = function route(
|
|
20894
|
+
app.route = function route(path16) {
|
|
20895
20895
|
this.lazyrouter();
|
|
20896
|
-
return this._router.route(
|
|
20896
|
+
return this._router.route(path16);
|
|
20897
20897
|
};
|
|
20898
20898
|
app.engine = function engine(ext, fn) {
|
|
20899
20899
|
if (typeof fn !== "function") {
|
|
@@ -20944,7 +20944,7 @@ var require_application = __commonJS({
|
|
|
20944
20944
|
}
|
|
20945
20945
|
return this;
|
|
20946
20946
|
};
|
|
20947
|
-
app.path = function
|
|
20947
|
+
app.path = function path16() {
|
|
20948
20948
|
return this.parent ? this.parent.path() + this.mountpath : "";
|
|
20949
20949
|
};
|
|
20950
20950
|
app.enabled = function enabled(setting) {
|
|
@@ -20960,19 +20960,19 @@ var require_application = __commonJS({
|
|
|
20960
20960
|
return this.set(setting, false);
|
|
20961
20961
|
};
|
|
20962
20962
|
methods.forEach(function(method) {
|
|
20963
|
-
app[method] = function(
|
|
20963
|
+
app[method] = function(path16) {
|
|
20964
20964
|
if (method === "get" && arguments.length === 1) {
|
|
20965
|
-
return this.set(
|
|
20965
|
+
return this.set(path16);
|
|
20966
20966
|
}
|
|
20967
20967
|
this.lazyrouter();
|
|
20968
|
-
var route = this._router.route(
|
|
20968
|
+
var route = this._router.route(path16);
|
|
20969
20969
|
route[method].apply(route, slice.call(arguments, 1));
|
|
20970
20970
|
return this;
|
|
20971
20971
|
};
|
|
20972
20972
|
});
|
|
20973
|
-
app.all = function all(
|
|
20973
|
+
app.all = function all(path16) {
|
|
20974
20974
|
this.lazyrouter();
|
|
20975
|
-
var route = this._router.route(
|
|
20975
|
+
var route = this._router.route(path16);
|
|
20976
20976
|
var args = slice.call(arguments, 1);
|
|
20977
20977
|
for (var i = 0; i < methods.length; i++) {
|
|
20978
20978
|
route[methods[i]].apply(route, args);
|
|
@@ -21022,7 +21022,7 @@ var require_application = __commonJS({
|
|
|
21022
21022
|
tryRender(view, renderOptions, done);
|
|
21023
21023
|
};
|
|
21024
21024
|
app.listen = function listen() {
|
|
21025
|
-
var server =
|
|
21025
|
+
var server = http3.createServer(this);
|
|
21026
21026
|
return server.listen.apply(server, arguments);
|
|
21027
21027
|
};
|
|
21028
21028
|
function logerror(err) {
|
|
@@ -21624,12 +21624,12 @@ var require_request = __commonJS({
|
|
|
21624
21624
|
var deprecate = require_depd()("express");
|
|
21625
21625
|
var isIP = require("net").isIP;
|
|
21626
21626
|
var typeis = require_type_is();
|
|
21627
|
-
var
|
|
21627
|
+
var http3 = require("http");
|
|
21628
21628
|
var fresh = require_fresh();
|
|
21629
21629
|
var parseRange = require_range_parser();
|
|
21630
21630
|
var parse = require_parseurl();
|
|
21631
21631
|
var proxyaddr = require_proxy_addr();
|
|
21632
|
-
var req = Object.create(
|
|
21632
|
+
var req = Object.create(http3.IncomingMessage.prototype);
|
|
21633
21633
|
module2.exports = req;
|
|
21634
21634
|
req.get = req.header = function header(name) {
|
|
21635
21635
|
if (!name) {
|
|
@@ -21731,7 +21731,7 @@ var require_request = __commonJS({
|
|
|
21731
21731
|
var subdomains2 = !isIP(hostname2) ? hostname2.split(".").reverse() : [hostname2];
|
|
21732
21732
|
return subdomains2.slice(offset);
|
|
21733
21733
|
});
|
|
21734
|
-
defineGetter(req, "path", function
|
|
21734
|
+
defineGetter(req, "path", function path16() {
|
|
21735
21735
|
return parse(this).pathname;
|
|
21736
21736
|
});
|
|
21737
21737
|
defineGetter(req, "hostname", function hostname2() {
|
|
@@ -22051,10 +22051,10 @@ var require_response = __commonJS({
|
|
|
22051
22051
|
var deprecate = require_depd()("express");
|
|
22052
22052
|
var encodeUrl = require_encodeurl();
|
|
22053
22053
|
var escapeHtml = require_escape_html();
|
|
22054
|
-
var
|
|
22054
|
+
var http3 = require("http");
|
|
22055
22055
|
var isAbsolute2 = require_utils2().isAbsolute;
|
|
22056
22056
|
var onFinished = require_on_finished();
|
|
22057
|
-
var
|
|
22057
|
+
var path16 = require("path");
|
|
22058
22058
|
var statuses = require_statuses();
|
|
22059
22059
|
var merge = require_utils_merge();
|
|
22060
22060
|
var sign = require_cookie_signature().sign;
|
|
@@ -22063,11 +22063,11 @@ var require_response = __commonJS({
|
|
|
22063
22063
|
var setCharset = require_utils2().setCharset;
|
|
22064
22064
|
var cookie = require_cookie();
|
|
22065
22065
|
var send = require_send();
|
|
22066
|
-
var extname3 =
|
|
22066
|
+
var extname3 = path16.extname;
|
|
22067
22067
|
var mime = send.mime;
|
|
22068
|
-
var resolve10 =
|
|
22068
|
+
var resolve10 = path16.resolve;
|
|
22069
22069
|
var vary = require_vary();
|
|
22070
|
-
var res = Object.create(
|
|
22070
|
+
var res = Object.create(http3.ServerResponse.prototype);
|
|
22071
22071
|
module2.exports = res;
|
|
22072
22072
|
var charsetRegExp = /;\s*charset\s*=/;
|
|
22073
22073
|
res.status = function status(code) {
|
|
@@ -22242,26 +22242,26 @@ var require_response = __commonJS({
|
|
|
22242
22242
|
this.type("txt");
|
|
22243
22243
|
return this.send(body);
|
|
22244
22244
|
};
|
|
22245
|
-
res.sendFile = function sendFile(
|
|
22245
|
+
res.sendFile = function sendFile(path17, options, callback) {
|
|
22246
22246
|
var done = callback;
|
|
22247
22247
|
var req = this.req;
|
|
22248
22248
|
var res2 = this;
|
|
22249
22249
|
var next = req.next;
|
|
22250
22250
|
var opts = options || {};
|
|
22251
|
-
if (!
|
|
22251
|
+
if (!path17) {
|
|
22252
22252
|
throw new TypeError("path argument is required to res.sendFile");
|
|
22253
22253
|
}
|
|
22254
|
-
if (typeof
|
|
22254
|
+
if (typeof path17 !== "string") {
|
|
22255
22255
|
throw new TypeError("path must be a string to res.sendFile");
|
|
22256
22256
|
}
|
|
22257
22257
|
if (typeof options === "function") {
|
|
22258
22258
|
done = options;
|
|
22259
22259
|
opts = {};
|
|
22260
22260
|
}
|
|
22261
|
-
if (!opts.root && !isAbsolute2(
|
|
22261
|
+
if (!opts.root && !isAbsolute2(path17)) {
|
|
22262
22262
|
throw new TypeError("path must be absolute or specify root to res.sendFile");
|
|
22263
22263
|
}
|
|
22264
|
-
var pathname = encodeURI(
|
|
22264
|
+
var pathname = encodeURI(path17);
|
|
22265
22265
|
var file = send(req, pathname, opts);
|
|
22266
22266
|
sendfile(res2, file, opts, function(err) {
|
|
22267
22267
|
if (done) return done(err);
|
|
@@ -22271,7 +22271,7 @@ var require_response = __commonJS({
|
|
|
22271
22271
|
}
|
|
22272
22272
|
});
|
|
22273
22273
|
};
|
|
22274
|
-
res.sendfile = function(
|
|
22274
|
+
res.sendfile = function(path17, options, callback) {
|
|
22275
22275
|
var done = callback;
|
|
22276
22276
|
var req = this.req;
|
|
22277
22277
|
var res2 = this;
|
|
@@ -22281,7 +22281,7 @@ var require_response = __commonJS({
|
|
|
22281
22281
|
done = options;
|
|
22282
22282
|
opts = {};
|
|
22283
22283
|
}
|
|
22284
|
-
var file = send(req,
|
|
22284
|
+
var file = send(req, path17, opts);
|
|
22285
22285
|
sendfile(res2, file, opts, function(err) {
|
|
22286
22286
|
if (done) return done(err);
|
|
22287
22287
|
if (err && err.code === "EISDIR") return next();
|
|
@@ -22294,7 +22294,7 @@ var require_response = __commonJS({
|
|
|
22294
22294
|
res.sendfile,
|
|
22295
22295
|
"res.sendfile: Use res.sendFile instead"
|
|
22296
22296
|
);
|
|
22297
|
-
res.download = function download(
|
|
22297
|
+
res.download = function download(path17, filename, options, callback) {
|
|
22298
22298
|
var done = callback;
|
|
22299
22299
|
var name = filename;
|
|
22300
22300
|
var opts = options || null;
|
|
@@ -22311,7 +22311,7 @@ var require_response = __commonJS({
|
|
|
22311
22311
|
opts = filename;
|
|
22312
22312
|
}
|
|
22313
22313
|
var headers = {
|
|
22314
|
-
"Content-Disposition": contentDisposition(name ||
|
|
22314
|
+
"Content-Disposition": contentDisposition(name || path17)
|
|
22315
22315
|
};
|
|
22316
22316
|
if (opts && opts.headers) {
|
|
22317
22317
|
var keys = Object.keys(opts.headers);
|
|
@@ -22324,7 +22324,7 @@ var require_response = __commonJS({
|
|
|
22324
22324
|
}
|
|
22325
22325
|
opts = Object.create(opts);
|
|
22326
22326
|
opts.headers = headers;
|
|
22327
|
-
var fullPath = !opts.root ? resolve10(
|
|
22327
|
+
var fullPath = !opts.root ? resolve10(path17) : path17;
|
|
22328
22328
|
return this.sendFile(fullPath, opts, done);
|
|
22329
22329
|
};
|
|
22330
22330
|
res.contentType = res.type = function contentType(type) {
|
|
@@ -22625,11 +22625,11 @@ var require_serve_static = __commonJS({
|
|
|
22625
22625
|
}
|
|
22626
22626
|
var forwardError = !fallthrough;
|
|
22627
22627
|
var originalUrl = parseUrl.original(req);
|
|
22628
|
-
var
|
|
22629
|
-
if (
|
|
22630
|
-
|
|
22628
|
+
var path16 = parseUrl(req).pathname;
|
|
22629
|
+
if (path16 === "/" && originalUrl.pathname.substr(-1) !== "/") {
|
|
22630
|
+
path16 = "";
|
|
22631
22631
|
}
|
|
22632
|
-
var stream = send(req,
|
|
22632
|
+
var stream = send(req, path16, opts);
|
|
22633
22633
|
stream.on("directory", onDirectory);
|
|
22634
22634
|
if (setHeaders) {
|
|
22635
22635
|
stream.on("headers", setHeaders);
|
|
@@ -22697,7 +22697,7 @@ var require_express = __commonJS({
|
|
|
22697
22697
|
var mixin = require_merge_descriptors();
|
|
22698
22698
|
var proto = require_application();
|
|
22699
22699
|
var Route = require_route();
|
|
22700
|
-
var
|
|
22700
|
+
var Router8 = require_router();
|
|
22701
22701
|
var req = require_request();
|
|
22702
22702
|
var res = require_response();
|
|
22703
22703
|
exports2 = module2.exports = createApplication;
|
|
@@ -22720,7 +22720,7 @@ var require_express = __commonJS({
|
|
|
22720
22720
|
exports2.request = req;
|
|
22721
22721
|
exports2.response = res;
|
|
22722
22722
|
exports2.Route = Route;
|
|
22723
|
-
exports2.Router =
|
|
22723
|
+
exports2.Router = Router8;
|
|
22724
22724
|
exports2.json = bodyParser.json;
|
|
22725
22725
|
exports2.query = require_query();
|
|
22726
22726
|
exports2.raw = bodyParser.raw;
|
|
@@ -22791,6 +22791,7 @@ __export(main_exports, {
|
|
|
22791
22791
|
shouldSkipStartupRequirementsCheck: () => shouldSkipStartupRequirementsCheck
|
|
22792
22792
|
});
|
|
22793
22793
|
module.exports = __toCommonJS(main_exports);
|
|
22794
|
+
var http2 = __toESM(require("http"), 1);
|
|
22794
22795
|
var nodePath = __toESM(require("path"), 1);
|
|
22795
22796
|
|
|
22796
22797
|
// ../../packages/core/src/logger.ts
|
|
@@ -23149,6 +23150,13 @@ function persistNodeStartupTransport(storagePath, transport) {
|
|
|
23149
23150
|
transport
|
|
23150
23151
|
});
|
|
23151
23152
|
}
|
|
23153
|
+
function persistNodeStartupJoin(storagePath, join13) {
|
|
23154
|
+
const startup = resolveNodeStartupMetadata(storagePath);
|
|
23155
|
+
persistNodeStartupMetadata(storagePath, {
|
|
23156
|
+
...startup,
|
|
23157
|
+
join: join13
|
|
23158
|
+
});
|
|
23159
|
+
}
|
|
23152
23160
|
function resolvePersistedDevTunnelId(storagePath, kind) {
|
|
23153
23161
|
return readNodeMetadata(storagePath).devTunnelIds?.[kind]?.trim() || void 0;
|
|
23154
23162
|
}
|
|
@@ -24013,19 +24021,19 @@ async function fetchWithTimeout(url, init, timeoutMs = DEFAULT_NODE_REQUEST_TIME
|
|
|
24013
24021
|
cleanup();
|
|
24014
24022
|
}
|
|
24015
24023
|
}
|
|
24016
|
-
async function fetchNodeWithFallback(node,
|
|
24024
|
+
async function fetchNodeWithFallback(node, path16, init, timeoutMs = DEFAULT_NODE_REQUEST_TIMEOUT_MS, trace) {
|
|
24017
24025
|
let lastError;
|
|
24018
24026
|
const endpoints = getNodeRequestEndpoints(node);
|
|
24019
24027
|
for (const [index, endpoint] of endpoints.entries()) {
|
|
24020
24028
|
const attempt = index + 1;
|
|
24021
|
-
trace?.onAttempt?.({ attempt, endpoint, path:
|
|
24029
|
+
trace?.onAttempt?.({ attempt, endpoint, path: path16, timeoutMs, totalEndpoints: endpoints.length });
|
|
24022
24030
|
try {
|
|
24023
|
-
const response = await fetchWithTimeout(`${endpoint}${
|
|
24024
|
-
trace?.onResponse?.({ attempt, endpoint, path:
|
|
24031
|
+
const response = await fetchWithTimeout(`${endpoint}${path16}`, init, timeoutMs);
|
|
24032
|
+
trace?.onResponse?.({ attempt, endpoint, path: path16, response, timeoutMs, totalEndpoints: endpoints.length });
|
|
24025
24033
|
return { endpoint, response };
|
|
24026
24034
|
} catch (error) {
|
|
24027
24035
|
lastError = error;
|
|
24028
|
-
trace?.onError?.({ attempt, endpoint, error, path:
|
|
24036
|
+
trace?.onError?.({ attempt, endpoint, error, path: path16, timeoutMs, totalEndpoints: endpoints.length });
|
|
24029
24037
|
}
|
|
24030
24038
|
}
|
|
24031
24039
|
throw lastError instanceof Error ? lastError : new Error("No reachable node endpoint");
|
|
@@ -25817,9 +25825,9 @@ var DataRouter = class {
|
|
|
25817
25825
|
/**
|
|
25818
25826
|
* Returns true if the request should be proxied to the leader.
|
|
25819
25827
|
*/
|
|
25820
|
-
shouldProxy(method,
|
|
25828
|
+
shouldProxy(method, path16) {
|
|
25821
25829
|
if (this.election.isLeader()) return false;
|
|
25822
|
-
if (this.isExcludedPath(
|
|
25830
|
+
if (this.isExcludedPath(path16)) return false;
|
|
25823
25831
|
if (method.toUpperCase() === "GET") return false;
|
|
25824
25832
|
return WRITE_METHODS.has(method.toUpperCase());
|
|
25825
25833
|
}
|
|
@@ -25920,8 +25928,8 @@ var DataRouter = class {
|
|
|
25920
25928
|
};
|
|
25921
25929
|
}
|
|
25922
25930
|
// ── Helpers ───────────────────────────────────────────────────────────
|
|
25923
|
-
isExcludedPath(
|
|
25924
|
-
return EXCLUDED_PATH_PREFIXES.some((prefix) =>
|
|
25931
|
+
isExcludedPath(path16) {
|
|
25932
|
+
return EXCLUDED_PATH_PREFIXES.some((prefix) => path16.startsWith(prefix)) || EXCLUDED_PATH_SUFFIXES.some((suffix) => path16.endsWith(suffix));
|
|
25925
25933
|
}
|
|
25926
25934
|
};
|
|
25927
25935
|
|
|
@@ -26935,22 +26943,34 @@ ${joinErrors.map((e) => ` - ${e}`).join("\n")}`
|
|
|
26935
26943
|
async joinCluster(seedUrl) {
|
|
26936
26944
|
const log = this.logger.child("node/join-cluster");
|
|
26937
26945
|
const tasks = this.taskEngine.listTasks().tasks;
|
|
26946
|
+
const self = this.nodeRegistry.getSelf();
|
|
26938
26947
|
const joinBody = {
|
|
26939
|
-
id:
|
|
26940
|
-
endpoint:
|
|
26941
|
-
name:
|
|
26948
|
+
id: self.id,
|
|
26949
|
+
endpoint: self.endpoint,
|
|
26950
|
+
name: self.name,
|
|
26942
26951
|
capabilities: [],
|
|
26952
|
+
transportType: self.transportType,
|
|
26953
|
+
workDir: self.workDir,
|
|
26954
|
+
workDirFolders: listWorkDirFolders(this.getWorkDir()),
|
|
26943
26955
|
tasks
|
|
26944
26956
|
};
|
|
26945
|
-
if (
|
|
26946
|
-
joinBody.devtunnelEndpoint =
|
|
26957
|
+
if (self.devtunnelEndpoint) {
|
|
26958
|
+
joinBody.devtunnelEndpoint = self.devtunnelEndpoint;
|
|
26959
|
+
}
|
|
26960
|
+
if (self.dashboardOrigin) {
|
|
26961
|
+
joinBody.dashboardOrigin = self.dashboardOrigin;
|
|
26962
|
+
}
|
|
26963
|
+
if (self.previewOrigin) {
|
|
26964
|
+
joinBody.previewOrigin = self.previewOrigin;
|
|
26947
26965
|
}
|
|
26948
26966
|
log.info("sending cluster join request", {
|
|
26949
26967
|
seedUrl,
|
|
26950
|
-
nodeId:
|
|
26951
|
-
endpoint:
|
|
26968
|
+
nodeId: self.id,
|
|
26969
|
+
endpoint: self.endpoint,
|
|
26952
26970
|
taskCount: tasks.length,
|
|
26953
|
-
hasDevTunnel: !!
|
|
26971
|
+
hasDevTunnel: !!self.devtunnelEndpoint,
|
|
26972
|
+
hasDashboardOrigin: !!self.dashboardOrigin,
|
|
26973
|
+
hasPreviewOrigin: !!self.previewOrigin
|
|
26954
26974
|
});
|
|
26955
26975
|
let response;
|
|
26956
26976
|
try {
|
|
@@ -26996,6 +27016,7 @@ ${joinErrors.map((e) => ` - ${e}`).join("\n")}`
|
|
|
26996
27016
|
nodeCount: data.nodes.length
|
|
26997
27017
|
});
|
|
26998
27018
|
this.applyClusterState(data.nodes, data.leaderId, data.term);
|
|
27019
|
+
persistNodeStartupJoin(this.config.storage.path, seedUrl);
|
|
26999
27020
|
}
|
|
27000
27021
|
async leaveCluster() {
|
|
27001
27022
|
const log = this.logger.child("node/leave-cluster");
|
|
@@ -27048,6 +27069,7 @@ ${joinErrors.map((e) => ` - ${e}`).join("\n")}`
|
|
|
27048
27069
|
this.nodeRegistry.clearLeader();
|
|
27049
27070
|
this.election.assumeLeadership();
|
|
27050
27071
|
this.syncSelfInfoFromRegistry();
|
|
27072
|
+
persistNodeStartupJoin(this.config.storage.path, void 0);
|
|
27051
27073
|
log.info("detached from leader and assumed solo leadership", {
|
|
27052
27074
|
previousLeaderId: leader.id,
|
|
27053
27075
|
nodeId: refreshedSelf.id,
|
|
@@ -27229,15 +27251,17 @@ ${joinErrors.map((e) => ` - ${e}`).join("\n")}`
|
|
|
27229
27251
|
this.selfInfo.status = current.status;
|
|
27230
27252
|
}
|
|
27231
27253
|
applyClusterState(nodes, leaderId, term) {
|
|
27232
|
-
const
|
|
27254
|
+
const currentSelf = this.nodeRegistry.getSelf();
|
|
27255
|
+
const remoteSelf = nodes.find((node) => node.id === currentSelf.id);
|
|
27233
27256
|
const nextSelf = {
|
|
27234
|
-
...
|
|
27257
|
+
...currentSelf,
|
|
27235
27258
|
...remoteSelf ?? {},
|
|
27236
27259
|
transportType: this.config.transport.type,
|
|
27237
|
-
workDir:
|
|
27260
|
+
workDir: currentSelf.workDir,
|
|
27238
27261
|
workDirFolders: listWorkDirFolders(this.getWorkDir()),
|
|
27239
|
-
...
|
|
27240
|
-
...
|
|
27262
|
+
...currentSelf.devtunnelEndpoint ? { devtunnelEndpoint: currentSelf.devtunnelEndpoint } : {},
|
|
27263
|
+
...currentSelf.dashboardOrigin ? { dashboardOrigin: currentSelf.dashboardOrigin } : {},
|
|
27264
|
+
...currentSelf.previewOrigin ? { previewOrigin: currentSelf.previewOrigin } : {}
|
|
27241
27265
|
};
|
|
27242
27266
|
this.selfInfo = nextSelf;
|
|
27243
27267
|
this.nodeRegistry.setSelf(nextSelf);
|
|
@@ -27881,8 +27905,8 @@ function getErrorMap() {
|
|
|
27881
27905
|
|
|
27882
27906
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
|
|
27883
27907
|
var makeIssue = (params) => {
|
|
27884
|
-
const { data, path:
|
|
27885
|
-
const fullPath = [...
|
|
27908
|
+
const { data, path: path16, errorMaps, issueData } = params;
|
|
27909
|
+
const fullPath = [...path16, ...issueData.path || []];
|
|
27886
27910
|
const fullIssue = {
|
|
27887
27911
|
...issueData,
|
|
27888
27912
|
path: fullPath
|
|
@@ -27998,11 +28022,11 @@ var errorUtil;
|
|
|
27998
28022
|
|
|
27999
28023
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
|
|
28000
28024
|
var ParseInputLazyPath = class {
|
|
28001
|
-
constructor(parent, value,
|
|
28025
|
+
constructor(parent, value, path16, key) {
|
|
28002
28026
|
this._cachedPath = [];
|
|
28003
28027
|
this.parent = parent;
|
|
28004
28028
|
this.data = value;
|
|
28005
|
-
this._path =
|
|
28029
|
+
this._path = path16;
|
|
28006
28030
|
this._key = key;
|
|
28007
28031
|
}
|
|
28008
28032
|
get path() {
|
|
@@ -31500,7 +31524,12 @@ var JoinClusterBody = external_exports.object({
|
|
|
31500
31524
|
endpoint: external_exports.string().url(),
|
|
31501
31525
|
name: external_exports.string().min(1),
|
|
31502
31526
|
capabilities: external_exports.array(external_exports.string()).default([]),
|
|
31527
|
+
transportType: external_exports.string().optional(),
|
|
31528
|
+
workDir: external_exports.string().optional(),
|
|
31529
|
+
workDirFolders: external_exports.array(external_exports.string()).optional(),
|
|
31503
31530
|
devtunnelEndpoint: external_exports.string().url().optional(),
|
|
31531
|
+
dashboardOrigin: external_exports.string().url().optional(),
|
|
31532
|
+
previewOrigin: external_exports.string().url().optional(),
|
|
31504
31533
|
tasks: external_exports.array(JoinTaskSchema).default([])
|
|
31505
31534
|
});
|
|
31506
31535
|
var JoinClusterResponse = external_exports.object({
|
|
@@ -31663,9 +31692,9 @@ var BatchTaskIdsBody = external_exports.object({
|
|
|
31663
31692
|
});
|
|
31664
31693
|
|
|
31665
31694
|
// ../../packages/api/src/server.ts
|
|
31666
|
-
var
|
|
31667
|
-
var
|
|
31668
|
-
var
|
|
31695
|
+
var path14 = __toESM(require("path"), 1);
|
|
31696
|
+
var fs14 = __toESM(require("fs"), 1);
|
|
31697
|
+
var import_express8 = __toESM(require_express2(), 1);
|
|
31669
31698
|
|
|
31670
31699
|
// ../../packages/api/src/middleware/auth.ts
|
|
31671
31700
|
var SKIP_AUTH_PATHS = ["/api/system/health"];
|
|
@@ -31745,7 +31774,7 @@ function createAuthMiddleware(config) {
|
|
|
31745
31774
|
return;
|
|
31746
31775
|
}
|
|
31747
31776
|
if (config.validateBearerToken) {
|
|
31748
|
-
if (isTrustedDashboardRequest(req, config)) {
|
|
31777
|
+
if (config.allowTrustedHostBypass !== false && isTrustedDashboardRequest(req, config)) {
|
|
31749
31778
|
log.debug("skipping bearer auth for trusted dashboard request", {
|
|
31750
31779
|
path: req.path,
|
|
31751
31780
|
method: req.method,
|
|
@@ -31933,7 +31962,9 @@ function createClusterRoutes() {
|
|
|
31933
31962
|
name: body.name,
|
|
31934
31963
|
endpoint: body.endpoint,
|
|
31935
31964
|
taskCount: body.tasks?.length ?? 0,
|
|
31936
|
-
hasDevTunnel: !!body.devtunnelEndpoint
|
|
31965
|
+
hasDevTunnel: !!body.devtunnelEndpoint,
|
|
31966
|
+
hasDashboardOrigin: !!body.dashboardOrigin,
|
|
31967
|
+
hasPreviewOrigin: !!body.previewOrigin
|
|
31937
31968
|
});
|
|
31938
31969
|
const existingNodes = nodeRegistry.getAllNodes();
|
|
31939
31970
|
let removedCount = 0;
|
|
@@ -31952,7 +31983,12 @@ function createClusterRoutes() {
|
|
|
31952
31983
|
capabilities: body.capabilities ?? [],
|
|
31953
31984
|
joinedAt: Date.now(),
|
|
31954
31985
|
lastHeartbeat: Date.now(),
|
|
31955
|
-
...body.
|
|
31986
|
+
...body.transportType && { transportType: body.transportType },
|
|
31987
|
+
...body.workDir && { workDir: body.workDir },
|
|
31988
|
+
...body.workDirFolders && { workDirFolders: body.workDirFolders },
|
|
31989
|
+
...body.devtunnelEndpoint && { devtunnelEndpoint: body.devtunnelEndpoint },
|
|
31990
|
+
...body.dashboardOrigin && { dashboardOrigin: body.dashboardOrigin },
|
|
31991
|
+
...body.previewOrigin && { previewOrigin: body.previewOrigin }
|
|
31956
31992
|
};
|
|
31957
31993
|
nodeRegistry.addNode(node);
|
|
31958
31994
|
taskEngine.importTasks(body.tasks ?? []);
|
|
@@ -32080,174 +32116,72 @@ function assertCanChangeNodeDevTunnel(taskEngine, nodeId) {
|
|
|
32080
32116
|
);
|
|
32081
32117
|
}
|
|
32082
32118
|
|
|
32083
|
-
// ../../packages/api/src/
|
|
32084
|
-
var
|
|
32085
|
-
|
|
32086
|
-
|
|
32087
|
-
|
|
32088
|
-
|
|
32089
|
-
|
|
32090
|
-
|
|
32091
|
-
|
|
32092
|
-
|
|
32093
|
-
|
|
32094
|
-
|
|
32095
|
-
|
|
32096
|
-
if (!resolvedPath.startsWith(normalizedRoot + path11.sep) && resolvedPath !== normalizedRoot) {
|
|
32097
|
-
throw new Error("Invalid preview path");
|
|
32098
|
-
}
|
|
32099
|
-
return {
|
|
32100
|
-
absolutePath: resolvedPath,
|
|
32101
|
-
normalizedPath: path11.relative(normalizedRoot, resolvedPath).split(path11.sep).join("/")
|
|
32102
|
-
};
|
|
32103
|
-
}
|
|
32104
|
-
function resolvePreviewEntryPath(rootPath, entryPath) {
|
|
32105
|
-
const { absolutePath, normalizedPath } = resolvePreviewPath(rootPath, entryPath ?? "index.html");
|
|
32106
|
-
if (!fs10.existsSync(absolutePath) || !fs10.statSync(absolutePath).isFile()) {
|
|
32107
|
-
throw new Error("Preview entry not found");
|
|
32108
|
-
}
|
|
32109
|
-
return normalizedPath;
|
|
32110
|
-
}
|
|
32111
|
-
function buildPreviewUrl(origin, session) {
|
|
32112
|
-
const encodedEntryPath = session.entryPath.split("/").filter(Boolean).map((segment) => encodeURIComponent(segment)).join("/");
|
|
32113
|
-
return `${origin.replace(/\/+$/, "")}/preview/${session.token}/${encodedEntryPath}`;
|
|
32114
|
-
}
|
|
32115
|
-
var DEFAULT_TTL_MS = 15 * 60 * 1e3;
|
|
32116
|
-
var PreviewSessionManager = class {
|
|
32117
|
-
sessions = /* @__PURE__ */ new Map();
|
|
32118
|
-
create(options) {
|
|
32119
|
-
const token = crypto2.randomBytes(32).toString("hex");
|
|
32120
|
-
const entryPath = resolvePreviewEntryPath(options.rootPath, options.entryPath);
|
|
32121
|
-
const session = {
|
|
32122
|
-
token,
|
|
32123
|
-
taskId: options.taskId,
|
|
32124
|
-
rootPath: options.rootPath,
|
|
32125
|
-
entryPath,
|
|
32126
|
-
expiresAt: Date.now() + (options.ttlMs ?? DEFAULT_TTL_MS)
|
|
32127
|
-
};
|
|
32128
|
-
this.sessions.set(token, session);
|
|
32129
|
-
return session;
|
|
32130
|
-
}
|
|
32131
|
-
get(token) {
|
|
32132
|
-
const session = this.sessions.get(token);
|
|
32133
|
-
if (!session) return null;
|
|
32134
|
-
if (Date.now() > session.expiresAt) {
|
|
32135
|
-
this.sessions.delete(token);
|
|
32136
|
-
return null;
|
|
32119
|
+
// ../../packages/api/src/task-cancellation.ts
|
|
32120
|
+
var TERMINAL_STATUSES2 = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "archived"]);
|
|
32121
|
+
function cancelTaskOnCurrentNode(deps, taskId, options = {}) {
|
|
32122
|
+
const task = deps.taskEngine.getTask(taskId);
|
|
32123
|
+
if (!task) {
|
|
32124
|
+
if (options.missingOk) {
|
|
32125
|
+
return {
|
|
32126
|
+
task: null,
|
|
32127
|
+
cancelled: false,
|
|
32128
|
+
engineCancelRequested: false,
|
|
32129
|
+
missing: true,
|
|
32130
|
+
terminal: false
|
|
32131
|
+
};
|
|
32137
32132
|
}
|
|
32138
|
-
|
|
32133
|
+
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
32139
32134
|
}
|
|
32140
|
-
|
|
32141
|
-
|
|
32142
|
-
|
|
32143
|
-
|
|
32144
|
-
|
|
32145
|
-
|
|
32135
|
+
if (TERMINAL_STATUSES2.has(task.status)) {
|
|
32136
|
+
if (options.terminalOk) {
|
|
32137
|
+
return {
|
|
32138
|
+
task,
|
|
32139
|
+
cancelled: false,
|
|
32140
|
+
engineCancelRequested: false,
|
|
32141
|
+
missing: false,
|
|
32142
|
+
terminal: true
|
|
32143
|
+
};
|
|
32146
32144
|
}
|
|
32145
|
+
throw new MeshyError("VALIDATION_ERROR", `Task ${taskId} cannot be cancelled (status: ${task.status})`, 400);
|
|
32147
32146
|
}
|
|
32148
|
-
|
|
32149
|
-
|
|
32150
|
-
|
|
32151
|
-
|
|
32152
|
-
|
|
32153
|
-
|
|
32154
|
-
|
|
32155
|
-
".json": "application/json",
|
|
32156
|
-
".png": "image/png",
|
|
32157
|
-
".jpg": "image/jpeg",
|
|
32158
|
-
".jpeg": "image/jpeg",
|
|
32159
|
-
".gif": "image/gif",
|
|
32160
|
-
".svg": "image/svg+xml",
|
|
32161
|
-
".webp": "image/webp",
|
|
32162
|
-
".ico": "image/x-icon",
|
|
32163
|
-
".woff": "font/woff",
|
|
32164
|
-
".woff2": "font/woff2",
|
|
32165
|
-
".ttf": "font/ttf",
|
|
32166
|
-
".eot": "application/vnd.ms-fontobject",
|
|
32167
|
-
".pdf": "application/pdf"
|
|
32168
|
-
};
|
|
32169
|
-
function getMime(filePath) {
|
|
32170
|
-
return MIME_MAP[path11.extname(filePath).toLowerCase()] ?? "application/octet-stream";
|
|
32171
|
-
}
|
|
32172
|
-
var PreviewServer = class {
|
|
32173
|
-
server = null;
|
|
32174
|
-
sessionManager;
|
|
32175
|
-
constructor(sessionManager) {
|
|
32176
|
-
this.sessionManager = sessionManager;
|
|
32177
|
-
}
|
|
32178
|
-
async start(port) {
|
|
32179
|
-
return new Promise((resolve10, reject) => {
|
|
32180
|
-
this.server = http.createServer((req, res) => this.handleRequest(req, res));
|
|
32181
|
-
this.server.listen(port, () => {
|
|
32182
|
-
const addr = this.server.address();
|
|
32183
|
-
const actualPort = typeof addr === "object" && addr ? addr.port : port;
|
|
32184
|
-
resolve10(actualPort);
|
|
32147
|
+
let engineCancelRequested = false;
|
|
32148
|
+
if (task.status === "running") {
|
|
32149
|
+
const engine = deps.engineRegistry.get(task.agent);
|
|
32150
|
+
if (!engine || typeof engine.cancelTask !== "function") {
|
|
32151
|
+
deps.logger.warn("engine not registered while cancelling running task", {
|
|
32152
|
+
taskId,
|
|
32153
|
+
agent: task.agent
|
|
32185
32154
|
});
|
|
32186
|
-
|
|
32187
|
-
|
|
32188
|
-
|
|
32189
|
-
|
|
32190
|
-
|
|
32191
|
-
|
|
32192
|
-
|
|
32193
|
-
return;
|
|
32155
|
+
} else {
|
|
32156
|
+
engineCancelRequested = engine.cancelTask(taskId);
|
|
32157
|
+
if (!engineCancelRequested) {
|
|
32158
|
+
deps.logger.warn("running task had no active engine process to cancel", {
|
|
32159
|
+
taskId,
|
|
32160
|
+
agent: task.agent
|
|
32161
|
+
});
|
|
32194
32162
|
}
|
|
32195
|
-
this.server.close(() => resolve10());
|
|
32196
|
-
});
|
|
32197
|
-
}
|
|
32198
|
-
getPort() {
|
|
32199
|
-
if (!this.server) return null;
|
|
32200
|
-
const addr = this.server.address();
|
|
32201
|
-
return typeof addr === "object" && addr ? addr.port : null;
|
|
32202
|
-
}
|
|
32203
|
-
handleRequest(req, res) {
|
|
32204
|
-
if (req.method !== "GET") {
|
|
32205
|
-
res.writeHead(405, { "Content-Type": "text/plain" });
|
|
32206
|
-
res.end("Method not allowed");
|
|
32207
|
-
return;
|
|
32208
32163
|
}
|
|
32209
|
-
const url = new URL(req.url ?? "/", `http://localhost`);
|
|
32210
|
-
const match = url.pathname.match(/^\/preview\/([a-f0-9]+)(?:\/(.*))?$/i);
|
|
32211
|
-
const token = match?.[1];
|
|
32212
|
-
if (!token) {
|
|
32213
|
-
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
32214
|
-
res.end("Preview not found");
|
|
32215
|
-
return;
|
|
32216
|
-
}
|
|
32217
|
-
const session = this.sessionManager.get(token);
|
|
32218
|
-
if (!session) {
|
|
32219
|
-
res.writeHead(403, { "Content-Type": "text/plain" });
|
|
32220
|
-
res.end("Invalid or expired preview token");
|
|
32221
|
-
return;
|
|
32222
|
-
}
|
|
32223
|
-
const requestedPath = decodeURIComponent(match?.[2] ?? session.entryPath);
|
|
32224
|
-
let resolved;
|
|
32225
|
-
try {
|
|
32226
|
-
resolved = resolvePreviewPath(session.rootPath, requestedPath).absolutePath;
|
|
32227
|
-
} catch {
|
|
32228
|
-
res.writeHead(400, { "Content-Type": "text/plain" });
|
|
32229
|
-
res.end("Invalid path");
|
|
32230
|
-
return;
|
|
32231
|
-
}
|
|
32232
|
-
if (!fs10.existsSync(resolved) || !fs10.statSync(resolved).isFile()) {
|
|
32233
|
-
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
32234
|
-
res.end("File not found");
|
|
32235
|
-
return;
|
|
32236
|
-
}
|
|
32237
|
-
const mime = getMime(resolved);
|
|
32238
|
-
const content = fs10.readFileSync(resolved);
|
|
32239
|
-
res.writeHead(200, {
|
|
32240
|
-
"Content-Type": mime,
|
|
32241
|
-
"Content-Length": content.length,
|
|
32242
|
-
"Cache-Control": "no-cache"
|
|
32243
|
-
});
|
|
32244
|
-
res.end(content);
|
|
32245
32164
|
}
|
|
32246
|
-
|
|
32165
|
+
const cancelled = deps.taskEngine.cancelTask(taskId);
|
|
32166
|
+
if (!cancelled) {
|
|
32167
|
+
throw new MeshyError("VALIDATION_ERROR", `Task ${taskId} cannot be cancelled`, 400);
|
|
32168
|
+
}
|
|
32169
|
+
return {
|
|
32170
|
+
task,
|
|
32171
|
+
cancelled: true,
|
|
32172
|
+
engineCancelRequested,
|
|
32173
|
+
missing: false,
|
|
32174
|
+
terminal: false
|
|
32175
|
+
};
|
|
32176
|
+
}
|
|
32177
|
+
|
|
32178
|
+
// ../../packages/api/src/task-output-service.ts
|
|
32179
|
+
var fs12 = __toESM(require("fs"), 1);
|
|
32180
|
+
var path13 = __toESM(require("path"), 1);
|
|
32247
32181
|
|
|
32248
32182
|
// ../../packages/api/src/output/helpers.ts
|
|
32249
|
-
var
|
|
32250
|
-
var
|
|
32183
|
+
var fs10 = __toESM(require("fs"), 1);
|
|
32184
|
+
var path11 = __toESM(require("path"), 1);
|
|
32251
32185
|
var MAX_INLINE_SIZE = 512 * 1024;
|
|
32252
32186
|
var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
32253
32187
|
".txt",
|
|
@@ -32324,7 +32258,7 @@ var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
32324
32258
|
".ico",
|
|
32325
32259
|
".avif"
|
|
32326
32260
|
]);
|
|
32327
|
-
var
|
|
32261
|
+
var MIME_MAP = {
|
|
32328
32262
|
".png": "image/png",
|
|
32329
32263
|
".jpg": "image/jpeg",
|
|
32330
32264
|
".jpeg": "image/jpeg",
|
|
@@ -32357,18 +32291,18 @@ var MIME_MAP2 = {
|
|
|
32357
32291
|
".sh": "text/x-shellscript"
|
|
32358
32292
|
};
|
|
32359
32293
|
function mimeForExt(ext) {
|
|
32360
|
-
return
|
|
32294
|
+
return MIME_MAP[ext] ?? "application/octet-stream";
|
|
32361
32295
|
}
|
|
32362
32296
|
function resolveOutputPath(root, relativePath) {
|
|
32363
|
-
const resolved =
|
|
32364
|
-
const normalizedRoot =
|
|
32365
|
-
if (!resolved.startsWith(normalizedRoot +
|
|
32297
|
+
const resolved = path11.resolve(root, relativePath);
|
|
32298
|
+
const normalizedRoot = path11.resolve(root);
|
|
32299
|
+
if (!resolved.startsWith(normalizedRoot + path11.sep) && resolved !== normalizedRoot) {
|
|
32366
32300
|
throw new Error("Path traversal detected");
|
|
32367
32301
|
}
|
|
32368
32302
|
return resolved;
|
|
32369
32303
|
}
|
|
32370
32304
|
function classifyFile(filePath) {
|
|
32371
|
-
const ext =
|
|
32305
|
+
const ext = path11.extname(filePath).toLowerCase();
|
|
32372
32306
|
if (ext === ".json" || ext === ".jsonl" || ext === ".ndjson") {
|
|
32373
32307
|
return { kind: "json", mimeType: "application/json" };
|
|
32374
32308
|
}
|
|
@@ -32395,14 +32329,14 @@ function classifyFile(filePath) {
|
|
|
32395
32329
|
}
|
|
32396
32330
|
function listDirectory(root, relativePath) {
|
|
32397
32331
|
const absPath = resolveOutputPath(root, relativePath);
|
|
32398
|
-
if (!
|
|
32332
|
+
if (!fs10.existsSync(absPath) || !fs10.statSync(absPath).isDirectory()) {
|
|
32399
32333
|
return [];
|
|
32400
32334
|
}
|
|
32401
|
-
const entries =
|
|
32335
|
+
const entries = fs10.readdirSync(absPath, { withFileTypes: true });
|
|
32402
32336
|
const result = [];
|
|
32403
32337
|
for (const entry of entries) {
|
|
32404
32338
|
if (entry.name.startsWith(".")) continue;
|
|
32405
|
-
const entryRelPath =
|
|
32339
|
+
const entryRelPath = path11.join(relativePath || ".", entry.name).split(path11.sep).join("/");
|
|
32406
32340
|
if (entry.isDirectory()) {
|
|
32407
32341
|
result.push({
|
|
32408
32342
|
path: entryRelPath,
|
|
@@ -32410,8 +32344,8 @@ function listDirectory(root, relativePath) {
|
|
|
32410
32344
|
type: "directory"
|
|
32411
32345
|
});
|
|
32412
32346
|
} else if (entry.isFile()) {
|
|
32413
|
-
const fullPath =
|
|
32414
|
-
const stat =
|
|
32347
|
+
const fullPath = path11.join(absPath, entry.name);
|
|
32348
|
+
const stat = fs10.statSync(fullPath);
|
|
32415
32349
|
const { kind, mimeType } = classifyFile(entry.name);
|
|
32416
32350
|
result.push({
|
|
32417
32351
|
path: entryRelPath,
|
|
@@ -32431,11 +32365,11 @@ function listDirectory(root, relativePath) {
|
|
|
32431
32365
|
}
|
|
32432
32366
|
function detectHtmlEntries(root) {
|
|
32433
32367
|
const entries = [];
|
|
32434
|
-
if (
|
|
32368
|
+
if (fs10.existsSync(path11.join(root, "index.html"))) {
|
|
32435
32369
|
entries.push({ path: "index.html", label: "index.html" });
|
|
32436
32370
|
}
|
|
32437
32371
|
try {
|
|
32438
|
-
const topLevel =
|
|
32372
|
+
const topLevel = fs10.readdirSync(root, { withFileTypes: true });
|
|
32439
32373
|
const htmlFiles = topLevel.filter(
|
|
32440
32374
|
(e) => e.isFile() && e.name.endsWith(".html") && !e.name.startsWith(".")
|
|
32441
32375
|
);
|
|
@@ -32446,8 +32380,8 @@ function detectHtmlEntries(root) {
|
|
|
32446
32380
|
}
|
|
32447
32381
|
const subdirs = topLevel.filter((e) => e.isDirectory() && !e.name.startsWith("."));
|
|
32448
32382
|
for (const dir of subdirs) {
|
|
32449
|
-
const subIndex =
|
|
32450
|
-
if (
|
|
32383
|
+
const subIndex = path11.join(root, dir.name, "index.html");
|
|
32384
|
+
if (fs10.existsSync(subIndex)) {
|
|
32451
32385
|
entries.push({
|
|
32452
32386
|
path: `${dir.name}/index.html`,
|
|
32453
32387
|
label: `${dir.name}/index.html`
|
|
@@ -32459,11 +32393,11 @@ function detectHtmlEntries(root) {
|
|
|
32459
32393
|
return entries;
|
|
32460
32394
|
}
|
|
32461
32395
|
function getOutputSummary(root) {
|
|
32462
|
-
const rootName =
|
|
32396
|
+
const rootName = path11.basename(root);
|
|
32463
32397
|
const htmlEntries = detectHtmlEntries(root);
|
|
32464
32398
|
let fileCount;
|
|
32465
32399
|
try {
|
|
32466
|
-
const entries =
|
|
32400
|
+
const entries = fs10.readdirSync(root, { withFileTypes: true });
|
|
32467
32401
|
fileCount = entries.filter((e) => !e.name.startsWith(".")).length;
|
|
32468
32402
|
} catch {
|
|
32469
32403
|
fileCount = void 0;
|
|
@@ -32479,14 +32413,14 @@ function getOutputSummary(root) {
|
|
|
32479
32413
|
}
|
|
32480
32414
|
function readFileContent(root, relativePath) {
|
|
32481
32415
|
const absPath = resolveOutputPath(root, relativePath);
|
|
32482
|
-
if (!
|
|
32416
|
+
if (!fs10.existsSync(absPath) || !fs10.statSync(absPath).isFile()) {
|
|
32483
32417
|
throw new Error("File not found");
|
|
32484
32418
|
}
|
|
32485
|
-
const stat =
|
|
32419
|
+
const stat = fs10.statSync(absPath);
|
|
32486
32420
|
const { kind, mimeType } = classifyFile(absPath);
|
|
32487
32421
|
if (kind === "image" || kind === "pdf" || kind === "binary") {
|
|
32488
32422
|
const truncated2 = stat.size > MAX_INLINE_SIZE;
|
|
32489
|
-
const buffer = truncated2 ? Buffer.alloc(0) :
|
|
32423
|
+
const buffer = truncated2 ? Buffer.alloc(0) : fs10.readFileSync(absPath);
|
|
32490
32424
|
return {
|
|
32491
32425
|
path: relativePath,
|
|
32492
32426
|
kind,
|
|
@@ -32497,7 +32431,7 @@ function readFileContent(root, relativePath) {
|
|
|
32497
32431
|
};
|
|
32498
32432
|
}
|
|
32499
32433
|
const truncated = stat.size > MAX_INLINE_SIZE;
|
|
32500
|
-
const content = truncated ?
|
|
32434
|
+
const content = truncated ? fs10.readFileSync(absPath, "utf-8").slice(0, MAX_INLINE_SIZE) : fs10.readFileSync(absPath, "utf-8");
|
|
32501
32435
|
return {
|
|
32502
32436
|
path: relativePath,
|
|
32503
32437
|
kind,
|
|
@@ -32557,62 +32491,264 @@ function getGitDiff(dirPath) {
|
|
|
32557
32491
|
};
|
|
32558
32492
|
}
|
|
32559
32493
|
|
|
32560
|
-
// ../../packages/api/src/
|
|
32561
|
-
var
|
|
32562
|
-
|
|
32563
|
-
|
|
32564
|
-
|
|
32565
|
-
|
|
32566
|
-
|
|
32567
|
-
|
|
32568
|
-
|
|
32569
|
-
|
|
32570
|
-
|
|
32571
|
-
|
|
32572
|
-
|
|
32494
|
+
// ../../packages/api/src/preview/preview-server.ts
|
|
32495
|
+
var crypto2 = __toESM(require("crypto"), 1);
|
|
32496
|
+
var fs11 = __toESM(require("fs"), 1);
|
|
32497
|
+
var path12 = __toESM(require("path"), 1);
|
|
32498
|
+
var http = __toESM(require("http"), 1);
|
|
32499
|
+
function resolvePreviewPath(rootPath, relativePath) {
|
|
32500
|
+
const sanitizedPath = relativePath.replace(/\\/g, "/");
|
|
32501
|
+
const resolvedPath = path12.resolve(rootPath, sanitizedPath);
|
|
32502
|
+
const normalizedRoot = path12.resolve(rootPath);
|
|
32503
|
+
if (!resolvedPath.startsWith(normalizedRoot + path12.sep) && resolvedPath !== normalizedRoot) {
|
|
32504
|
+
throw new Error("Invalid preview path");
|
|
32505
|
+
}
|
|
32506
|
+
return {
|
|
32507
|
+
absolutePath: resolvedPath,
|
|
32508
|
+
normalizedPath: path12.relative(normalizedRoot, resolvedPath).split(path12.sep).join("/")
|
|
32509
|
+
};
|
|
32510
|
+
}
|
|
32511
|
+
function resolvePreviewEntryPath(rootPath, entryPath) {
|
|
32512
|
+
const { absolutePath, normalizedPath } = resolvePreviewPath(rootPath, entryPath ?? "index.html");
|
|
32513
|
+
if (!fs11.existsSync(absolutePath) || !fs11.statSync(absolutePath).isFile()) {
|
|
32514
|
+
throw new Error("Preview entry not found");
|
|
32515
|
+
}
|
|
32516
|
+
return normalizedPath;
|
|
32517
|
+
}
|
|
32518
|
+
function buildPreviewUrl(origin, session) {
|
|
32519
|
+
const encodedEntryPath = session.entryPath.split("/").filter(Boolean).map((segment) => encodeURIComponent(segment)).join("/");
|
|
32520
|
+
return `${origin.replace(/\/+$/, "")}/preview/${session.token}/${encodedEntryPath}`;
|
|
32521
|
+
}
|
|
32522
|
+
var DEFAULT_TTL_MS = 15 * 60 * 1e3;
|
|
32523
|
+
var PreviewSessionManager = class {
|
|
32524
|
+
sessions = /* @__PURE__ */ new Map();
|
|
32525
|
+
create(options) {
|
|
32526
|
+
const token = crypto2.randomBytes(32).toString("hex");
|
|
32527
|
+
const entryPath = resolvePreviewEntryPath(options.rootPath, options.entryPath);
|
|
32528
|
+
const session = {
|
|
32529
|
+
token,
|
|
32530
|
+
taskId: options.taskId,
|
|
32531
|
+
rootPath: options.rootPath,
|
|
32532
|
+
entryPath,
|
|
32533
|
+
expiresAt: Date.now() + (options.ttlMs ?? DEFAULT_TTL_MS)
|
|
32534
|
+
};
|
|
32535
|
+
this.sessions.set(token, session);
|
|
32536
|
+
return session;
|
|
32537
|
+
}
|
|
32538
|
+
get(token) {
|
|
32539
|
+
const session = this.sessions.get(token);
|
|
32540
|
+
if (!session) return null;
|
|
32541
|
+
if (Date.now() > session.expiresAt) {
|
|
32542
|
+
this.sessions.delete(token);
|
|
32543
|
+
return null;
|
|
32573
32544
|
}
|
|
32545
|
+
return session;
|
|
32546
|
+
}
|
|
32547
|
+
cleanup() {
|
|
32548
|
+
const now = Date.now();
|
|
32549
|
+
for (const [token, session] of this.sessions) {
|
|
32550
|
+
if (now > session.expiresAt) {
|
|
32551
|
+
this.sessions.delete(token);
|
|
32552
|
+
}
|
|
32553
|
+
}
|
|
32554
|
+
}
|
|
32555
|
+
};
|
|
32556
|
+
var MIME_MAP2 = {
|
|
32557
|
+
".html": "text/html",
|
|
32558
|
+
".htm": "text/html",
|
|
32559
|
+
".css": "text/css",
|
|
32560
|
+
".js": "text/javascript",
|
|
32561
|
+
".mjs": "text/javascript",
|
|
32562
|
+
".json": "application/json",
|
|
32563
|
+
".png": "image/png",
|
|
32564
|
+
".jpg": "image/jpeg",
|
|
32565
|
+
".jpeg": "image/jpeg",
|
|
32566
|
+
".gif": "image/gif",
|
|
32567
|
+
".svg": "image/svg+xml",
|
|
32568
|
+
".webp": "image/webp",
|
|
32569
|
+
".ico": "image/x-icon",
|
|
32570
|
+
".woff": "font/woff",
|
|
32571
|
+
".woff2": "font/woff2",
|
|
32572
|
+
".ttf": "font/ttf",
|
|
32573
|
+
".eot": "application/vnd.ms-fontobject",
|
|
32574
|
+
".pdf": "application/pdf"
|
|
32575
|
+
};
|
|
32576
|
+
function getMime(filePath) {
|
|
32577
|
+
return MIME_MAP2[path12.extname(filePath).toLowerCase()] ?? "application/octet-stream";
|
|
32578
|
+
}
|
|
32579
|
+
function handlePreviewRequest(sessionManager, req, res) {
|
|
32580
|
+
const url = new URL(req.url ?? "/", "http://localhost");
|
|
32581
|
+
if (!url.pathname.startsWith("/preview/")) {
|
|
32582
|
+
return false;
|
|
32583
|
+
}
|
|
32584
|
+
if (req.method !== "GET") {
|
|
32585
|
+
res.writeHead(405, { "Content-Type": "text/plain" });
|
|
32586
|
+
res.end("Method not allowed");
|
|
32587
|
+
return true;
|
|
32588
|
+
}
|
|
32589
|
+
const match = url.pathname.match(/^\/preview\/([a-f0-9]+)(?:\/(.*))?$/i);
|
|
32590
|
+
const token = match?.[1];
|
|
32591
|
+
if (!token) {
|
|
32592
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
32593
|
+
res.end("Preview not found");
|
|
32594
|
+
return true;
|
|
32595
|
+
}
|
|
32596
|
+
const session = sessionManager.get(token);
|
|
32597
|
+
if (!session) {
|
|
32598
|
+
res.writeHead(403, { "Content-Type": "text/plain" });
|
|
32599
|
+
res.end("Invalid or expired preview token");
|
|
32600
|
+
return true;
|
|
32601
|
+
}
|
|
32602
|
+
const requestedPath = decodeURIComponent(match?.[2] ?? session.entryPath);
|
|
32603
|
+
let resolved;
|
|
32604
|
+
try {
|
|
32605
|
+
resolved = resolvePreviewPath(session.rootPath, requestedPath).absolutePath;
|
|
32606
|
+
} catch {
|
|
32607
|
+
res.writeHead(400, { "Content-Type": "text/plain" });
|
|
32608
|
+
res.end("Invalid path");
|
|
32609
|
+
return true;
|
|
32610
|
+
}
|
|
32611
|
+
if (!fs11.existsSync(resolved) || !fs11.statSync(resolved).isFile()) {
|
|
32612
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
32613
|
+
res.end("File not found");
|
|
32614
|
+
return true;
|
|
32615
|
+
}
|
|
32616
|
+
const mime = getMime(resolved);
|
|
32617
|
+
const content = fs11.readFileSync(resolved);
|
|
32618
|
+
res.writeHead(200, {
|
|
32619
|
+
"Content-Type": mime,
|
|
32620
|
+
"Content-Length": content.length,
|
|
32621
|
+
"Cache-Control": "no-cache"
|
|
32622
|
+
});
|
|
32623
|
+
res.end(content);
|
|
32624
|
+
return true;
|
|
32625
|
+
}
|
|
32626
|
+
|
|
32627
|
+
// ../../packages/api/src/task-output-service.ts
|
|
32628
|
+
var TASK_OUTPUT_ROUTE_PREFIX = "/api/tasks";
|
|
32629
|
+
function getTask(taskEngine, taskId) {
|
|
32630
|
+
const task = taskEngine.getTask(taskId);
|
|
32631
|
+
if (!task) {
|
|
32574
32632
|
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
32575
32633
|
}
|
|
32576
|
-
|
|
32577
|
-
|
|
32578
|
-
|
|
32579
|
-
|
|
32580
|
-
|
|
32581
|
-
|
|
32582
|
-
|
|
32583
|
-
|
|
32584
|
-
|
|
32634
|
+
return task;
|
|
32635
|
+
}
|
|
32636
|
+
function getTaskOutputRoot(taskEngine, taskId) {
|
|
32637
|
+
const task = getTask(taskEngine, taskId);
|
|
32638
|
+
if (!task.effectiveProjectPath) {
|
|
32639
|
+
throw new MeshyError("VALIDATION_ERROR", "Task output not available", 400);
|
|
32640
|
+
}
|
|
32641
|
+
return task.effectiveProjectPath;
|
|
32642
|
+
}
|
|
32643
|
+
function buildTaskOutputDownloadUrl(taskId, filePath) {
|
|
32644
|
+
return `${TASK_OUTPUT_ROUTE_PREFIX}/${taskId}/output/download?path=${encodeURIComponent(filePath)}`;
|
|
32645
|
+
}
|
|
32646
|
+
function getLocalTaskOutputSummary(taskEngine, taskId) {
|
|
32647
|
+
const task = getTask(taskEngine, taskId);
|
|
32648
|
+
if (!task.effectiveProjectPath) {
|
|
32649
|
+
return {
|
|
32650
|
+
taskId: task.id,
|
|
32651
|
+
requestedProject: task.project,
|
|
32652
|
+
effectiveProjectPath: null,
|
|
32653
|
+
assignedTo: task.assignedTo,
|
|
32654
|
+
available: false,
|
|
32655
|
+
summary: null
|
|
32656
|
+
};
|
|
32657
|
+
}
|
|
32658
|
+
return {
|
|
32659
|
+
taskId: task.id,
|
|
32660
|
+
requestedProject: task.project,
|
|
32661
|
+
effectiveProjectPath: task.effectiveProjectPath,
|
|
32662
|
+
assignedTo: task.assignedTo,
|
|
32663
|
+
available: true,
|
|
32664
|
+
summary: getOutputSummary(task.effectiveProjectPath)
|
|
32665
|
+
};
|
|
32666
|
+
}
|
|
32667
|
+
function getLocalTaskOutputTree(taskEngine, taskId, currentPath) {
|
|
32668
|
+
const rootPath = getTaskOutputRoot(taskEngine, taskId);
|
|
32669
|
+
try {
|
|
32670
|
+
return {
|
|
32671
|
+
rootPath,
|
|
32672
|
+
currentPath,
|
|
32673
|
+
entries: listDirectory(rootPath, currentPath)
|
|
32674
|
+
};
|
|
32675
|
+
} catch (err) {
|
|
32676
|
+
if (err instanceof Error && err.message === "Path traversal detected") {
|
|
32677
|
+
throw new MeshyError("VALIDATION_ERROR", "Invalid directory path", 400);
|
|
32585
32678
|
}
|
|
32586
|
-
throw
|
|
32679
|
+
throw err;
|
|
32587
32680
|
}
|
|
32588
|
-
|
|
32589
|
-
|
|
32590
|
-
|
|
32591
|
-
|
|
32592
|
-
|
|
32593
|
-
|
|
32594
|
-
|
|
32595
|
-
|
|
32596
|
-
|
|
32597
|
-
|
|
32598
|
-
|
|
32599
|
-
|
|
32600
|
-
|
|
32601
|
-
|
|
32602
|
-
|
|
32681
|
+
}
|
|
32682
|
+
function getLocalTaskOutputContent(taskEngine, taskId, filePath) {
|
|
32683
|
+
const rootPath = getTaskOutputRoot(taskEngine, taskId);
|
|
32684
|
+
try {
|
|
32685
|
+
return {
|
|
32686
|
+
...readFileContent(rootPath, filePath),
|
|
32687
|
+
downloadUrl: buildTaskOutputDownloadUrl(taskId, filePath)
|
|
32688
|
+
};
|
|
32689
|
+
} catch (err) {
|
|
32690
|
+
if (err instanceof Error && err.message === "Path traversal detected") {
|
|
32691
|
+
throw new MeshyError("VALIDATION_ERROR", "Invalid file path", 400);
|
|
32692
|
+
}
|
|
32693
|
+
if (err instanceof Error && err.message === "File not found") {
|
|
32694
|
+
throw new MeshyError("TASK_NOT_FOUND", `File not found: ${filePath}`, 404);
|
|
32695
|
+
}
|
|
32696
|
+
throw err;
|
|
32697
|
+
}
|
|
32698
|
+
}
|
|
32699
|
+
function getLocalTaskOutputDownload(taskEngine, taskId, filePath) {
|
|
32700
|
+
const rootPath = getTaskOutputRoot(taskEngine, taskId);
|
|
32701
|
+
try {
|
|
32702
|
+
const absolutePath = resolveOutputPath(rootPath, filePath);
|
|
32703
|
+
if (!fs12.existsSync(absolutePath) || !fs12.statSync(absolutePath).isFile()) {
|
|
32704
|
+
throw new MeshyError("TASK_NOT_FOUND", `File not found: ${filePath}`, 404);
|
|
32705
|
+
}
|
|
32706
|
+
const { mimeType } = classifyFile(absolutePath);
|
|
32707
|
+
const fileName = path13.basename(absolutePath).replace(/"/g, "");
|
|
32708
|
+
return {
|
|
32709
|
+
content: fs12.readFileSync(absolutePath),
|
|
32710
|
+
headers: {
|
|
32711
|
+
"Content-Type": mimeType,
|
|
32712
|
+
"Content-Disposition": `inline; filename="${fileName}"`,
|
|
32713
|
+
"Cache-Control": "no-cache"
|
|
32603
32714
|
}
|
|
32715
|
+
};
|
|
32716
|
+
} catch (err) {
|
|
32717
|
+
if (err instanceof MeshyError) {
|
|
32718
|
+
throw err;
|
|
32719
|
+
}
|
|
32720
|
+
if (err instanceof Error && err.message === "Path traversal detected") {
|
|
32721
|
+
throw new MeshyError("VALIDATION_ERROR", "Invalid file path", 400);
|
|
32604
32722
|
}
|
|
32723
|
+
throw err;
|
|
32605
32724
|
}
|
|
32606
|
-
|
|
32607
|
-
|
|
32608
|
-
|
|
32725
|
+
}
|
|
32726
|
+
function getLocalTaskOutputDiff(taskEngine, taskId) {
|
|
32727
|
+
const rootPath = getTaskOutputRoot(taskEngine, taskId);
|
|
32728
|
+
return getGitDiff(rootPath);
|
|
32729
|
+
}
|
|
32730
|
+
async function createPreviewSessionPayload(deps, taskId, entryPath) {
|
|
32731
|
+
const previewManager = deps.previewSessionManager;
|
|
32732
|
+
if (!previewManager) {
|
|
32733
|
+
throw new MeshyError("VALIDATION_ERROR", "Preview not available on this node", 400);
|
|
32734
|
+
}
|
|
32735
|
+
if (!deps.previewPort) {
|
|
32736
|
+
throw new MeshyError("VALIDATION_ERROR", "Preview server not running", 400);
|
|
32737
|
+
}
|
|
32738
|
+
const rootPath = getTaskOutputRoot(deps.taskEngine, taskId);
|
|
32739
|
+
const session = previewManager.create({
|
|
32740
|
+
taskId,
|
|
32741
|
+
rootPath,
|
|
32742
|
+
entryPath
|
|
32743
|
+
});
|
|
32744
|
+
const origin = deps.ensurePreviewOrigin ? await deps.ensurePreviewOrigin() ?? deps.previewOrigin : deps.previewOrigin;
|
|
32745
|
+
if (!origin) {
|
|
32746
|
+
throw new MeshyError("VALIDATION_ERROR", "Preview origin not available", 502);
|
|
32609
32747
|
}
|
|
32610
32748
|
return {
|
|
32611
|
-
|
|
32612
|
-
|
|
32613
|
-
|
|
32614
|
-
missing: false,
|
|
32615
|
-
terminal: false
|
|
32749
|
+
previewUrl: buildPreviewUrl(origin, session),
|
|
32750
|
+
expiresAt: session.expiresAt,
|
|
32751
|
+
entryPath: session.entryPath
|
|
32616
32752
|
};
|
|
32617
32753
|
}
|
|
32618
32754
|
|
|
@@ -32654,44 +32790,6 @@ function errorResponse(requestId, err) {
|
|
|
32654
32790
|
}
|
|
32655
32791
|
});
|
|
32656
32792
|
}
|
|
32657
|
-
function getTask(taskEngine, taskId) {
|
|
32658
|
-
const task = taskEngine.getTask(taskId);
|
|
32659
|
-
if (!task) {
|
|
32660
|
-
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
32661
|
-
}
|
|
32662
|
-
return task;
|
|
32663
|
-
}
|
|
32664
|
-
function getTaskOutputRoot(taskEngine, taskId) {
|
|
32665
|
-
const task = getTask(taskEngine, taskId);
|
|
32666
|
-
if (!task.effectiveProjectPath) {
|
|
32667
|
-
throw new MeshyError("VALIDATION_ERROR", "Task output not available", 400);
|
|
32668
|
-
}
|
|
32669
|
-
return task.effectiveProjectPath;
|
|
32670
|
-
}
|
|
32671
|
-
async function createPreviewSessionPayload(deps, taskId, entryPath) {
|
|
32672
|
-
const previewManager = deps.previewSessionManager;
|
|
32673
|
-
if (!previewManager) {
|
|
32674
|
-
throw new MeshyError("VALIDATION_ERROR", "Preview not available on this node", 400);
|
|
32675
|
-
}
|
|
32676
|
-
if (!deps.previewPort) {
|
|
32677
|
-
throw new MeshyError("VALIDATION_ERROR", "Preview server not running", 400);
|
|
32678
|
-
}
|
|
32679
|
-
const rootPath = getTaskOutputRoot(deps.taskEngine, taskId);
|
|
32680
|
-
const session = previewManager.create({
|
|
32681
|
-
taskId,
|
|
32682
|
-
rootPath,
|
|
32683
|
-
entryPath
|
|
32684
|
-
});
|
|
32685
|
-
const origin = deps.ensurePreviewOrigin ? await deps.ensurePreviewOrigin() ?? deps.previewOrigin : deps.previewOrigin;
|
|
32686
|
-
if (!origin) {
|
|
32687
|
-
throw new MeshyError("VALIDATION_ERROR", "Preview origin not available", 502);
|
|
32688
|
-
}
|
|
32689
|
-
return {
|
|
32690
|
-
previewUrl: buildPreviewUrl(origin, session),
|
|
32691
|
-
expiresAt: session.expiresAt,
|
|
32692
|
-
entryPath: session.entryPath
|
|
32693
|
-
};
|
|
32694
|
-
}
|
|
32695
32793
|
async function executeWorkerControlRequest(deps, request) {
|
|
32696
32794
|
const log = deps.logger.child("worker-control");
|
|
32697
32795
|
log.info("received worker control request", {
|
|
@@ -32751,89 +32849,40 @@ async function executeWorkerControlRequest(deps, request) {
|
|
|
32751
32849
|
break;
|
|
32752
32850
|
}
|
|
32753
32851
|
case "task-output-summary": {
|
|
32754
|
-
|
|
32755
|
-
|
|
32756
|
-
|
|
32757
|
-
|
|
32758
|
-
|
|
32759
|
-
effectiveProjectPath: null,
|
|
32760
|
-
assignedTo: task.assignedTo,
|
|
32761
|
-
available: false,
|
|
32762
|
-
summary: null
|
|
32763
|
-
});
|
|
32764
|
-
break;
|
|
32765
|
-
}
|
|
32766
|
-
response = jsonResponse(request.requestId, 200, {
|
|
32767
|
-
taskId: task.id,
|
|
32768
|
-
requestedProject: task.project,
|
|
32769
|
-
effectiveProjectPath: task.effectiveProjectPath,
|
|
32770
|
-
assignedTo: task.assignedTo,
|
|
32771
|
-
available: true,
|
|
32772
|
-
summary: getOutputSummary(task.effectiveProjectPath)
|
|
32773
|
-
});
|
|
32852
|
+
response = jsonResponse(
|
|
32853
|
+
request.requestId,
|
|
32854
|
+
200,
|
|
32855
|
+
getLocalTaskOutputSummary(deps.taskEngine, request.taskId ?? "")
|
|
32856
|
+
);
|
|
32774
32857
|
break;
|
|
32775
32858
|
}
|
|
32776
32859
|
case "task-output-tree": {
|
|
32777
|
-
|
|
32778
|
-
|
|
32779
|
-
|
|
32780
|
-
|
|
32781
|
-
|
|
32782
|
-
|
|
32783
|
-
});
|
|
32784
|
-
break;
|
|
32785
|
-
} catch (err) {
|
|
32786
|
-
if (err instanceof Error && err.message === "Path traversal detected") {
|
|
32787
|
-
throw new MeshyError("VALIDATION_ERROR", "Invalid directory path", 400);
|
|
32788
|
-
}
|
|
32789
|
-
throw err;
|
|
32790
|
-
}
|
|
32860
|
+
response = jsonResponse(
|
|
32861
|
+
request.requestId,
|
|
32862
|
+
200,
|
|
32863
|
+
getLocalTaskOutputTree(deps.taskEngine, request.taskId ?? "", request.path ?? ".")
|
|
32864
|
+
);
|
|
32865
|
+
break;
|
|
32791
32866
|
}
|
|
32792
32867
|
case "task-output-content": {
|
|
32793
|
-
|
|
32794
|
-
|
|
32795
|
-
|
|
32796
|
-
|
|
32797
|
-
|
|
32798
|
-
|
|
32799
|
-
});
|
|
32800
|
-
break;
|
|
32801
|
-
} catch (err) {
|
|
32802
|
-
if (err instanceof Error && err.message === "Path traversal detected") {
|
|
32803
|
-
throw new MeshyError("VALIDATION_ERROR", "Invalid file path", 400);
|
|
32804
|
-
}
|
|
32805
|
-
if (err instanceof Error && err.message === "File not found") {
|
|
32806
|
-
throw new MeshyError("TASK_NOT_FOUND", `File not found: ${request.path}`, 404);
|
|
32807
|
-
}
|
|
32808
|
-
throw err;
|
|
32809
|
-
}
|
|
32868
|
+
response = jsonResponse(
|
|
32869
|
+
request.requestId,
|
|
32870
|
+
200,
|
|
32871
|
+
getLocalTaskOutputContent(deps.taskEngine, request.taskId ?? "", request.path ?? "")
|
|
32872
|
+
);
|
|
32873
|
+
break;
|
|
32810
32874
|
}
|
|
32811
32875
|
case "task-output-download": {
|
|
32812
|
-
const
|
|
32813
|
-
|
|
32814
|
-
|
|
32815
|
-
if (!fs12.existsSync(absolutePath) || !fs12.statSync(absolutePath).isFile()) {
|
|
32816
|
-
throw new MeshyError("TASK_NOT_FOUND", `File not found: ${request.path}`, 404);
|
|
32817
|
-
}
|
|
32818
|
-
const { mimeType } = classifyFile(absolutePath);
|
|
32819
|
-
const fileName = path13.basename(absolutePath).replace(/"/g, "");
|
|
32820
|
-
response = binaryResponse(request.requestId, 200, fs12.readFileSync(absolutePath), {
|
|
32821
|
-
"Content-Type": mimeType,
|
|
32822
|
-
"Content-Disposition": `inline; filename="${fileName}"`,
|
|
32823
|
-
"Cache-Control": "no-cache"
|
|
32824
|
-
});
|
|
32825
|
-
break;
|
|
32826
|
-
} catch (err) {
|
|
32827
|
-
if (err instanceof MeshyError) throw err;
|
|
32828
|
-
if (err instanceof Error && err.message === "Path traversal detected") {
|
|
32829
|
-
throw new MeshyError("VALIDATION_ERROR", "Invalid file path", 400);
|
|
32830
|
-
}
|
|
32831
|
-
throw err;
|
|
32832
|
-
}
|
|
32876
|
+
const download = getLocalTaskOutputDownload(deps.taskEngine, request.taskId ?? "", request.path ?? "");
|
|
32877
|
+
response = binaryResponse(request.requestId, 200, download.content, download.headers);
|
|
32878
|
+
break;
|
|
32833
32879
|
}
|
|
32834
32880
|
case "task-output-diff": {
|
|
32835
|
-
|
|
32836
|
-
|
|
32881
|
+
response = jsonResponse(
|
|
32882
|
+
request.requestId,
|
|
32883
|
+
200,
|
|
32884
|
+
getLocalTaskOutputDiff(deps.taskEngine, request.taskId ?? "")
|
|
32885
|
+
);
|
|
32837
32886
|
break;
|
|
32838
32887
|
}
|
|
32839
32888
|
case "task-preview-session": {
|
|
@@ -33066,9 +33115,7 @@ function createNodeRoutes() {
|
|
|
33066
33115
|
}
|
|
33067
33116
|
|
|
33068
33117
|
// ../../packages/api/src/routes/tasks.ts
|
|
33069
|
-
var
|
|
33070
|
-
var path14 = __toESM(require("path"), 1);
|
|
33071
|
-
var import_express3 = __toESM(require_express2(), 1);
|
|
33118
|
+
var import_express4 = __toESM(require_express2(), 1);
|
|
33072
33119
|
|
|
33073
33120
|
// ../../packages/api/src/task-route-utils.ts
|
|
33074
33121
|
var fs13 = __toESM(require("fs"), 1);
|
|
@@ -33177,11 +33224,190 @@ function startLocalTaskFollowUp(deps, task, content, assignedTo, metadata) {
|
|
|
33177
33224
|
}
|
|
33178
33225
|
}
|
|
33179
33226
|
|
|
33227
|
+
// ../../packages/api/src/routes/task-output.ts
|
|
33228
|
+
var import_express3 = __toESM(require_express2(), 1);
|
|
33229
|
+
function asyncHandler3(fn) {
|
|
33230
|
+
return (req, res, next) => fn(req, res, next).catch(next);
|
|
33231
|
+
}
|
|
33232
|
+
async function maybeHandleRemoteTaskOutputRequest(req, res, taskId, subPath, init, fallbackRequest) {
|
|
33233
|
+
const { taskEngine, nodeRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
33234
|
+
const log = rootLogger.child("tasks/output");
|
|
33235
|
+
const task = taskEngine.getTask(taskId);
|
|
33236
|
+
if (!task) {
|
|
33237
|
+
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
33238
|
+
}
|
|
33239
|
+
const selfId = nodeRegistry.getSelf()?.id;
|
|
33240
|
+
const needsProxy = !!(task.assignedTo && task.assignedTo !== selfId);
|
|
33241
|
+
if (!needsProxy) {
|
|
33242
|
+
return false;
|
|
33243
|
+
}
|
|
33244
|
+
const assignedNodeId = task.assignedTo;
|
|
33245
|
+
if (!assignedNodeId) {
|
|
33246
|
+
return false;
|
|
33247
|
+
}
|
|
33248
|
+
const node = nodeRegistry.getNode(assignedNodeId);
|
|
33249
|
+
if (!node) {
|
|
33250
|
+
throw new MeshyError("NODE_NOT_FOUND", `Assigned node ${assignedNodeId} not found`, 404);
|
|
33251
|
+
}
|
|
33252
|
+
if (!node.previewOrigin) {
|
|
33253
|
+
if (fallbackRequest && heartbeat?.requestWorkerControl) {
|
|
33254
|
+
log.warn("task output server origin missing, falling back to keepalive control", {
|
|
33255
|
+
taskId,
|
|
33256
|
+
assignedTo: assignedNodeId,
|
|
33257
|
+
kind: fallbackRequest.kind
|
|
33258
|
+
});
|
|
33259
|
+
const controlResponse = await heartbeat.requestWorkerControl(assignedNodeId, fallbackRequest);
|
|
33260
|
+
sendWorkerControlResponse(res, controlResponse);
|
|
33261
|
+
return true;
|
|
33262
|
+
}
|
|
33263
|
+
throw new MeshyError("NODE_OFFLINE", "Task output API is not available on the assigned worker", 502);
|
|
33264
|
+
}
|
|
33265
|
+
const qs = new URL(req.originalUrl ?? req.url, "http://localhost").search;
|
|
33266
|
+
const proxyPath = `/api/tasks/${taskId}/output${subPath}${qs}`;
|
|
33267
|
+
try {
|
|
33268
|
+
const { endpoint, response: proxyRes } = await fetchNodeWithFallback(
|
|
33269
|
+
{ endpoint: node.previewOrigin },
|
|
33270
|
+
proxyPath,
|
|
33271
|
+
init
|
|
33272
|
+
);
|
|
33273
|
+
log.debug("proxying task output request to worker output server", {
|
|
33274
|
+
taskId,
|
|
33275
|
+
assignedTo: assignedNodeId,
|
|
33276
|
+
proxyPath,
|
|
33277
|
+
outputOrigin: endpoint
|
|
33278
|
+
});
|
|
33279
|
+
await sendProxyResponse(res, proxyRes);
|
|
33280
|
+
return true;
|
|
33281
|
+
} catch (err) {
|
|
33282
|
+
if (fallbackRequest && heartbeat?.requestWorkerControl) {
|
|
33283
|
+
log.warn("output server proxy failed, falling back to keepalive control", {
|
|
33284
|
+
taskId,
|
|
33285
|
+
assignedTo: assignedNodeId,
|
|
33286
|
+
kind: fallbackRequest.kind,
|
|
33287
|
+
error: err instanceof Error ? err.message : String(err)
|
|
33288
|
+
});
|
|
33289
|
+
const controlResponse = await heartbeat.requestWorkerControl(assignedNodeId, fallbackRequest);
|
|
33290
|
+
sendWorkerControlResponse(res, controlResponse);
|
|
33291
|
+
return true;
|
|
33292
|
+
}
|
|
33293
|
+
log.warn("output server proxy error", {
|
|
33294
|
+
taskId,
|
|
33295
|
+
assignedTo: assignedNodeId,
|
|
33296
|
+
error: err instanceof Error ? err.message : String(err)
|
|
33297
|
+
});
|
|
33298
|
+
throw new MeshyError("NODE_OFFLINE", "Cannot reach worker for task output", 502);
|
|
33299
|
+
}
|
|
33300
|
+
}
|
|
33301
|
+
function createTaskOutputRoutes(options = {}) {
|
|
33302
|
+
const router = (0, import_express3.Router)();
|
|
33303
|
+
const allowRemoteProxy = options.allowRemoteProxy ?? true;
|
|
33304
|
+
router.get("/:id/output", asyncHandler3(async (req, res) => {
|
|
33305
|
+
const taskId = req.params.id;
|
|
33306
|
+
if (allowRemoteProxy) {
|
|
33307
|
+
const handled = await maybeHandleRemoteTaskOutputRequest(req, res, taskId, "", void 0, {
|
|
33308
|
+
kind: "task-output-summary",
|
|
33309
|
+
taskId
|
|
33310
|
+
});
|
|
33311
|
+
if (handled) {
|
|
33312
|
+
return;
|
|
33313
|
+
}
|
|
33314
|
+
}
|
|
33315
|
+
const { taskEngine } = req.app.locals.deps;
|
|
33316
|
+
res.json(getLocalTaskOutputSummary(taskEngine, taskId));
|
|
33317
|
+
}));
|
|
33318
|
+
router.get("/:id/output/tree", asyncHandler3(async (req, res) => {
|
|
33319
|
+
const taskId = req.params.id;
|
|
33320
|
+
const query = TaskOutputTreeQuery.parse(req.query);
|
|
33321
|
+
if (allowRemoteProxy) {
|
|
33322
|
+
const handled = await maybeHandleRemoteTaskOutputRequest(req, res, taskId, "/tree", void 0, {
|
|
33323
|
+
kind: "task-output-tree",
|
|
33324
|
+
taskId,
|
|
33325
|
+
path: query.path
|
|
33326
|
+
});
|
|
33327
|
+
if (handled) {
|
|
33328
|
+
return;
|
|
33329
|
+
}
|
|
33330
|
+
}
|
|
33331
|
+
const { taskEngine } = req.app.locals.deps;
|
|
33332
|
+
res.json(getLocalTaskOutputTree(taskEngine, taskId, query.path));
|
|
33333
|
+
}));
|
|
33334
|
+
router.get("/:id/output/content", asyncHandler3(async (req, res) => {
|
|
33335
|
+
const taskId = req.params.id;
|
|
33336
|
+
const query = TaskOutputContentQuery.parse(req.query);
|
|
33337
|
+
if (allowRemoteProxy) {
|
|
33338
|
+
const handled = await maybeHandleRemoteTaskOutputRequest(req, res, taskId, "/content", void 0, {
|
|
33339
|
+
kind: "task-output-content",
|
|
33340
|
+
taskId,
|
|
33341
|
+
path: query.path
|
|
33342
|
+
});
|
|
33343
|
+
if (handled) {
|
|
33344
|
+
return;
|
|
33345
|
+
}
|
|
33346
|
+
}
|
|
33347
|
+
const { taskEngine } = req.app.locals.deps;
|
|
33348
|
+
res.json(getLocalTaskOutputContent(taskEngine, taskId, query.path));
|
|
33349
|
+
}));
|
|
33350
|
+
router.get("/:id/output/download", asyncHandler3(async (req, res) => {
|
|
33351
|
+
const taskId = req.params.id;
|
|
33352
|
+
const query = TaskOutputDownloadQuery.parse(req.query);
|
|
33353
|
+
if (allowRemoteProxy) {
|
|
33354
|
+
const handled = await maybeHandleRemoteTaskOutputRequest(req, res, taskId, "/download", void 0, {
|
|
33355
|
+
kind: "task-output-download",
|
|
33356
|
+
taskId,
|
|
33357
|
+
path: query.path
|
|
33358
|
+
});
|
|
33359
|
+
if (handled) {
|
|
33360
|
+
return;
|
|
33361
|
+
}
|
|
33362
|
+
}
|
|
33363
|
+
const { taskEngine } = req.app.locals.deps;
|
|
33364
|
+
const download = getLocalTaskOutputDownload(taskEngine, taskId, query.path);
|
|
33365
|
+
for (const [key, value] of Object.entries(download.headers)) {
|
|
33366
|
+
res.setHeader(key, value);
|
|
33367
|
+
}
|
|
33368
|
+
res.send(download.content);
|
|
33369
|
+
}));
|
|
33370
|
+
router.get("/:id/output/diff", asyncHandler3(async (req, res) => {
|
|
33371
|
+
const taskId = req.params.id;
|
|
33372
|
+
if (allowRemoteProxy) {
|
|
33373
|
+
const handled = await maybeHandleRemoteTaskOutputRequest(req, res, taskId, "/diff", void 0, {
|
|
33374
|
+
kind: "task-output-diff",
|
|
33375
|
+
taskId
|
|
33376
|
+
});
|
|
33377
|
+
if (handled) {
|
|
33378
|
+
return;
|
|
33379
|
+
}
|
|
33380
|
+
}
|
|
33381
|
+
const { taskEngine } = req.app.locals.deps;
|
|
33382
|
+
res.json(getLocalTaskOutputDiff(taskEngine, taskId));
|
|
33383
|
+
}));
|
|
33384
|
+
router.post("/:id/output/preview-sessions", asyncHandler3(async (req, res) => {
|
|
33385
|
+
const taskId = req.params.id;
|
|
33386
|
+
const body = TaskPreviewSessionBody.parse(req.body ?? {});
|
|
33387
|
+
if (allowRemoteProxy) {
|
|
33388
|
+
const handled = await maybeHandleRemoteTaskOutputRequest(req, res, taskId, "/preview-sessions", {
|
|
33389
|
+
method: "POST",
|
|
33390
|
+
headers: { "Content-Type": "application/json" },
|
|
33391
|
+
body: JSON.stringify(body)
|
|
33392
|
+
}, {
|
|
33393
|
+
kind: "task-preview-session",
|
|
33394
|
+
taskId,
|
|
33395
|
+
path: body.path
|
|
33396
|
+
});
|
|
33397
|
+
if (handled) {
|
|
33398
|
+
return;
|
|
33399
|
+
}
|
|
33400
|
+
}
|
|
33401
|
+
res.json(await createPreviewSessionPayload(req.app.locals.deps, taskId, body.path));
|
|
33402
|
+
}));
|
|
33403
|
+
return router;
|
|
33404
|
+
}
|
|
33405
|
+
|
|
33180
33406
|
// ../../packages/api/src/routes/tasks.ts
|
|
33181
33407
|
var TERMINAL_STATUSES3 = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "archived"]);
|
|
33182
33408
|
var ARCHIVABLE_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "archived"]);
|
|
33183
33409
|
var ACTIVE_STATUSES = /* @__PURE__ */ new Set(["pending", "assigned", "running"]);
|
|
33184
|
-
function
|
|
33410
|
+
function asyncHandler4(fn) {
|
|
33185
33411
|
return (req, res, next) => fn(req, res, next).catch(next);
|
|
33186
33412
|
}
|
|
33187
33413
|
function withAssignedNodeMetadata(task, nodeRegistry) {
|
|
@@ -33196,8 +33422,8 @@ function withAssignedNodeMetadata(task, nodeRegistry) {
|
|
|
33196
33422
|
};
|
|
33197
33423
|
}
|
|
33198
33424
|
function createTaskRoutes() {
|
|
33199
|
-
const router = (0,
|
|
33200
|
-
router.post("/",
|
|
33425
|
+
const router = (0, import_express4.Router)();
|
|
33426
|
+
router.post("/", asyncHandler4(async (req, res) => {
|
|
33201
33427
|
const { taskEngine, nodeRegistry } = req.app.locals.deps;
|
|
33202
33428
|
const body = CreateTaskBody.parse(req.body);
|
|
33203
33429
|
const task = taskEngine.createTask({
|
|
@@ -33216,7 +33442,7 @@ function createTaskRoutes() {
|
|
|
33216
33442
|
}
|
|
33217
33443
|
res.status(201).json(withAssignedNodeMetadata(task, nodeRegistry));
|
|
33218
33444
|
}));
|
|
33219
|
-
router.get("/",
|
|
33445
|
+
router.get("/", asyncHandler4(async (req, res) => {
|
|
33220
33446
|
const { taskEngine, nodeRegistry } = req.app.locals.deps;
|
|
33221
33447
|
const query = TaskListQuery.parse(req.query);
|
|
33222
33448
|
const filter = {};
|
|
@@ -33231,7 +33457,7 @@ function createTaskRoutes() {
|
|
|
33231
33457
|
total: result.total
|
|
33232
33458
|
});
|
|
33233
33459
|
}));
|
|
33234
|
-
router.post("/batch/delete",
|
|
33460
|
+
router.post("/batch/delete", asyncHandler4(async (req, res) => {
|
|
33235
33461
|
const { taskEngine } = req.app.locals.deps;
|
|
33236
33462
|
const { ids } = BatchTaskIdsBody.parse(req.body);
|
|
33237
33463
|
const results = ids.map((id) => {
|
|
@@ -33244,7 +33470,7 @@ function createTaskRoutes() {
|
|
|
33244
33470
|
});
|
|
33245
33471
|
res.json({ results });
|
|
33246
33472
|
}));
|
|
33247
|
-
router.post("/batch/archive",
|
|
33473
|
+
router.post("/batch/archive", asyncHandler4(async (req, res) => {
|
|
33248
33474
|
const { taskEngine } = req.app.locals.deps;
|
|
33249
33475
|
const { ids } = BatchTaskIdsBody.parse(req.body);
|
|
33250
33476
|
const results = ids.map((id) => {
|
|
@@ -33262,7 +33488,7 @@ function createTaskRoutes() {
|
|
|
33262
33488
|
});
|
|
33263
33489
|
res.json({ results });
|
|
33264
33490
|
}));
|
|
33265
|
-
router.get("/:id",
|
|
33491
|
+
router.get("/:id", asyncHandler4(async (req, res) => {
|
|
33266
33492
|
const { taskEngine, nodeRegistry } = req.app.locals.deps;
|
|
33267
33493
|
const task = taskEngine.getTask(req.params.id);
|
|
33268
33494
|
if (!task) {
|
|
@@ -33270,7 +33496,7 @@ function createTaskRoutes() {
|
|
|
33270
33496
|
}
|
|
33271
33497
|
res.json(withAssignedNodeMetadata(task, nodeRegistry));
|
|
33272
33498
|
}));
|
|
33273
|
-
router.patch("/:id",
|
|
33499
|
+
router.patch("/:id", asyncHandler4(async (req, res) => {
|
|
33274
33500
|
const { taskEngine, nodeRegistry, logger: rootLogger } = req.app.locals.deps;
|
|
33275
33501
|
const log = rootLogger.child("tasks/patch");
|
|
33276
33502
|
const updates = UpdateTaskBody.parse(req.body);
|
|
@@ -33309,7 +33535,7 @@ function createTaskRoutes() {
|
|
|
33309
33535
|
}
|
|
33310
33536
|
res.json(withAssignedNodeMetadata(task, nodeRegistry));
|
|
33311
33537
|
}));
|
|
33312
|
-
router.delete("/:id",
|
|
33538
|
+
router.delete("/:id", asyncHandler4(async (req, res) => {
|
|
33313
33539
|
const { taskEngine } = req.app.locals.deps;
|
|
33314
33540
|
const result = taskEngine.deleteTask(req.params.id);
|
|
33315
33541
|
if (!result) {
|
|
@@ -33317,7 +33543,7 @@ function createTaskRoutes() {
|
|
|
33317
33543
|
}
|
|
33318
33544
|
res.json({ ok: true });
|
|
33319
33545
|
}));
|
|
33320
|
-
router.post("/:id/cancel",
|
|
33546
|
+
router.post("/:id/cancel", asyncHandler4(async (req, res) => {
|
|
33321
33547
|
const { taskEngine, nodeRegistry, engineRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
33322
33548
|
const log = rootLogger.child("tasks/cancel");
|
|
33323
33549
|
const task = taskEngine.getTask(req.params.id);
|
|
@@ -33354,18 +33580,18 @@ function createTaskRoutes() {
|
|
|
33354
33580
|
}, task.id);
|
|
33355
33581
|
res.json({ ok: true });
|
|
33356
33582
|
}));
|
|
33357
|
-
router.post("/:id/assign",
|
|
33583
|
+
router.post("/:id/assign", asyncHandler4(async (req, res) => {
|
|
33358
33584
|
const { taskEngine, nodeRegistry } = req.app.locals.deps;
|
|
33359
33585
|
const body = AssignTaskBody.parse(req.body);
|
|
33360
33586
|
const task = taskEngine.assignTask(req.params.id, body.nodeId);
|
|
33361
33587
|
res.json(withAssignedNodeMetadata(task, nodeRegistry));
|
|
33362
33588
|
}));
|
|
33363
|
-
router.post("/:id/retry",
|
|
33589
|
+
router.post("/:id/retry", asyncHandler4(async (req, res) => {
|
|
33364
33590
|
const { taskEngine, nodeRegistry } = req.app.locals.deps;
|
|
33365
33591
|
const task = taskEngine.retryTask(req.params.id);
|
|
33366
33592
|
res.json(withAssignedNodeMetadata(task, nodeRegistry));
|
|
33367
33593
|
}));
|
|
33368
|
-
router.get("/:id/logs",
|
|
33594
|
+
router.get("/:id/logs", asyncHandler4(async (req, res) => {
|
|
33369
33595
|
const { engineRegistry, taskEngine, nodeRegistry, logger: rootLogger } = req.app.locals.deps;
|
|
33370
33596
|
const log = rootLogger.child("tasks/logs");
|
|
33371
33597
|
const query = TaskLogsQuery.parse(req.query);
|
|
@@ -33432,7 +33658,7 @@ function createTaskRoutes() {
|
|
|
33432
33658
|
});
|
|
33433
33659
|
res.json(local);
|
|
33434
33660
|
}));
|
|
33435
|
-
router.post("/:id/message",
|
|
33661
|
+
router.post("/:id/message", asyncHandler4(async (req, res) => {
|
|
33436
33662
|
const { taskEngine, engineRegistry, nodeRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
33437
33663
|
const log = rootLogger.child("tasks/message");
|
|
33438
33664
|
const body = SendMessageBody.parse(req.body);
|
|
@@ -33516,281 +33742,24 @@ function createTaskRoutes() {
|
|
|
33516
33742
|
}, task, body.content, task.assignedTo);
|
|
33517
33743
|
res.json({ ok: true });
|
|
33518
33744
|
}));
|
|
33519
|
-
|
|
33520
|
-
const { taskEngine, nodeRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
33521
|
-
const log = rootLogger.child("tasks/output");
|
|
33522
|
-
const task = taskEngine.getTask(taskId);
|
|
33523
|
-
if (!task) {
|
|
33524
|
-
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
33525
|
-
}
|
|
33526
|
-
const effectivePath = task.effectiveProjectPath;
|
|
33527
|
-
if (!effectivePath) {
|
|
33528
|
-
throw new MeshyError("VALIDATION_ERROR", "Task output not available", 400);
|
|
33529
|
-
}
|
|
33530
|
-
const selfId = nodeRegistry.getSelf()?.id;
|
|
33531
|
-
const needsProxy = !!(task.assignedTo && task.assignedTo !== selfId);
|
|
33532
|
-
if (needsProxy) {
|
|
33533
|
-
const node = nodeRegistry.getNode(task.assignedTo);
|
|
33534
|
-
if (!node) {
|
|
33535
|
-
throw new MeshyError("NODE_NOT_FOUND", `Assigned node ${task.assignedTo} not found`, 404);
|
|
33536
|
-
}
|
|
33537
|
-
const canPushToNode = heartbeat?.canPushToNode?.(task.assignedTo) ?? true;
|
|
33538
|
-
if (!canPushToNode && fallbackRequest && heartbeat?.requestWorkerControl) {
|
|
33539
|
-
log.debug("skipping direct output proxy because worker is keepalive-only", {
|
|
33540
|
-
taskId,
|
|
33541
|
-
assignedTo: task.assignedTo,
|
|
33542
|
-
kind: fallbackRequest.kind
|
|
33543
|
-
});
|
|
33544
|
-
const controlResponse = await heartbeat.requestWorkerControl(task.assignedTo, fallbackRequest);
|
|
33545
|
-
sendWorkerControlResponse(res, controlResponse);
|
|
33546
|
-
return null;
|
|
33547
|
-
}
|
|
33548
|
-
const qs = new URL(req.url, "http://localhost").search;
|
|
33549
|
-
const proxyPath = `/api/tasks/${taskId}/output${subPath}${qs}`;
|
|
33550
|
-
try {
|
|
33551
|
-
const { endpoint, response: proxyRes } = await fetchNodeWithFallback(node, proxyPath, init);
|
|
33552
|
-
const proxyUrl = `${endpoint}${proxyPath}`;
|
|
33553
|
-
log.debug("proxying output request to worker", { taskId, proxyUrl });
|
|
33554
|
-
await sendProxyResponse(res, proxyRes);
|
|
33555
|
-
return null;
|
|
33556
|
-
} catch (err) {
|
|
33557
|
-
if (fallbackRequest && heartbeat?.requestWorkerControl) {
|
|
33558
|
-
log.warn("direct output proxy failed, falling back to keepalive control", {
|
|
33559
|
-
taskId,
|
|
33560
|
-
assignedTo: task.assignedTo,
|
|
33561
|
-
kind: fallbackRequest.kind,
|
|
33562
|
-
error: err instanceof Error ? err.message : String(err)
|
|
33563
|
-
});
|
|
33564
|
-
try {
|
|
33565
|
-
const controlResponse = await heartbeat.requestWorkerControl(task.assignedTo, fallbackRequest);
|
|
33566
|
-
sendWorkerControlResponse(res, controlResponse);
|
|
33567
|
-
return null;
|
|
33568
|
-
} catch (fallbackErr) {
|
|
33569
|
-
log.warn("keepalive output fallback failed", {
|
|
33570
|
-
taskId,
|
|
33571
|
-
assignedTo: task.assignedTo,
|
|
33572
|
-
kind: fallbackRequest.kind,
|
|
33573
|
-
error: fallbackErr instanceof Error ? fallbackErr.message : String(fallbackErr)
|
|
33574
|
-
});
|
|
33575
|
-
}
|
|
33576
|
-
}
|
|
33577
|
-
log.warn("output proxy error", { error: err instanceof Error ? err.message : String(err) });
|
|
33578
|
-
throw new MeshyError("NODE_OFFLINE", "Cannot reach worker for task output", 502);
|
|
33579
|
-
}
|
|
33580
|
-
}
|
|
33581
|
-
return effectivePath;
|
|
33582
|
-
}
|
|
33583
|
-
router.get("/:id/output", asyncHandler3(async (req, res) => {
|
|
33584
|
-
const { taskEngine } = req.app.locals.deps;
|
|
33585
|
-
const taskId = req.params.id;
|
|
33586
|
-
const task = taskEngine.getTask(taskId);
|
|
33587
|
-
if (!task) {
|
|
33588
|
-
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
33589
|
-
}
|
|
33590
|
-
const effectivePath = task.effectiveProjectPath;
|
|
33591
|
-
if (!effectivePath) {
|
|
33592
|
-
res.json({
|
|
33593
|
-
taskId,
|
|
33594
|
-
requestedProject: task.project,
|
|
33595
|
-
effectiveProjectPath: null,
|
|
33596
|
-
assignedTo: task.assignedTo,
|
|
33597
|
-
available: false,
|
|
33598
|
-
summary: null
|
|
33599
|
-
});
|
|
33600
|
-
return;
|
|
33601
|
-
}
|
|
33602
|
-
const root = await resolveTaskOutputOrProxy(req, res, taskId, "", void 0, {
|
|
33603
|
-
kind: "task-output-summary",
|
|
33604
|
-
taskId
|
|
33605
|
-
});
|
|
33606
|
-
if (root === null) return;
|
|
33607
|
-
const summary = getOutputSummary(root);
|
|
33608
|
-
res.json({
|
|
33609
|
-
taskId,
|
|
33610
|
-
requestedProject: task.project,
|
|
33611
|
-
effectiveProjectPath: effectivePath,
|
|
33612
|
-
assignedTo: task.assignedTo,
|
|
33613
|
-
available: true,
|
|
33614
|
-
summary
|
|
33615
|
-
});
|
|
33616
|
-
}));
|
|
33617
|
-
router.get("/:id/output/tree", asyncHandler3(async (req, res) => {
|
|
33618
|
-
const taskId = req.params.id;
|
|
33619
|
-
const query = TaskOutputTreeQuery.parse(req.query);
|
|
33620
|
-
const root = await resolveTaskOutputOrProxy(req, res, taskId, "/tree", void 0, {
|
|
33621
|
-
kind: "task-output-tree",
|
|
33622
|
-
taskId,
|
|
33623
|
-
path: query.path
|
|
33624
|
-
});
|
|
33625
|
-
if (root === null) return;
|
|
33626
|
-
try {
|
|
33627
|
-
const entries = listDirectory(root, query.path);
|
|
33628
|
-
res.json({
|
|
33629
|
-
rootPath: root,
|
|
33630
|
-
currentPath: query.path,
|
|
33631
|
-
entries
|
|
33632
|
-
});
|
|
33633
|
-
} catch (err) {
|
|
33634
|
-
if (err instanceof Error && err.message === "Path traversal detected") {
|
|
33635
|
-
throw new MeshyError("VALIDATION_ERROR", "Invalid directory path", 400);
|
|
33636
|
-
}
|
|
33637
|
-
throw err;
|
|
33638
|
-
}
|
|
33639
|
-
}));
|
|
33640
|
-
router.get("/:id/output/content", asyncHandler3(async (req, res) => {
|
|
33641
|
-
const taskId = req.params.id;
|
|
33642
|
-
const query = TaskOutputContentQuery.parse(req.query);
|
|
33643
|
-
const root = await resolveTaskOutputOrProxy(req, res, taskId, "/content", void 0, {
|
|
33644
|
-
kind: "task-output-content",
|
|
33645
|
-
taskId,
|
|
33646
|
-
path: query.path
|
|
33647
|
-
});
|
|
33648
|
-
if (root === null) return;
|
|
33649
|
-
try {
|
|
33650
|
-
const content = readFileContent(root, query.path);
|
|
33651
|
-
res.json({
|
|
33652
|
-
...content,
|
|
33653
|
-
downloadUrl: `/api/tasks/${taskId}/output/download?path=${encodeURIComponent(query.path)}`
|
|
33654
|
-
});
|
|
33655
|
-
} catch (err) {
|
|
33656
|
-
if (err instanceof Error && err.message === "Path traversal detected") {
|
|
33657
|
-
throw new MeshyError("VALIDATION_ERROR", "Invalid file path", 400);
|
|
33658
|
-
}
|
|
33659
|
-
if (err instanceof Error && err.message === "File not found") {
|
|
33660
|
-
throw new MeshyError("TASK_NOT_FOUND", `File not found: ${query.path}`, 404);
|
|
33661
|
-
}
|
|
33662
|
-
throw err;
|
|
33663
|
-
}
|
|
33664
|
-
}));
|
|
33665
|
-
router.get("/:id/output/download", asyncHandler3(async (req, res) => {
|
|
33666
|
-
const taskId = req.params.id;
|
|
33667
|
-
const query = TaskOutputDownloadQuery.parse(req.query);
|
|
33668
|
-
const root = await resolveTaskOutputOrProxy(req, res, taskId, "/download", void 0, {
|
|
33669
|
-
kind: "task-output-download",
|
|
33670
|
-
taskId,
|
|
33671
|
-
path: query.path
|
|
33672
|
-
});
|
|
33673
|
-
if (root === null) return;
|
|
33674
|
-
try {
|
|
33675
|
-
const absolutePath = resolveOutputPath(root, query.path);
|
|
33676
|
-
if (!fs14.existsSync(absolutePath) || !fs14.statSync(absolutePath).isFile()) {
|
|
33677
|
-
throw new MeshyError("TASK_NOT_FOUND", `File not found: ${query.path}`, 404);
|
|
33678
|
-
}
|
|
33679
|
-
const { mimeType } = classifyFile(absolutePath);
|
|
33680
|
-
const fileName = path14.basename(absolutePath).replace(/"/g, "");
|
|
33681
|
-
const content = fs14.readFileSync(absolutePath);
|
|
33682
|
-
res.setHeader("Content-Type", mimeType);
|
|
33683
|
-
res.setHeader("Content-Disposition", `inline; filename="${fileName}"`);
|
|
33684
|
-
res.setHeader("Cache-Control", "no-cache");
|
|
33685
|
-
res.send(content);
|
|
33686
|
-
} catch (err) {
|
|
33687
|
-
if (err instanceof MeshyError) throw err;
|
|
33688
|
-
if (err instanceof Error && err.message === "Path traversal detected") {
|
|
33689
|
-
throw new MeshyError("VALIDATION_ERROR", "Invalid file path", 400);
|
|
33690
|
-
}
|
|
33691
|
-
throw err;
|
|
33692
|
-
}
|
|
33693
|
-
}));
|
|
33694
|
-
router.get("/:id/output/diff", asyncHandler3(async (req, res) => {
|
|
33695
|
-
const taskId = req.params.id;
|
|
33696
|
-
const root = await resolveTaskOutputOrProxy(req, res, taskId, "/diff", void 0, {
|
|
33697
|
-
kind: "task-output-diff",
|
|
33698
|
-
taskId
|
|
33699
|
-
});
|
|
33700
|
-
if (root === null) return;
|
|
33701
|
-
const diff = getGitDiff(root);
|
|
33702
|
-
res.json(diff);
|
|
33703
|
-
}));
|
|
33704
|
-
router.post("/:id/output/preview-sessions", asyncHandler3(async (req, res) => {
|
|
33705
|
-
const { taskEngine, nodeRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
33706
|
-
const log = rootLogger.child("tasks/preview");
|
|
33707
|
-
const taskId = req.params.id;
|
|
33708
|
-
const body = TaskPreviewSessionBody.parse(req.body ?? {});
|
|
33709
|
-
const task = taskEngine.getTask(taskId);
|
|
33710
|
-
if (!task) {
|
|
33711
|
-
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
33712
|
-
}
|
|
33713
|
-
const effectivePath = task.effectiveProjectPath;
|
|
33714
|
-
if (!effectivePath) {
|
|
33715
|
-
throw new MeshyError("VALIDATION_ERROR", "Task output not available", 400);
|
|
33716
|
-
}
|
|
33717
|
-
const selfId = nodeRegistry.getSelf()?.id;
|
|
33718
|
-
const needsProxy = !!(task.assignedTo && task.assignedTo !== selfId);
|
|
33719
|
-
if (needsProxy) {
|
|
33720
|
-
const node = nodeRegistry.getNode(task.assignedTo);
|
|
33721
|
-
if (!node) {
|
|
33722
|
-
throw new MeshyError("NODE_NOT_FOUND", `Assigned node ${task.assignedTo} not found`, 404);
|
|
33723
|
-
}
|
|
33724
|
-
const canPushToNode = heartbeat?.canPushToNode?.(task.assignedTo) ?? true;
|
|
33725
|
-
if (!canPushToNode && heartbeat?.requestWorkerControl) {
|
|
33726
|
-
log.debug("skipping direct preview proxy because worker is keepalive-only", {
|
|
33727
|
-
taskId,
|
|
33728
|
-
assignedTo: task.assignedTo
|
|
33729
|
-
});
|
|
33730
|
-
const controlResponse = await heartbeat.requestWorkerControl(task.assignedTo, {
|
|
33731
|
-
kind: "task-preview-session",
|
|
33732
|
-
taskId,
|
|
33733
|
-
path: body.path
|
|
33734
|
-
});
|
|
33735
|
-
sendWorkerControlResponse(res, controlResponse);
|
|
33736
|
-
return;
|
|
33737
|
-
}
|
|
33738
|
-
try {
|
|
33739
|
-
const { endpoint, response: proxyRes } = await fetchNodeWithFallback(node, "/api/worker/preview-session", {
|
|
33740
|
-
method: "POST",
|
|
33741
|
-
headers: { "Content-Type": "application/json" },
|
|
33742
|
-
body: JSON.stringify({ taskId, path: body.path })
|
|
33743
|
-
});
|
|
33744
|
-
const workerEndpoint = endpoint;
|
|
33745
|
-
log.debug("proxying preview session request to worker", { taskId, workerEndpoint });
|
|
33746
|
-
await sendProxyResponse(res, proxyRes);
|
|
33747
|
-
return;
|
|
33748
|
-
} catch (err) {
|
|
33749
|
-
if (heartbeat?.requestWorkerControl) {
|
|
33750
|
-
log.warn("direct preview proxy failed, falling back to keepalive control", {
|
|
33751
|
-
taskId,
|
|
33752
|
-
assignedTo: task.assignedTo,
|
|
33753
|
-
error: err instanceof Error ? err.message : String(err)
|
|
33754
|
-
});
|
|
33755
|
-
try {
|
|
33756
|
-
const controlResponse = await heartbeat.requestWorkerControl(task.assignedTo, {
|
|
33757
|
-
kind: "task-preview-session",
|
|
33758
|
-
taskId,
|
|
33759
|
-
path: body.path
|
|
33760
|
-
});
|
|
33761
|
-
sendWorkerControlResponse(res, controlResponse);
|
|
33762
|
-
return;
|
|
33763
|
-
} catch (fallbackErr) {
|
|
33764
|
-
log.warn("keepalive preview fallback failed", {
|
|
33765
|
-
taskId,
|
|
33766
|
-
assignedTo: task.assignedTo,
|
|
33767
|
-
error: fallbackErr instanceof Error ? fallbackErr.message : String(fallbackErr)
|
|
33768
|
-
});
|
|
33769
|
-
}
|
|
33770
|
-
}
|
|
33771
|
-
log.warn("preview session proxy error", { error: err instanceof Error ? err.message : String(err) });
|
|
33772
|
-
throw new MeshyError("NODE_OFFLINE", "Cannot reach worker for preview session", 502);
|
|
33773
|
-
}
|
|
33774
|
-
}
|
|
33775
|
-
res.json(await createPreviewSessionPayload(req.app.locals.deps, taskId, body.path));
|
|
33776
|
-
}));
|
|
33745
|
+
router.use(createTaskOutputRoutes());
|
|
33777
33746
|
return router;
|
|
33778
33747
|
}
|
|
33779
33748
|
|
|
33780
33749
|
// ../../packages/api/src/routes/worker.ts
|
|
33781
|
-
var
|
|
33750
|
+
var import_express5 = __toESM(require_express2(), 1);
|
|
33782
33751
|
var WorkerMessageBody = external_exports.object({
|
|
33783
33752
|
taskId: external_exports.string().min(1)
|
|
33784
33753
|
}).and(SendMessageBody);
|
|
33785
33754
|
var WorkerTaskBody = external_exports.object({
|
|
33786
33755
|
taskId: external_exports.string().min(1)
|
|
33787
33756
|
});
|
|
33788
|
-
function
|
|
33757
|
+
function asyncHandler5(fn) {
|
|
33789
33758
|
return (req, res, next) => fn(req, res, next).catch(next);
|
|
33790
33759
|
}
|
|
33791
33760
|
function createWorkerRoutes() {
|
|
33792
|
-
const router = (0,
|
|
33793
|
-
router.post("/execute",
|
|
33761
|
+
const router = (0, import_express5.Router)();
|
|
33762
|
+
router.post("/execute", asyncHandler5(async (req, res) => {
|
|
33794
33763
|
const { taskEngine, engineRegistry, nodeRegistry, eventBus, logger: rootLogger, workDir } = req.app.locals.deps;
|
|
33795
33764
|
const log = rootLogger.child("worker/execute");
|
|
33796
33765
|
const task = req.body;
|
|
@@ -33863,7 +33832,7 @@ function createWorkerRoutes() {
|
|
|
33863
33832
|
}
|
|
33864
33833
|
}
|
|
33865
33834
|
}));
|
|
33866
|
-
router.post("/message",
|
|
33835
|
+
router.post("/message", asyncHandler5(async (req, res) => {
|
|
33867
33836
|
const { engineRegistry, taskEngine, nodeRegistry, eventBus, logger: rootLogger } = req.app.locals.deps;
|
|
33868
33837
|
const log = rootLogger.child("worker/message");
|
|
33869
33838
|
const body = WorkerMessageBody.parse(req.body);
|
|
@@ -33906,7 +33875,7 @@ function createWorkerRoutes() {
|
|
|
33906
33875
|
}
|
|
33907
33876
|
res.json({ ok: true });
|
|
33908
33877
|
}));
|
|
33909
|
-
router.post("/cancel",
|
|
33878
|
+
router.post("/cancel", asyncHandler5(async (req, res) => {
|
|
33910
33879
|
const { taskEngine, engineRegistry, logger: rootLogger } = req.app.locals.deps;
|
|
33911
33880
|
const log = rootLogger.child("worker/cancel");
|
|
33912
33881
|
const body = WorkerTaskBody.parse(req.body);
|
|
@@ -33926,7 +33895,7 @@ function createWorkerRoutes() {
|
|
|
33926
33895
|
terminal: result.terminal
|
|
33927
33896
|
});
|
|
33928
33897
|
}));
|
|
33929
|
-
router.post("/output",
|
|
33898
|
+
router.post("/output", asyncHandler5(async (req, res) => {
|
|
33930
33899
|
const { eventBus, engineRegistry, taskEngine, logger: rootLogger } = req.app.locals.deps;
|
|
33931
33900
|
const log = rootLogger.child("worker/output");
|
|
33932
33901
|
const { taskId, event } = req.body;
|
|
@@ -33941,7 +33910,7 @@ function createWorkerRoutes() {
|
|
|
33941
33910
|
}
|
|
33942
33911
|
res.json({ ok: true });
|
|
33943
33912
|
}));
|
|
33944
|
-
router.post("/heartbeat",
|
|
33913
|
+
router.post("/heartbeat", asyncHandler5(async (req, res) => {
|
|
33945
33914
|
const { heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
33946
33915
|
const log = rootLogger.child("worker/heartbeat");
|
|
33947
33916
|
const body = req.body;
|
|
@@ -33958,7 +33927,7 @@ function createWorkerRoutes() {
|
|
|
33958
33927
|
});
|
|
33959
33928
|
res.json(response);
|
|
33960
33929
|
}));
|
|
33961
|
-
router.post("/keepalive",
|
|
33930
|
+
router.post("/keepalive", asyncHandler5(async (req, res) => {
|
|
33962
33931
|
const { heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
33963
33932
|
const log = rootLogger.child("worker/keepalive");
|
|
33964
33933
|
const body = req.body;
|
|
@@ -33978,17 +33947,17 @@ function createWorkerRoutes() {
|
|
|
33978
33947
|
});
|
|
33979
33948
|
res.json(response);
|
|
33980
33949
|
}));
|
|
33981
|
-
router.post("/vote",
|
|
33950
|
+
router.post("/vote", asyncHandler5(async (req, res) => {
|
|
33982
33951
|
const { election } = req.app.locals.deps;
|
|
33983
33952
|
const response = election.handleVoteRequest(req.body);
|
|
33984
33953
|
res.json(response);
|
|
33985
33954
|
}));
|
|
33986
|
-
router.post("/announce",
|
|
33955
|
+
router.post("/announce", asyncHandler5(async (req, res) => {
|
|
33987
33956
|
const { election } = req.app.locals.deps;
|
|
33988
33957
|
election.handleLeaderAnnounce(req.body);
|
|
33989
33958
|
res.json({ ok: true });
|
|
33990
33959
|
}));
|
|
33991
|
-
router.post("/preview-session",
|
|
33960
|
+
router.post("/preview-session", asyncHandler5(async (req, res) => {
|
|
33992
33961
|
const { logger: rootLogger } = req.app.locals.deps;
|
|
33993
33962
|
const log = rootLogger.child("worker/preview-session");
|
|
33994
33963
|
const body = TaskPreviewSessionBody.extend({
|
|
@@ -33998,7 +33967,7 @@ function createWorkerRoutes() {
|
|
|
33998
33967
|
log.info("created preview session", { taskId: body.taskId, entryPath: payload.entryPath });
|
|
33999
33968
|
res.json(payload);
|
|
34000
33969
|
}));
|
|
34001
|
-
router.post("/control-response",
|
|
33970
|
+
router.post("/control-response", asyncHandler5(async (req, res) => {
|
|
34002
33971
|
const { heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
34003
33972
|
const log = rootLogger.child("worker/control-response");
|
|
34004
33973
|
const body = req.body;
|
|
@@ -34018,13 +33987,13 @@ function createWorkerRoutes() {
|
|
|
34018
33987
|
}
|
|
34019
33988
|
|
|
34020
33989
|
// ../../packages/api/src/routes/system.ts
|
|
34021
|
-
var
|
|
34022
|
-
function
|
|
33990
|
+
var import_express6 = __toESM(require_express2(), 1);
|
|
33991
|
+
function asyncHandler6(fn) {
|
|
34023
33992
|
return (req, res, next) => fn(req, res, next).catch(next);
|
|
34024
33993
|
}
|
|
34025
33994
|
function createSystemRoutes() {
|
|
34026
|
-
const router = (0,
|
|
34027
|
-
router.get("/health",
|
|
33995
|
+
const router = (0, import_express6.Router)();
|
|
33996
|
+
router.get("/health", asyncHandler6(async (req, res) => {
|
|
34028
33997
|
const { logger: rootLogger } = req.app.locals.deps;
|
|
34029
33998
|
rootLogger.child("system/health").info("received system health API call", {
|
|
34030
33999
|
method: req.method,
|
|
@@ -34033,7 +34002,7 @@ function createSystemRoutes() {
|
|
|
34033
34002
|
});
|
|
34034
34003
|
res.json({ status: "ok", timestamp: Date.now() });
|
|
34035
34004
|
}));
|
|
34036
|
-
router.get("/info",
|
|
34005
|
+
router.get("/info", asyncHandler6(async (req, res) => {
|
|
34037
34006
|
const { nodeRegistry, getTransportType, config, dashboardOrigin } = req.app.locals.deps;
|
|
34038
34007
|
const self = nodeRegistry.getSelf();
|
|
34039
34008
|
res.json({
|
|
@@ -34049,7 +34018,7 @@ function createSystemRoutes() {
|
|
|
34049
34018
|
}
|
|
34050
34019
|
});
|
|
34051
34020
|
}));
|
|
34052
|
-
router.post("/transport",
|
|
34021
|
+
router.post("/transport", asyncHandler6(async (req, res) => {
|
|
34053
34022
|
const { switchTransport } = req.app.locals.deps;
|
|
34054
34023
|
if (!switchTransport) {
|
|
34055
34024
|
res.status(501).json({ error: "Transport switching not available" });
|
|
@@ -34063,7 +34032,7 @@ function createSystemRoutes() {
|
|
|
34063
34032
|
const newEndpoint = await switchTransport(type);
|
|
34064
34033
|
res.json({ ok: true, transportType: type, endpoint: newEndpoint });
|
|
34065
34034
|
}));
|
|
34066
|
-
router.post("/devtunnel",
|
|
34035
|
+
router.post("/devtunnel", asyncHandler6(async (req, res) => {
|
|
34067
34036
|
const { enableDevTunnel, disableDevTunnel, nodeRegistry, taskEngine } = req.app.locals.deps;
|
|
34068
34037
|
if (!enableDevTunnel || !disableDevTunnel) {
|
|
34069
34038
|
res.status(501).json({ error: "DevTunnel control not available" });
|
|
@@ -34092,7 +34061,7 @@ function createSystemRoutes() {
|
|
|
34092
34061
|
});
|
|
34093
34062
|
}
|
|
34094
34063
|
}));
|
|
34095
|
-
router.get("/metrics",
|
|
34064
|
+
router.get("/metrics", asyncHandler6(async (req, res) => {
|
|
34096
34065
|
const { taskEngine } = req.app.locals.deps;
|
|
34097
34066
|
const metrics = taskEngine.getMetrics();
|
|
34098
34067
|
res.json(metrics);
|
|
@@ -34101,7 +34070,7 @@ function createSystemRoutes() {
|
|
|
34101
34070
|
}
|
|
34102
34071
|
|
|
34103
34072
|
// ../../packages/api/src/routes/events.ts
|
|
34104
|
-
var
|
|
34073
|
+
var import_express7 = __toESM(require_express2(), 1);
|
|
34105
34074
|
var HEARTBEAT_INTERVAL_MS = 15e3;
|
|
34106
34075
|
var CATEGORY_MAP = {
|
|
34107
34076
|
tasks: "task.",
|
|
@@ -34136,7 +34105,7 @@ function shouldIncludeEvent(eventName, categories) {
|
|
|
34136
34105
|
});
|
|
34137
34106
|
}
|
|
34138
34107
|
function createEventRoutes() {
|
|
34139
|
-
const router = (0,
|
|
34108
|
+
const router = (0, import_express7.Router)();
|
|
34140
34109
|
router.get("/", (req, res) => {
|
|
34141
34110
|
const { eventBus } = req.app.locals.deps;
|
|
34142
34111
|
const categories = parseFilter(req.query.filter);
|
|
@@ -34187,8 +34156,8 @@ var JSON_BODY_LIMIT_LARGE = "25mb";
|
|
|
34187
34156
|
function resolveRuntimeBaseDir() {
|
|
34188
34157
|
const entryPath = process.argv[1];
|
|
34189
34158
|
if (typeof entryPath === "string" && entryPath.length > 0) {
|
|
34190
|
-
const resolved =
|
|
34191
|
-
return
|
|
34159
|
+
const resolved = fs14.realpathSync(path14.resolve(entryPath));
|
|
34160
|
+
return path14.dirname(resolved);
|
|
34192
34161
|
}
|
|
34193
34162
|
return process.cwd();
|
|
34194
34163
|
}
|
|
@@ -34196,25 +34165,25 @@ function resolveStaticDir(baseDir) {
|
|
|
34196
34165
|
const envStaticDir = process.env.MESHY_STATIC_DIR;
|
|
34197
34166
|
const candidateDirs = [
|
|
34198
34167
|
envStaticDir,
|
|
34199
|
-
|
|
34200
|
-
|
|
34201
|
-
|
|
34202
|
-
|
|
34203
|
-
|
|
34204
|
-
|
|
34205
|
-
|
|
34206
|
-
|
|
34207
|
-
|
|
34168
|
+
path14.resolve(baseDir, "dashboard"),
|
|
34169
|
+
path14.resolve(baseDir, "../dashboard"),
|
|
34170
|
+
path14.resolve(baseDir, "../../dashboard/dist"),
|
|
34171
|
+
path14.resolve(baseDir, "../../../packages/dashboard/dist"),
|
|
34172
|
+
path14.resolve(baseDir, "../public"),
|
|
34173
|
+
path14.resolve(baseDir, "../../packages/api/public"),
|
|
34174
|
+
path14.resolve(baseDir, "../../../packages/api/public"),
|
|
34175
|
+
path14.resolve(process.cwd(), "packages/dashboard/dist"),
|
|
34176
|
+
path14.resolve(process.cwd(), "packages/api/public")
|
|
34208
34177
|
].filter((value) => typeof value === "string" && value.length > 0);
|
|
34209
34178
|
for (const candidate of candidateDirs) {
|
|
34210
|
-
if (
|
|
34179
|
+
if (fs14.existsSync(candidate)) {
|
|
34211
34180
|
return candidate;
|
|
34212
34181
|
}
|
|
34213
34182
|
}
|
|
34214
34183
|
return null;
|
|
34215
34184
|
}
|
|
34216
34185
|
function createServer2(deps) {
|
|
34217
|
-
const app = (0,
|
|
34186
|
+
const app = (0, import_express8.default)();
|
|
34218
34187
|
app.locals.deps = deps;
|
|
34219
34188
|
if (typeof deps.heartbeat.setControlRequestHandler === "function") {
|
|
34220
34189
|
deps.heartbeat.setControlRequestHandler((request) => executeWorkerControlRequest(deps, request));
|
|
@@ -34238,7 +34207,7 @@ function createServer2(deps) {
|
|
|
34238
34207
|
const runtimeBaseDir = resolveRuntimeBaseDir();
|
|
34239
34208
|
const staticDir = resolveStaticDir(runtimeBaseDir);
|
|
34240
34209
|
if (staticDir) {
|
|
34241
|
-
const staticMiddleware =
|
|
34210
|
+
const staticMiddleware = import_express8.default.static(staticDir);
|
|
34242
34211
|
app.use((req, res, next) => {
|
|
34243
34212
|
if (isApiRequest(req)) {
|
|
34244
34213
|
next();
|
|
@@ -34251,10 +34220,10 @@ function createServer2(deps) {
|
|
|
34251
34220
|
staticMiddleware(req, res, next);
|
|
34252
34221
|
});
|
|
34253
34222
|
}
|
|
34254
|
-
app.use(
|
|
34223
|
+
app.use(import_express8.default.json({ limit: JSON_BODY_LIMIT }));
|
|
34255
34224
|
app.use(createAuthMiddleware(authConfig));
|
|
34256
34225
|
app.use(createRoutingMiddleware(deps.dataRouter));
|
|
34257
|
-
const largeBodyParser =
|
|
34226
|
+
const largeBodyParser = import_express8.default.json({ limit: JSON_BODY_LIMIT_LARGE });
|
|
34258
34227
|
app.use("/api/cluster", createClusterRoutes());
|
|
34259
34228
|
app.use("/api/nodes", createNodeRoutes());
|
|
34260
34229
|
app.use("/api/tasks", largeBodyParser, createTaskRoutes());
|
|
@@ -34262,8 +34231,8 @@ function createServer2(deps) {
|
|
|
34262
34231
|
app.use("/api/system", createSystemRoutes());
|
|
34263
34232
|
app.use("/api/events", createEventRoutes());
|
|
34264
34233
|
if (staticDir) {
|
|
34265
|
-
const indexPath =
|
|
34266
|
-
if (
|
|
34234
|
+
const indexPath = path14.join(staticDir, "index.html");
|
|
34235
|
+
if (fs14.existsSync(indexPath)) {
|
|
34267
34236
|
app.get("*", (req, res, next) => {
|
|
34268
34237
|
if (isApiRequest(req)) {
|
|
34269
34238
|
next();
|
|
@@ -34281,6 +34250,34 @@ function createServer2(deps) {
|
|
|
34281
34250
|
return app;
|
|
34282
34251
|
}
|
|
34283
34252
|
|
|
34253
|
+
// ../../packages/api/src/output-server.ts
|
|
34254
|
+
var import_express9 = __toESM(require_express2(), 1);
|
|
34255
|
+
var JSON_BODY_LIMIT_LARGE2 = "25mb";
|
|
34256
|
+
function createOutputServer(deps) {
|
|
34257
|
+
if (!deps.previewSessionManager) {
|
|
34258
|
+
throw new Error("Preview session manager is required for the output server");
|
|
34259
|
+
}
|
|
34260
|
+
const app = (0, import_express9.default)();
|
|
34261
|
+
app.locals.deps = deps;
|
|
34262
|
+
app.use((req, res, next) => {
|
|
34263
|
+
if (handlePreviewRequest(deps.previewSessionManager, req, res)) {
|
|
34264
|
+
return;
|
|
34265
|
+
}
|
|
34266
|
+
next();
|
|
34267
|
+
});
|
|
34268
|
+
const authConfig = {
|
|
34269
|
+
apiKey: deps.config.apiKey,
|
|
34270
|
+
validateBearerToken: deps.config.validateBearerToken,
|
|
34271
|
+
allowTrustedHostBypass: false
|
|
34272
|
+
};
|
|
34273
|
+
const largeBodyParser = import_express9.default.json({ limit: JSON_BODY_LIMIT_LARGE2 });
|
|
34274
|
+
app.use("/api/tasks", largeBodyParser, createAuthMiddleware(authConfig), createTaskOutputRoutes({
|
|
34275
|
+
allowRemoteProxy: false
|
|
34276
|
+
}));
|
|
34277
|
+
app.use(createErrorMiddleware());
|
|
34278
|
+
return app;
|
|
34279
|
+
}
|
|
34280
|
+
|
|
34284
34281
|
// ../../packages/transport/src/direct.ts
|
|
34285
34282
|
var import_node_os = require("os");
|
|
34286
34283
|
var import_node_http = require("http");
|
|
@@ -34591,8 +34588,8 @@ function createTransport(config) {
|
|
|
34591
34588
|
}
|
|
34592
34589
|
|
|
34593
34590
|
// src/startup.ts
|
|
34594
|
-
var
|
|
34595
|
-
var
|
|
34591
|
+
var fs15 = __toESM(require("fs"), 1);
|
|
34592
|
+
var path15 = __toESM(require("path"), 1);
|
|
34596
34593
|
var readline = __toESM(require("readline/promises"), 1);
|
|
34597
34594
|
var import_node_child_process6 = require("child_process");
|
|
34598
34595
|
function getDefaultNodeName() {
|
|
@@ -34656,19 +34653,19 @@ function createDefaultCommandRunner(platform) {
|
|
|
34656
34653
|
};
|
|
34657
34654
|
}
|
|
34658
34655
|
function getNodeMetadataPath2(storagePath) {
|
|
34659
|
-
return
|
|
34656
|
+
return path15.join(storagePath, "metadata.json");
|
|
34660
34657
|
}
|
|
34661
34658
|
function readStartupMetadataFile(storagePath) {
|
|
34662
34659
|
try {
|
|
34663
|
-
const raw = JSON.parse(
|
|
34660
|
+
const raw = JSON.parse(fs15.readFileSync(getNodeMetadataPath2(storagePath), "utf-8"));
|
|
34664
34661
|
return typeof raw === "object" && raw !== null ? raw : {};
|
|
34665
34662
|
} catch {
|
|
34666
34663
|
return {};
|
|
34667
34664
|
}
|
|
34668
34665
|
}
|
|
34669
34666
|
function writeStartupMetadataFile(storagePath, metadata) {
|
|
34670
|
-
|
|
34671
|
-
|
|
34667
|
+
fs15.mkdirSync(storagePath, { recursive: true });
|
|
34668
|
+
fs15.writeFileSync(getNodeMetadataPath2(storagePath), JSON.stringify(metadata, null, 2) + "\n", "utf-8");
|
|
34672
34669
|
}
|
|
34673
34670
|
function formatLocalDate(now) {
|
|
34674
34671
|
const year = now.getFullYear();
|
|
@@ -34913,9 +34910,9 @@ function parseArgs(argv) {
|
|
|
34913
34910
|
}
|
|
34914
34911
|
return result;
|
|
34915
34912
|
}
|
|
34916
|
-
function loadConfigFile(
|
|
34913
|
+
function loadConfigFile(path16) {
|
|
34917
34914
|
try {
|
|
34918
|
-
const raw =
|
|
34915
|
+
const raw = fs15.readFileSync(path16, "utf-8");
|
|
34919
34916
|
return JSON.parse(raw);
|
|
34920
34917
|
} catch {
|
|
34921
34918
|
return {};
|
|
@@ -35164,14 +35161,35 @@ async function main() {
|
|
|
35164
35161
|
});
|
|
35165
35162
|
await meshyNode.start();
|
|
35166
35163
|
const previewSessionManager = new PreviewSessionManager();
|
|
35167
|
-
const previewServer = new PreviewServer(previewSessionManager);
|
|
35168
35164
|
const previewPort = config.node.port + 1;
|
|
35169
|
-
|
|
35165
|
+
let actualPreviewPort = previewPort;
|
|
35170
35166
|
let dashboardTransport = null;
|
|
35171
35167
|
let dashboardOrigin;
|
|
35172
35168
|
let previewTransport = null;
|
|
35173
35169
|
let previewOrigin;
|
|
35170
|
+
let outputServer = null;
|
|
35174
35171
|
let deps;
|
|
35172
|
+
async function listen(app2, port) {
|
|
35173
|
+
return new Promise((resolve10, reject) => {
|
|
35174
|
+
const server2 = http2.createServer(app2);
|
|
35175
|
+
server2.listen(port, () => resolve10(server2));
|
|
35176
|
+
server2.on("error", reject);
|
|
35177
|
+
});
|
|
35178
|
+
}
|
|
35179
|
+
async function closeServer(server2) {
|
|
35180
|
+
if (!server2) {
|
|
35181
|
+
return;
|
|
35182
|
+
}
|
|
35183
|
+
await new Promise((resolve10, reject) => {
|
|
35184
|
+
server2.close((err) => {
|
|
35185
|
+
if (err) {
|
|
35186
|
+
reject(err);
|
|
35187
|
+
return;
|
|
35188
|
+
}
|
|
35189
|
+
resolve10();
|
|
35190
|
+
});
|
|
35191
|
+
});
|
|
35192
|
+
}
|
|
35175
35193
|
function createDashboardTransportConfig() {
|
|
35176
35194
|
return {
|
|
35177
35195
|
type: "devtunnel",
|
|
@@ -35294,6 +35312,10 @@ async function main() {
|
|
|
35294
35312
|
const nextOrigin = await nextTransport.getEndpoint();
|
|
35295
35313
|
previewTransport = nextTransport;
|
|
35296
35314
|
setAdvertisedPreviewOrigin(nextOrigin);
|
|
35315
|
+
meshyNode.getLogger().info("started output preview tunnel", {
|
|
35316
|
+
previewOrigin: nextOrigin,
|
|
35317
|
+
previewPort: actualPreviewPort
|
|
35318
|
+
});
|
|
35297
35319
|
if (previousTransport) {
|
|
35298
35320
|
await previousTransport.stop().catch(() => void 0);
|
|
35299
35321
|
}
|
|
@@ -35372,6 +35394,11 @@ async function main() {
|
|
|
35372
35394
|
deps.previewPort = actualPreviewPort;
|
|
35373
35395
|
deps.dashboardOrigin = dashboardOrigin;
|
|
35374
35396
|
deps.previewOrigin = previewOrigin;
|
|
35397
|
+
const outputApp = createOutputServer(deps);
|
|
35398
|
+
outputServer = await listen(outputApp, previewPort);
|
|
35399
|
+
const outputAddress = outputServer.address();
|
|
35400
|
+
actualPreviewPort = typeof outputAddress === "object" && outputAddress ? outputAddress.port : previewPort;
|
|
35401
|
+
deps.previewPort = actualPreviewPort;
|
|
35375
35402
|
meshyNode.getLogger().info("configured node auth mode", {
|
|
35376
35403
|
authEnabled: authMetadata.enabled,
|
|
35377
35404
|
allowSameTenant: authMetadata.allowSameTenant,
|
|
@@ -35379,6 +35406,7 @@ async function main() {
|
|
|
35379
35406
|
mainTransportType: meshyNode.getTransportType(),
|
|
35380
35407
|
sidecarEnabled: meshyNode.isDevTunnelEnabled()
|
|
35381
35408
|
});
|
|
35409
|
+
await restartPreviewTransport(createPreviewTransportConfig());
|
|
35382
35410
|
await syncDashboardTransport("startup");
|
|
35383
35411
|
const previewHealthTimer = setInterval(() => {
|
|
35384
35412
|
void (async () => {
|
|
@@ -35391,6 +35419,7 @@ async function main() {
|
|
|
35391
35419
|
meshyNode.getLogger().warn("preview transport became unhealthy and was cleared", {
|
|
35392
35420
|
previewPort: actualPreviewPort
|
|
35393
35421
|
});
|
|
35422
|
+
await restartPreviewTransport(createPreviewTransportConfig());
|
|
35394
35423
|
})();
|
|
35395
35424
|
}, config.cluster.heartbeatInterval);
|
|
35396
35425
|
const dashboardHealthTimer = setInterval(() => {
|
|
@@ -35437,9 +35466,9 @@ async function main() {
|
|
|
35437
35466
|
if (previewTransport) {
|
|
35438
35467
|
await previewTransport.stop();
|
|
35439
35468
|
}
|
|
35440
|
-
await
|
|
35469
|
+
await closeServer(outputServer);
|
|
35441
35470
|
await meshyNode.stop();
|
|
35442
|
-
server
|
|
35471
|
+
await closeServer(server);
|
|
35443
35472
|
console.log("Goodbye!");
|
|
35444
35473
|
process.exit(0);
|
|
35445
35474
|
} catch (err) {
|