tandem-editor 0.6.3 → 0.7.0
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/CHANGELOG.md +389 -32
- package/dist/channel/index.js +41 -7
- package/dist/channel/index.js.map +1 -1
- package/dist/cli/index.js +334 -36
- package/dist/cli/index.js.map +1 -1
- package/dist/monitor/index.js +23 -2
- package/dist/monitor/index.js.map +1 -1
- package/dist/server/index.js +787 -392
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/server/index.js
CHANGED
|
@@ -40,7 +40,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
40
40
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
41
41
|
|
|
42
42
|
// src/shared/constants.ts
|
|
43
|
-
var DEFAULT_WS_PORT, DEFAULT_MCP_PORT, SUPPORTED_EXTENSIONS, MAX_FILE_SIZE, MAX_WS_PAYLOAD, IDLE_TIMEOUT, SESSION_MAX_AGE, TANDEM_MODE_DEFAULT, SELECTION_DWELL_DEFAULT_MS, SELECTION_DWELL_MIN_MS, SELECTION_DWELL_MAX_MS, CHARS_PER_PAGE, LARGE_FILE_PAGE_THRESHOLD, VERY_LARGE_FILE_PAGE_THRESHOLD, CTRL_ROOM, Y_MAP_ANNOTATIONS, Y_MAP_AWARENESS, Y_MAP_USER_AWARENESS, Y_MAP_MODE, Y_MAP_DWELL_MS, Y_MAP_CHAT, Y_MAP_DOCUMENT_META, Y_MAP_ANNOTATION_REPLIES, Y_MAP_SAVED_AT_VERSION, Y_MAP_AUTHORSHIP, NOTIFICATION_BUFFER_SIZE, TUTORIAL_ANNOTATION_PREFIX, CHANNEL_EVENT_BUFFER_SIZE, CHANNEL_EVENT_BUFFER_AGE_MS, CHANNEL_SSE_KEEPALIVE_MS, TAURI_HOSTNAME;
|
|
43
|
+
var DEFAULT_WS_PORT, DEFAULT_MCP_PORT, SUPPORTED_EXTENSIONS, MAX_FILE_SIZE, MAX_WS_PAYLOAD, IDLE_TIMEOUT, SESSION_MAX_AGE, TANDEM_MODE_DEFAULT, SELECTION_DWELL_DEFAULT_MS, SELECTION_DWELL_MIN_MS, SELECTION_DWELL_MAX_MS, CHARS_PER_PAGE, LARGE_FILE_PAGE_THRESHOLD, VERY_LARGE_FILE_PAGE_THRESHOLD, CTRL_ROOM, Y_MAP_ANNOTATIONS, Y_MAP_AWARENESS, Y_MAP_USER_AWARENESS, Y_MAP_MODE, Y_MAP_DWELL_MS, Y_MAP_CHAT, Y_MAP_DOCUMENT_META, Y_MAP_ANNOTATION_REPLIES, Y_MAP_SAVED_AT_VERSION, Y_MAP_AUTHORSHIP, NOTIFICATION_BUFFER_SIZE, TUTORIAL_ANNOTATION_PREFIX, CHANNEL_EVENT_BUFFER_SIZE, CHANNEL_EVENT_BUFFER_AGE_MS, CHANNEL_SSE_KEEPALIVE_MS, TOKEN_FILE_NAME, DEFAULT_BIND_HOST, TANDEM_ALLOW_UNAUTHENTICATED_LAN_ENV, TAURI_HOSTNAME;
|
|
44
44
|
var init_constants = __esm({
|
|
45
45
|
"src/shared/constants.ts"() {
|
|
46
46
|
"use strict";
|
|
@@ -74,6 +74,9 @@ var init_constants = __esm({
|
|
|
74
74
|
CHANNEL_EVENT_BUFFER_SIZE = 200;
|
|
75
75
|
CHANNEL_EVENT_BUFFER_AGE_MS = 6e4;
|
|
76
76
|
CHANNEL_SSE_KEEPALIVE_MS = 15e3;
|
|
77
|
+
TOKEN_FILE_NAME = "auth-token";
|
|
78
|
+
DEFAULT_BIND_HOST = "127.0.0.1";
|
|
79
|
+
TANDEM_ALLOW_UNAUTHENTICATED_LAN_ENV = "TANDEM_ALLOW_UNAUTHENTICATED_LAN";
|
|
77
80
|
TAURI_HOSTNAME = "tauri.localhost";
|
|
78
81
|
}
|
|
79
82
|
});
|
|
@@ -1066,14 +1069,14 @@ var callAll, id, isOneOf;
|
|
|
1066
1069
|
var init_function = __esm({
|
|
1067
1070
|
"node_modules/lib0/function.js"() {
|
|
1068
1071
|
"use strict";
|
|
1069
|
-
callAll = (
|
|
1072
|
+
callAll = (fs11, args2, i = 0) => {
|
|
1070
1073
|
try {
|
|
1071
|
-
for (; i <
|
|
1072
|
-
|
|
1074
|
+
for (; i < fs11.length; i++) {
|
|
1075
|
+
fs11[i](...args2);
|
|
1073
1076
|
}
|
|
1074
1077
|
} finally {
|
|
1075
|
-
if (i <
|
|
1076
|
-
callAll(
|
|
1078
|
+
if (i < fs11.length) {
|
|
1079
|
+
callAll(fs11, args2, i + 1);
|
|
1077
1080
|
}
|
|
1078
1081
|
}
|
|
1079
1082
|
};
|
|
@@ -3098,15 +3101,15 @@ var init_yjs = __esm({
|
|
|
3098
3101
|
sortAndMergeDeleteSet(ds);
|
|
3099
3102
|
transaction.afterState = getStateVector(transaction.doc.store);
|
|
3100
3103
|
doc.emit("beforeObserverCalls", [transaction, doc]);
|
|
3101
|
-
const
|
|
3104
|
+
const fs11 = [];
|
|
3102
3105
|
transaction.changed.forEach(
|
|
3103
|
-
(subs, itemtype) =>
|
|
3106
|
+
(subs, itemtype) => fs11.push(() => {
|
|
3104
3107
|
if (itemtype._item === null || !itemtype._item.deleted) {
|
|
3105
3108
|
itemtype._callObserver(transaction, subs);
|
|
3106
3109
|
}
|
|
3107
3110
|
})
|
|
3108
3111
|
);
|
|
3109
|
-
|
|
3112
|
+
fs11.push(() => {
|
|
3110
3113
|
transaction.changedParentTypes.forEach((events, type2) => {
|
|
3111
3114
|
if (type2._dEH.l.length > 0 && (type2._item === null || !type2._item.deleted)) {
|
|
3112
3115
|
events = events.filter(
|
|
@@ -3117,19 +3120,19 @@ var init_yjs = __esm({
|
|
|
3117
3120
|
event._path = null;
|
|
3118
3121
|
});
|
|
3119
3122
|
events.sort((event1, event2) => event1.path.length - event2.path.length);
|
|
3120
|
-
|
|
3123
|
+
fs11.push(() => {
|
|
3121
3124
|
callEventHandlerListeners(type2._dEH, events, transaction);
|
|
3122
3125
|
});
|
|
3123
3126
|
}
|
|
3124
3127
|
});
|
|
3125
|
-
|
|
3126
|
-
|
|
3128
|
+
fs11.push(() => doc.emit("afterTransaction", [transaction, doc]));
|
|
3129
|
+
fs11.push(() => {
|
|
3127
3130
|
if (transaction._needFormattingCleanup) {
|
|
3128
3131
|
cleanupYTextAfterTransaction(transaction);
|
|
3129
3132
|
}
|
|
3130
3133
|
});
|
|
3131
3134
|
});
|
|
3132
|
-
callAll(
|
|
3135
|
+
callAll(fs11, []);
|
|
3133
3136
|
} finally {
|
|
3134
3137
|
if (doc.gc) {
|
|
3135
3138
|
tryGcDeleteSet(ds, store, doc.gcFilter);
|
|
@@ -3670,10 +3673,10 @@ var init_yjs = __esm({
|
|
|
3670
3673
|
}
|
|
3671
3674
|
};
|
|
3672
3675
|
getPathTo = (parent, child) => {
|
|
3673
|
-
const
|
|
3676
|
+
const path16 = [];
|
|
3674
3677
|
while (child._item !== null && child !== parent) {
|
|
3675
3678
|
if (child._item.parentSub !== null) {
|
|
3676
|
-
|
|
3679
|
+
path16.unshift(child._item.parentSub);
|
|
3677
3680
|
} else {
|
|
3678
3681
|
let i = 0;
|
|
3679
3682
|
let c = (
|
|
@@ -3686,12 +3689,12 @@ var init_yjs = __esm({
|
|
|
3686
3689
|
}
|
|
3687
3690
|
c = c.right;
|
|
3688
3691
|
}
|
|
3689
|
-
|
|
3692
|
+
path16.unshift(i);
|
|
3690
3693
|
}
|
|
3691
3694
|
child = /** @type {AbstractType<any>} */
|
|
3692
3695
|
child._item.parent;
|
|
3693
3696
|
}
|
|
3694
|
-
return
|
|
3697
|
+
return path16;
|
|
3695
3698
|
};
|
|
3696
3699
|
warnPrematureAccess = () => {
|
|
3697
3700
|
warn("Invalid access: Add Yjs type to a document before reading data.");
|
|
@@ -8459,7 +8462,7 @@ function transformGfmAutolinkLiterals(tree) {
|
|
|
8459
8462
|
{ ignore: ["link", "linkReference"] }
|
|
8460
8463
|
);
|
|
8461
8464
|
}
|
|
8462
|
-
function findUrl(_3, protocol, domain2,
|
|
8465
|
+
function findUrl(_3, protocol, domain2, path16, match) {
|
|
8463
8466
|
let prefix = "";
|
|
8464
8467
|
if (!previous(match)) {
|
|
8465
8468
|
return false;
|
|
@@ -8472,7 +8475,7 @@ function findUrl(_3, protocol, domain2, path15, match) {
|
|
|
8472
8475
|
if (!isCorrectDomain(domain2)) {
|
|
8473
8476
|
return false;
|
|
8474
8477
|
}
|
|
8475
|
-
const parts = splitUrl(domain2 +
|
|
8478
|
+
const parts = splitUrl(domain2 + path16);
|
|
8476
8479
|
if (!parts[0]) return false;
|
|
8477
8480
|
const result2 = {
|
|
8478
8481
|
type: "link",
|
|
@@ -20278,8 +20281,8 @@ function assertNonEmpty(part, name2) {
|
|
|
20278
20281
|
throw new Error("`" + name2 + "` cannot be empty");
|
|
20279
20282
|
}
|
|
20280
20283
|
}
|
|
20281
|
-
function assertPath(
|
|
20282
|
-
if (!
|
|
20284
|
+
function assertPath(path16, name2) {
|
|
20285
|
+
if (!path16) {
|
|
20283
20286
|
throw new Error("Setting `" + name2 + "` requires `path` to be set too");
|
|
20284
20287
|
}
|
|
20285
20288
|
}
|
|
@@ -20465,13 +20468,13 @@ var init_lib21 = __esm({
|
|
|
20465
20468
|
* @returns {undefined}
|
|
20466
20469
|
* Nothing.
|
|
20467
20470
|
*/
|
|
20468
|
-
set path(
|
|
20469
|
-
if (isUrl(
|
|
20470
|
-
|
|
20471
|
+
set path(path16) {
|
|
20472
|
+
if (isUrl(path16)) {
|
|
20473
|
+
path16 = fileURLToPath(path16);
|
|
20471
20474
|
}
|
|
20472
|
-
assertNonEmpty(
|
|
20473
|
-
if (this.path !==
|
|
20474
|
-
this.history.push(
|
|
20475
|
+
assertNonEmpty(path16, "path");
|
|
20476
|
+
if (this.path !== path16) {
|
|
20477
|
+
this.history.push(path16);
|
|
20475
20478
|
}
|
|
20476
20479
|
}
|
|
20477
20480
|
/**
|
|
@@ -22826,8 +22829,8 @@ var init_tap = __esm({
|
|
|
22826
22829
|
});
|
|
22827
22830
|
|
|
22828
22831
|
// node_modules/underscore/modules/toPath.js
|
|
22829
|
-
function toPath(
|
|
22830
|
-
return isArray_default(
|
|
22832
|
+
function toPath(path16) {
|
|
22833
|
+
return isArray_default(path16) ? path16 : [path16];
|
|
22831
22834
|
}
|
|
22832
22835
|
var init_toPath = __esm({
|
|
22833
22836
|
"node_modules/underscore/modules/toPath.js"() {
|
|
@@ -22839,8 +22842,8 @@ var init_toPath = __esm({
|
|
|
22839
22842
|
});
|
|
22840
22843
|
|
|
22841
22844
|
// node_modules/underscore/modules/_toPath.js
|
|
22842
|
-
function toPath2(
|
|
22843
|
-
return _.toPath(
|
|
22845
|
+
function toPath2(path16) {
|
|
22846
|
+
return _.toPath(path16);
|
|
22844
22847
|
}
|
|
22845
22848
|
var init_toPath2 = __esm({
|
|
22846
22849
|
"node_modules/underscore/modules/_toPath.js"() {
|
|
@@ -22851,11 +22854,11 @@ var init_toPath2 = __esm({
|
|
|
22851
22854
|
});
|
|
22852
22855
|
|
|
22853
22856
|
// node_modules/underscore/modules/_deepGet.js
|
|
22854
|
-
function deepGet(obj2,
|
|
22855
|
-
var length3 =
|
|
22857
|
+
function deepGet(obj2, path16) {
|
|
22858
|
+
var length3 = path16.length;
|
|
22856
22859
|
for (var i = 0; i < length3; i++) {
|
|
22857
22860
|
if (obj2 == null) return void 0;
|
|
22858
|
-
obj2 = obj2[
|
|
22861
|
+
obj2 = obj2[path16[i]];
|
|
22859
22862
|
}
|
|
22860
22863
|
return length3 ? obj2 : void 0;
|
|
22861
22864
|
}
|
|
@@ -22866,8 +22869,8 @@ var init_deepGet = __esm({
|
|
|
22866
22869
|
});
|
|
22867
22870
|
|
|
22868
22871
|
// node_modules/underscore/modules/get.js
|
|
22869
|
-
function get(object4,
|
|
22870
|
-
var value = deepGet(object4, toPath2(
|
|
22872
|
+
function get(object4, path16, defaultValue) {
|
|
22873
|
+
var value = deepGet(object4, toPath2(path16));
|
|
22871
22874
|
return isUndefined(value) ? defaultValue : value;
|
|
22872
22875
|
}
|
|
22873
22876
|
var init_get = __esm({
|
|
@@ -22880,11 +22883,11 @@ var init_get = __esm({
|
|
|
22880
22883
|
});
|
|
22881
22884
|
|
|
22882
22885
|
// node_modules/underscore/modules/has.js
|
|
22883
|
-
function has2(obj2,
|
|
22884
|
-
|
|
22885
|
-
var length3 =
|
|
22886
|
+
function has2(obj2, path16) {
|
|
22887
|
+
path16 = toPath2(path16);
|
|
22888
|
+
var length3 = path16.length;
|
|
22886
22889
|
for (var i = 0; i < length3; i++) {
|
|
22887
|
-
var key =
|
|
22890
|
+
var key = path16[i];
|
|
22888
22891
|
if (!has(obj2, key)) return false;
|
|
22889
22892
|
obj2 = obj2[key];
|
|
22890
22893
|
}
|
|
@@ -22924,10 +22927,10 @@ var init_matcher = __esm({
|
|
|
22924
22927
|
});
|
|
22925
22928
|
|
|
22926
22929
|
// node_modules/underscore/modules/property.js
|
|
22927
|
-
function property(
|
|
22928
|
-
|
|
22930
|
+
function property(path16) {
|
|
22931
|
+
path16 = toPath2(path16);
|
|
22929
22932
|
return function(obj2) {
|
|
22930
|
-
return deepGet(obj2,
|
|
22933
|
+
return deepGet(obj2, path16);
|
|
22931
22934
|
};
|
|
22932
22935
|
}
|
|
22933
22936
|
var init_property = __esm({
|
|
@@ -23043,8 +23046,8 @@ var init_noop = __esm({
|
|
|
23043
23046
|
// node_modules/underscore/modules/propertyOf.js
|
|
23044
23047
|
function propertyOf(obj2) {
|
|
23045
23048
|
if (obj2 == null) return noop;
|
|
23046
|
-
return function(
|
|
23047
|
-
return get(obj2,
|
|
23049
|
+
return function(path16) {
|
|
23050
|
+
return get(obj2, path16);
|
|
23048
23051
|
};
|
|
23049
23052
|
}
|
|
23050
23053
|
var init_propertyOf = __esm({
|
|
@@ -23249,14 +23252,14 @@ var init_template = __esm({
|
|
|
23249
23252
|
});
|
|
23250
23253
|
|
|
23251
23254
|
// node_modules/underscore/modules/result.js
|
|
23252
|
-
function result(obj2,
|
|
23253
|
-
|
|
23254
|
-
var length3 =
|
|
23255
|
+
function result(obj2, path16, fallback) {
|
|
23256
|
+
path16 = toPath2(path16);
|
|
23257
|
+
var length3 = path16.length;
|
|
23255
23258
|
if (!length3) {
|
|
23256
23259
|
return isFunction_default(fallback) ? fallback.call(obj2) : fallback;
|
|
23257
23260
|
}
|
|
23258
23261
|
for (var i = 0; i < length3; i++) {
|
|
23259
|
-
var prop = obj2 == null ? void 0 : obj2[
|
|
23262
|
+
var prop = obj2 == null ? void 0 : obj2[path16[i]];
|
|
23260
23263
|
if (prop === void 0) {
|
|
23261
23264
|
prop = fallback;
|
|
23262
23265
|
i = length3;
|
|
@@ -23980,14 +23983,14 @@ var init_invoke = __esm({
|
|
|
23980
23983
|
init_map2();
|
|
23981
23984
|
init_deepGet();
|
|
23982
23985
|
init_toPath2();
|
|
23983
|
-
invoke_default = restArguments(function(obj2,
|
|
23986
|
+
invoke_default = restArguments(function(obj2, path16, args2) {
|
|
23984
23987
|
var contextPath, func;
|
|
23985
|
-
if (isFunction_default(
|
|
23986
|
-
func =
|
|
23988
|
+
if (isFunction_default(path16)) {
|
|
23989
|
+
func = path16;
|
|
23987
23990
|
} else {
|
|
23988
|
-
|
|
23989
|
-
contextPath =
|
|
23990
|
-
|
|
23991
|
+
path16 = toPath2(path16);
|
|
23992
|
+
contextPath = path16.slice(0, -1);
|
|
23993
|
+
path16 = path16[path16.length - 1];
|
|
23991
23994
|
}
|
|
23992
23995
|
return map4(obj2, function(context) {
|
|
23993
23996
|
var method = func;
|
|
@@ -23996,7 +23999,7 @@ var init_invoke = __esm({
|
|
|
23996
23999
|
context = deepGet(context, contextPath);
|
|
23997
24000
|
}
|
|
23998
24001
|
if (context == null) return void 0;
|
|
23999
|
-
method = context[
|
|
24002
|
+
method = context[path16];
|
|
24000
24003
|
}
|
|
24001
24004
|
return method == null ? method : method.apply(context, args2);
|
|
24002
24005
|
});
|
|
@@ -33514,8 +33517,8 @@ var require_utils = __commonJS({
|
|
|
33514
33517
|
var result2 = transform2[inputType][outputType](input);
|
|
33515
33518
|
return result2;
|
|
33516
33519
|
};
|
|
33517
|
-
exports3.resolve = function(
|
|
33518
|
-
var parts =
|
|
33520
|
+
exports3.resolve = function(path16) {
|
|
33521
|
+
var parts = path16.split("/");
|
|
33519
33522
|
var result2 = [];
|
|
33520
33523
|
for (var index2 = 0; index2 < parts.length; index2++) {
|
|
33521
33524
|
var part = parts[index2];
|
|
@@ -39368,18 +39371,18 @@ var require_object = __commonJS({
|
|
|
39368
39371
|
var object4 = new ZipObject(name2, zipObjectContent, o);
|
|
39369
39372
|
this.files[name2] = object4;
|
|
39370
39373
|
};
|
|
39371
|
-
var parentFolder = function(
|
|
39372
|
-
if (
|
|
39373
|
-
|
|
39374
|
+
var parentFolder = function(path16) {
|
|
39375
|
+
if (path16.slice(-1) === "/") {
|
|
39376
|
+
path16 = path16.substring(0, path16.length - 1);
|
|
39374
39377
|
}
|
|
39375
|
-
var lastSlash =
|
|
39376
|
-
return lastSlash > 0 ?
|
|
39378
|
+
var lastSlash = path16.lastIndexOf("/");
|
|
39379
|
+
return lastSlash > 0 ? path16.substring(0, lastSlash) : "";
|
|
39377
39380
|
};
|
|
39378
|
-
var forceTrailingSlash = function(
|
|
39379
|
-
if (
|
|
39380
|
-
|
|
39381
|
+
var forceTrailingSlash = function(path16) {
|
|
39382
|
+
if (path16.slice(-1) !== "/") {
|
|
39383
|
+
path16 += "/";
|
|
39381
39384
|
}
|
|
39382
|
-
return
|
|
39385
|
+
return path16;
|
|
39383
39386
|
};
|
|
39384
39387
|
var folderAdd = function(name2, createFolders) {
|
|
39385
39388
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -40418,27 +40421,27 @@ var require_zipfile = __commonJS({
|
|
|
40418
40421
|
};
|
|
40419
40422
|
});
|
|
40420
40423
|
}
|
|
40421
|
-
function splitPath(
|
|
40422
|
-
var lastIndex =
|
|
40424
|
+
function splitPath(path16) {
|
|
40425
|
+
var lastIndex = path16.lastIndexOf("/");
|
|
40423
40426
|
if (lastIndex === -1) {
|
|
40424
|
-
return { dirname: "", basename:
|
|
40427
|
+
return { dirname: "", basename: path16 };
|
|
40425
40428
|
} else {
|
|
40426
40429
|
return {
|
|
40427
|
-
dirname:
|
|
40428
|
-
basename:
|
|
40430
|
+
dirname: path16.substring(0, lastIndex),
|
|
40431
|
+
basename: path16.substring(lastIndex + 1)
|
|
40429
40432
|
};
|
|
40430
40433
|
}
|
|
40431
40434
|
}
|
|
40432
40435
|
function joinPath() {
|
|
40433
|
-
var nonEmptyPaths = Array.prototype.filter.call(arguments, function(
|
|
40434
|
-
return
|
|
40436
|
+
var nonEmptyPaths = Array.prototype.filter.call(arguments, function(path16) {
|
|
40437
|
+
return path16;
|
|
40435
40438
|
});
|
|
40436
40439
|
var relevantPaths = [];
|
|
40437
|
-
nonEmptyPaths.forEach(function(
|
|
40438
|
-
if (/^\//.test(
|
|
40439
|
-
relevantPaths = [
|
|
40440
|
+
nonEmptyPaths.forEach(function(path16) {
|
|
40441
|
+
if (/^\//.test(path16)) {
|
|
40442
|
+
relevantPaths = [path16];
|
|
40440
40443
|
} else {
|
|
40441
|
-
relevantPaths.push(
|
|
40444
|
+
relevantPaths.push(path16);
|
|
40442
40445
|
}
|
|
40443
40446
|
});
|
|
40444
40447
|
return relevantPaths.join("/");
|
|
@@ -47762,9 +47765,9 @@ var require_office_xml_reader = __commonJS({
|
|
|
47762
47765
|
return collapseAlternateContent(document4)[0];
|
|
47763
47766
|
});
|
|
47764
47767
|
}
|
|
47765
|
-
function readXmlFromZipFile(docxFile,
|
|
47766
|
-
if (docxFile.exists(
|
|
47767
|
-
return docxFile.read(
|
|
47768
|
+
function readXmlFromZipFile(docxFile, path16) {
|
|
47769
|
+
if (docxFile.exists(path16)) {
|
|
47770
|
+
return docxFile.read(path16, "utf-8").then(stripUtf8Bom).then(read);
|
|
47768
47771
|
} else {
|
|
47769
47772
|
return promises.resolve(null);
|
|
47770
47773
|
}
|
|
@@ -49531,10 +49534,10 @@ var require_body_reader = __commonJS({
|
|
|
49531
49534
|
}
|
|
49532
49535
|
}
|
|
49533
49536
|
function findEmbeddedImageFile(relationshipId) {
|
|
49534
|
-
var
|
|
49537
|
+
var path16 = uris.uriToZipEntryName("word", relationships.findTargetByRelationshipId(relationshipId));
|
|
49535
49538
|
return {
|
|
49536
|
-
path:
|
|
49537
|
-
read: docxFile.read.bind(docxFile,
|
|
49539
|
+
path: path16,
|
|
49540
|
+
read: docxFile.read.bind(docxFile, path16)
|
|
49538
49541
|
};
|
|
49539
49542
|
}
|
|
49540
49543
|
function readImage(imageFile, altText) {
|
|
@@ -49774,12 +49777,12 @@ var require_content_types_reader = __commonJS({
|
|
|
49774
49777
|
}
|
|
49775
49778
|
function contentTypes(overrides, extensionDefaults) {
|
|
49776
49779
|
return {
|
|
49777
|
-
findContentType: function(
|
|
49778
|
-
var overrideContentType = overrides[
|
|
49780
|
+
findContentType: function(path16) {
|
|
49781
|
+
var overrideContentType = overrides[path16];
|
|
49779
49782
|
if (overrideContentType) {
|
|
49780
49783
|
return overrideContentType;
|
|
49781
49784
|
} else {
|
|
49782
|
-
var pathParts =
|
|
49785
|
+
var pathParts = path16.split(".");
|
|
49783
49786
|
var extension2 = pathParts[pathParts.length - 1];
|
|
49784
49787
|
if (extensionDefaults.hasOwnProperty(extension2)) {
|
|
49785
49788
|
return extensionDefaults[extension2];
|
|
@@ -50026,12 +50029,12 @@ var require_comments_reader = __commonJS({
|
|
|
50026
50029
|
var require_path_is_absolute = __commonJS({
|
|
50027
50030
|
"node_modules/path-is-absolute/index.js"(exports3, module3) {
|
|
50028
50031
|
"use strict";
|
|
50029
|
-
function posix(
|
|
50030
|
-
return
|
|
50032
|
+
function posix(path16) {
|
|
50033
|
+
return path16.charAt(0) === "/";
|
|
50031
50034
|
}
|
|
50032
|
-
function win32(
|
|
50035
|
+
function win32(path16) {
|
|
50033
50036
|
var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/;
|
|
50034
|
-
var result2 = splitDeviceRe.exec(
|
|
50037
|
+
var result2 = splitDeviceRe.exec(path16);
|
|
50035
50038
|
var device = result2[1] || "";
|
|
50036
50039
|
var isUnc = Boolean(device && device.charAt(1) !== ":");
|
|
50037
50040
|
return Boolean(result2[2] || isUnc);
|
|
@@ -50046,7 +50049,7 @@ var require_path_is_absolute = __commonJS({
|
|
|
50046
50049
|
var require_files = __commonJS({
|
|
50047
50050
|
"node_modules/mammoth/lib/docx/files.js"(exports3) {
|
|
50048
50051
|
"use strict";
|
|
50049
|
-
var
|
|
50052
|
+
var fs11 = __require("fs");
|
|
50050
50053
|
var url = __require("url");
|
|
50051
50054
|
var os2 = __require("os");
|
|
50052
50055
|
var dirname4 = __require("path").dirname;
|
|
@@ -50066,19 +50069,19 @@ var require_files = __commonJS({
|
|
|
50066
50069
|
}
|
|
50067
50070
|
var base = options.relativeToFile ? dirname4(options.relativeToFile) : null;
|
|
50068
50071
|
function read(uri, encoding) {
|
|
50069
|
-
return resolveUri(uri).then(function(
|
|
50070
|
-
return readFile(
|
|
50072
|
+
return resolveUri(uri).then(function(path16) {
|
|
50073
|
+
return readFile(path16, encoding).caught(function(error2) {
|
|
50071
50074
|
var message = "could not open external image: '" + uri + "' (document directory: '" + base + "')\n" + error2.message;
|
|
50072
50075
|
return promises.reject(new Error(message));
|
|
50073
50076
|
});
|
|
50074
50077
|
});
|
|
50075
50078
|
}
|
|
50076
50079
|
function resolveUri(uri) {
|
|
50077
|
-
var
|
|
50078
|
-
if (isAbsolutePath(
|
|
50079
|
-
return promises.resolve(
|
|
50080
|
+
var path16 = uriToPath(uri);
|
|
50081
|
+
if (isAbsolutePath(path16)) {
|
|
50082
|
+
return promises.resolve(path16);
|
|
50080
50083
|
} else if (base) {
|
|
50081
|
-
return promises.resolve(resolvePath(base,
|
|
50084
|
+
return promises.resolve(resolvePath(base, path16));
|
|
50082
50085
|
} else {
|
|
50083
50086
|
return promises.reject(new Error("could not find external image '" + uri + "', path of input document is unknown"));
|
|
50084
50087
|
}
|
|
@@ -50087,18 +50090,18 @@ var require_files = __commonJS({
|
|
|
50087
50090
|
read
|
|
50088
50091
|
};
|
|
50089
50092
|
}
|
|
50090
|
-
var readFile = promises.promisify(
|
|
50093
|
+
var readFile = promises.promisify(fs11.readFile.bind(fs11));
|
|
50091
50094
|
function uriToPath(uriString, platform) {
|
|
50092
50095
|
if (!platform) {
|
|
50093
50096
|
platform = os2.platform();
|
|
50094
50097
|
}
|
|
50095
50098
|
var uri = url.parse(uriString);
|
|
50096
50099
|
if (isLocalFileUri(uri) || isRelativeUri(uri)) {
|
|
50097
|
-
var
|
|
50098
|
-
if (platform === "win32" && /^\/[a-z]:/i.test(
|
|
50099
|
-
return
|
|
50100
|
+
var path16 = decodeURIComponent(uri.path);
|
|
50101
|
+
if (platform === "win32" && /^\/[a-z]:/i.test(path16)) {
|
|
50102
|
+
return path16.slice(1);
|
|
50100
50103
|
} else {
|
|
50101
|
-
return
|
|
50104
|
+
return path16;
|
|
50102
50105
|
}
|
|
50103
50106
|
} else {
|
|
50104
50107
|
throw new Error("Could not convert URI to path: " + uriString);
|
|
@@ -50299,18 +50302,18 @@ var require_docx_reader = __commonJS({
|
|
|
50299
50302
|
readElement: contentTypesReader.readContentTypesFromXml,
|
|
50300
50303
|
defaultValue: contentTypesReader.defaultContentTypes
|
|
50301
50304
|
});
|
|
50302
|
-
function readNumberingFromZipFile(zipFile,
|
|
50305
|
+
function readNumberingFromZipFile(zipFile, path16, styles) {
|
|
50303
50306
|
return xmlFileReader({
|
|
50304
|
-
filename:
|
|
50307
|
+
filename: path16,
|
|
50305
50308
|
readElement: function(element) {
|
|
50306
50309
|
return numberingXml.readNumberingXml(element, { styles });
|
|
50307
50310
|
},
|
|
50308
50311
|
defaultValue: numberingXml.defaultNumbering
|
|
50309
50312
|
})(zipFile);
|
|
50310
50313
|
}
|
|
50311
|
-
function readStylesFromZipFile(zipFile,
|
|
50314
|
+
function readStylesFromZipFile(zipFile, path16) {
|
|
50312
50315
|
return xmlFileReader({
|
|
50313
|
-
filename:
|
|
50316
|
+
filename: path16,
|
|
50314
50317
|
readElement: stylesReader.readStylesXml,
|
|
50315
50318
|
defaultValue: stylesReader.defaultStyles
|
|
50316
50319
|
})(zipFile);
|
|
@@ -50342,10 +50345,10 @@ var require_style_map = __commonJS({
|
|
|
50342
50345
|
});
|
|
50343
50346
|
}
|
|
50344
50347
|
function updateRelationships(docxFile) {
|
|
50345
|
-
var
|
|
50348
|
+
var path16 = "word/_rels/document.xml.rels";
|
|
50346
50349
|
var relationshipsUri = "http://schemas.openxmlformats.org/package/2006/relationships";
|
|
50347
50350
|
var relationshipElementName = "{" + relationshipsUri + "}Relationship";
|
|
50348
|
-
return docxFile.read(
|
|
50351
|
+
return docxFile.read(path16, "utf8").then(xml.readString).then(function(relationshipsContainer) {
|
|
50349
50352
|
var relationships = relationshipsContainer.children;
|
|
50350
50353
|
addOrUpdateElement(relationships, relationshipElementName, "Id", {
|
|
50351
50354
|
"Id": "rMammothStyleMap",
|
|
@@ -50353,21 +50356,21 @@ var require_style_map = __commonJS({
|
|
|
50353
50356
|
"Target": styleMapAbsolutePath
|
|
50354
50357
|
});
|
|
50355
50358
|
var namespaces = { "": relationshipsUri };
|
|
50356
|
-
return docxFile.write(
|
|
50359
|
+
return docxFile.write(path16, xml.writeString(relationshipsContainer, namespaces));
|
|
50357
50360
|
});
|
|
50358
50361
|
}
|
|
50359
50362
|
function updateContentTypes(docxFile) {
|
|
50360
|
-
var
|
|
50363
|
+
var path16 = "[Content_Types].xml";
|
|
50361
50364
|
var contentTypesUri = "http://schemas.openxmlformats.org/package/2006/content-types";
|
|
50362
50365
|
var overrideName = "{" + contentTypesUri + "}Override";
|
|
50363
|
-
return docxFile.read(
|
|
50366
|
+
return docxFile.read(path16, "utf8").then(xml.readString).then(function(typesElement) {
|
|
50364
50367
|
var children = typesElement.children;
|
|
50365
50368
|
addOrUpdateElement(children, overrideName, "PartName", {
|
|
50366
50369
|
"PartName": styleMapAbsolutePath,
|
|
50367
50370
|
"ContentType": "text/prs.mammoth.style-map"
|
|
50368
50371
|
});
|
|
50369
50372
|
var namespaces = { "": contentTypesUri };
|
|
50370
|
-
return docxFile.write(
|
|
50373
|
+
return docxFile.write(path16, xml.writeString(typesElement, namespaces));
|
|
50371
50374
|
});
|
|
50372
50375
|
}
|
|
50373
50376
|
function addOrUpdateElement(elements, name2, identifyingAttribute, attributes) {
|
|
@@ -51064,9 +51067,9 @@ var require_document_to_html = __commonJS({
|
|
|
51064
51067
|
};
|
|
51065
51068
|
var paths = [];
|
|
51066
51069
|
if (run2.highlight !== null) {
|
|
51067
|
-
var
|
|
51068
|
-
if (
|
|
51069
|
-
paths.push(
|
|
51070
|
+
var path16 = findHtmlPath({ type: "highlight", color: run2.highlight });
|
|
51071
|
+
if (path16) {
|
|
51072
|
+
paths.push(path16);
|
|
51070
51073
|
}
|
|
51071
51074
|
}
|
|
51072
51075
|
if (run2.isSmallCaps) {
|
|
@@ -51101,15 +51104,15 @@ var require_document_to_html = __commonJS({
|
|
|
51101
51104
|
messages.push(unrecognisedStyleWarning("run", run2));
|
|
51102
51105
|
}
|
|
51103
51106
|
paths.push(stylePath);
|
|
51104
|
-
paths.forEach(function(
|
|
51105
|
-
nodes =
|
|
51107
|
+
paths.forEach(function(path17) {
|
|
51108
|
+
nodes = path17.wrap.bind(path17, nodes);
|
|
51106
51109
|
});
|
|
51107
51110
|
return nodes();
|
|
51108
51111
|
}
|
|
51109
51112
|
function findHtmlPathForRunProperty(elementType, defaultTagName) {
|
|
51110
|
-
var
|
|
51111
|
-
if (
|
|
51112
|
-
return
|
|
51113
|
+
var path16 = findHtmlPath({ type: elementType });
|
|
51114
|
+
if (path16) {
|
|
51115
|
+
return path16;
|
|
51113
51116
|
} else if (defaultTagName) {
|
|
51114
51117
|
return htmlPaths.element(defaultTagName, {}, { fresh: false });
|
|
51115
51118
|
} else {
|
|
@@ -52829,11 +52832,11 @@ var require_options_reader = __commonJS({
|
|
|
52829
52832
|
var require_unzip = __commonJS({
|
|
52830
52833
|
"node_modules/mammoth/lib/unzip.js"(exports3) {
|
|
52831
52834
|
"use strict";
|
|
52832
|
-
var
|
|
52835
|
+
var fs11 = __require("fs");
|
|
52833
52836
|
var promises = require_promises();
|
|
52834
52837
|
var zipfile = require_zipfile();
|
|
52835
52838
|
exports3.openZip = openZip;
|
|
52836
|
-
var readFile = promises.promisify(
|
|
52839
|
+
var readFile = promises.promisify(fs11.readFile);
|
|
52837
52840
|
function openZip(options) {
|
|
52838
52841
|
if (options.path) {
|
|
52839
52842
|
return readFile(options.path).then(zipfile.openArrayBuffer);
|
|
@@ -56705,8 +56708,8 @@ var init_parseUtil = __esm({
|
|
|
56705
56708
|
init_errors();
|
|
56706
56709
|
init_en();
|
|
56707
56710
|
makeIssue = (params2) => {
|
|
56708
|
-
const { data, path:
|
|
56709
|
-
const fullPath = [...
|
|
56711
|
+
const { data, path: path16, errorMaps, issueData } = params2;
|
|
56712
|
+
const fullPath = [...path16, ...issueData.path || []];
|
|
56710
56713
|
const fullIssue = {
|
|
56711
56714
|
...issueData,
|
|
56712
56715
|
path: fullPath
|
|
@@ -57017,11 +57020,11 @@ var init_types = __esm({
|
|
|
57017
57020
|
init_parseUtil();
|
|
57018
57021
|
init_util();
|
|
57019
57022
|
ParseInputLazyPath = class {
|
|
57020
|
-
constructor(parent, value,
|
|
57023
|
+
constructor(parent, value, path16, key) {
|
|
57021
57024
|
this._cachedPath = [];
|
|
57022
57025
|
this.parent = parent;
|
|
57023
57026
|
this.data = value;
|
|
57024
|
-
this._path =
|
|
57027
|
+
this._path = path16;
|
|
57025
57028
|
this._key = key;
|
|
57026
57029
|
}
|
|
57027
57030
|
get path() {
|
|
@@ -63865,7 +63868,7 @@ var require_websocket = __commonJS({
|
|
|
63865
63868
|
var http = __require("http");
|
|
63866
63869
|
var net2 = __require("net");
|
|
63867
63870
|
var tls = __require("tls");
|
|
63868
|
-
var { randomBytes: randomBytes2, createHash:
|
|
63871
|
+
var { randomBytes: randomBytes2, createHash: createHash4 } = __require("crypto");
|
|
63869
63872
|
var { Duplex, Readable: Readable2 } = __require("stream");
|
|
63870
63873
|
var { URL: URL2 } = __require("url");
|
|
63871
63874
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -64525,7 +64528,7 @@ var require_websocket = __commonJS({
|
|
|
64525
64528
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
64526
64529
|
return;
|
|
64527
64530
|
}
|
|
64528
|
-
const digest =
|
|
64531
|
+
const digest = createHash4("sha1").update(key + GUID).digest("base64");
|
|
64529
64532
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
64530
64533
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
64531
64534
|
return;
|
|
@@ -64892,7 +64895,7 @@ var require_websocket_server = __commonJS({
|
|
|
64892
64895
|
var EventEmitter = __require("events");
|
|
64893
64896
|
var http = __require("http");
|
|
64894
64897
|
var { Duplex } = __require("stream");
|
|
64895
|
-
var { createHash:
|
|
64898
|
+
var { createHash: createHash4 } = __require("crypto");
|
|
64896
64899
|
var extension2 = require_extension();
|
|
64897
64900
|
var PerMessageDeflate = require_permessage_deflate();
|
|
64898
64901
|
var subprotocol = require_subprotocol();
|
|
@@ -65193,7 +65196,7 @@ var require_websocket_server = __commonJS({
|
|
|
65193
65196
|
);
|
|
65194
65197
|
}
|
|
65195
65198
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
65196
|
-
const digest =
|
|
65199
|
+
const digest = createHash4("sha1").update(key + GUID).digest("base64");
|
|
65197
65200
|
const headers = [
|
|
65198
65201
|
"HTTP/1.1 101 Switching Protocols",
|
|
65199
65202
|
"Upgrade: websocket",
|
|
@@ -67443,6 +67446,8 @@ function getOrCreateDocument(name2) {
|
|
|
67443
67446
|
async function startHocuspocus(port) {
|
|
67444
67447
|
hocuspocusInstance = new Hocuspocus({
|
|
67445
67448
|
port,
|
|
67449
|
+
// Hocuspocus always binds loopback — the MCP bind-host env var does not apply here.
|
|
67450
|
+
// WebSocket collaboration traffic stays local-only per the Cowork architecture.
|
|
67446
67451
|
address: "127.0.0.1",
|
|
67447
67452
|
quiet: true,
|
|
67448
67453
|
// stdout is the MCP wire — suppress the startup banner
|
|
@@ -86643,11 +86648,11 @@ var require_mime_types = __commonJS({
|
|
|
86643
86648
|
}
|
|
86644
86649
|
return exts[0];
|
|
86645
86650
|
}
|
|
86646
|
-
function lookup(
|
|
86647
|
-
if (!
|
|
86651
|
+
function lookup(path16) {
|
|
86652
|
+
if (!path16 || typeof path16 !== "string") {
|
|
86648
86653
|
return false;
|
|
86649
86654
|
}
|
|
86650
|
-
var extension3 = extname("x." +
|
|
86655
|
+
var extension3 = extname("x." + path16).toLowerCase().slice(1);
|
|
86651
86656
|
if (!extension3) {
|
|
86652
86657
|
return false;
|
|
86653
86658
|
}
|
|
@@ -90121,13 +90126,13 @@ var require_view = __commonJS({
|
|
|
90121
90126
|
"node_modules/express/lib/view.js"(exports3, module3) {
|
|
90122
90127
|
"use strict";
|
|
90123
90128
|
var debug = require_src()("express:view");
|
|
90124
|
-
var
|
|
90125
|
-
var
|
|
90126
|
-
var dirname4 =
|
|
90127
|
-
var basename2 =
|
|
90128
|
-
var extname =
|
|
90129
|
-
var join4 =
|
|
90130
|
-
var resolve4 =
|
|
90129
|
+
var path16 = __require("path");
|
|
90130
|
+
var fs11 = __require("fs");
|
|
90131
|
+
var dirname4 = path16.dirname;
|
|
90132
|
+
var basename2 = path16.basename;
|
|
90133
|
+
var extname = path16.extname;
|
|
90134
|
+
var join4 = path16.join;
|
|
90135
|
+
var resolve4 = path16.resolve;
|
|
90131
90136
|
module3.exports = View;
|
|
90132
90137
|
function View(name2, options) {
|
|
90133
90138
|
var opts = options || {};
|
|
@@ -90156,17 +90161,17 @@ var require_view = __commonJS({
|
|
|
90156
90161
|
this.path = this.lookup(fileName);
|
|
90157
90162
|
}
|
|
90158
90163
|
View.prototype.lookup = function lookup(name2) {
|
|
90159
|
-
var
|
|
90164
|
+
var path17;
|
|
90160
90165
|
var roots = [].concat(this.root);
|
|
90161
90166
|
debug('lookup "%s"', name2);
|
|
90162
|
-
for (var i = 0; i < roots.length && !
|
|
90167
|
+
for (var i = 0; i < roots.length && !path17; i++) {
|
|
90163
90168
|
var root3 = roots[i];
|
|
90164
90169
|
var loc = resolve4(root3, name2);
|
|
90165
90170
|
var dir = dirname4(loc);
|
|
90166
90171
|
var file = basename2(loc);
|
|
90167
|
-
|
|
90172
|
+
path17 = this.resolve(dir, file);
|
|
90168
90173
|
}
|
|
90169
|
-
return
|
|
90174
|
+
return path17;
|
|
90170
90175
|
};
|
|
90171
90176
|
View.prototype.render = function render2(options, callback) {
|
|
90172
90177
|
var sync = true;
|
|
@@ -90188,21 +90193,21 @@ var require_view = __commonJS({
|
|
|
90188
90193
|
};
|
|
90189
90194
|
View.prototype.resolve = function resolve5(dir, file) {
|
|
90190
90195
|
var ext = this.ext;
|
|
90191
|
-
var
|
|
90192
|
-
var stat = tryStat(
|
|
90196
|
+
var path17 = join4(dir, file);
|
|
90197
|
+
var stat = tryStat(path17);
|
|
90193
90198
|
if (stat && stat.isFile()) {
|
|
90194
|
-
return
|
|
90199
|
+
return path17;
|
|
90195
90200
|
}
|
|
90196
|
-
|
|
90197
|
-
stat = tryStat(
|
|
90201
|
+
path17 = join4(dir, basename2(file, ext), "index" + ext);
|
|
90202
|
+
stat = tryStat(path17);
|
|
90198
90203
|
if (stat && stat.isFile()) {
|
|
90199
|
-
return
|
|
90204
|
+
return path17;
|
|
90200
90205
|
}
|
|
90201
90206
|
};
|
|
90202
|
-
function tryStat(
|
|
90203
|
-
debug('stat "%s"',
|
|
90207
|
+
function tryStat(path17) {
|
|
90208
|
+
debug('stat "%s"', path17);
|
|
90204
90209
|
try {
|
|
90205
|
-
return
|
|
90210
|
+
return fs11.statSync(path17);
|
|
90206
90211
|
} catch (e) {
|
|
90207
90212
|
return void 0;
|
|
90208
90213
|
}
|
|
@@ -90215,14 +90220,14 @@ var require_etag = __commonJS({
|
|
|
90215
90220
|
"node_modules/etag/index.js"(exports3, module3) {
|
|
90216
90221
|
"use strict";
|
|
90217
90222
|
module3.exports = etag;
|
|
90218
|
-
var
|
|
90223
|
+
var crypto8 = __require("crypto");
|
|
90219
90224
|
var Stats = __require("fs").Stats;
|
|
90220
90225
|
var toString3 = Object.prototype.toString;
|
|
90221
90226
|
function entitytag(entity) {
|
|
90222
90227
|
if (entity.length === 0) {
|
|
90223
90228
|
return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"';
|
|
90224
90229
|
}
|
|
90225
|
-
var hash =
|
|
90230
|
+
var hash = crypto8.createHash("sha1").update(entity, "utf8").digest("base64").substring(0, 27);
|
|
90226
90231
|
var len = typeof entity === "string" ? Buffer.byteLength(entity, "utf8") : entity.length;
|
|
90227
90232
|
return '"' + len.toString(16) + "-" + hash + '"';
|
|
90228
90233
|
}
|
|
@@ -91392,15 +91397,15 @@ var require_dist2 = __commonJS({
|
|
|
91392
91397
|
if (token.type === endType)
|
|
91393
91398
|
break;
|
|
91394
91399
|
if (token.type === "char" || token.type === "escape") {
|
|
91395
|
-
let
|
|
91400
|
+
let path16 = token.value;
|
|
91396
91401
|
let cur = tokens[pos];
|
|
91397
91402
|
while (cur.type === "char" || cur.type === "escape") {
|
|
91398
|
-
|
|
91403
|
+
path16 += cur.value;
|
|
91399
91404
|
cur = tokens[++pos];
|
|
91400
91405
|
}
|
|
91401
91406
|
output.push({
|
|
91402
91407
|
type: "text",
|
|
91403
|
-
value: encodePath(
|
|
91408
|
+
value: encodePath(path16)
|
|
91404
91409
|
});
|
|
91405
91410
|
continue;
|
|
91406
91411
|
}
|
|
@@ -91424,16 +91429,16 @@ var require_dist2 = __commonJS({
|
|
|
91424
91429
|
}
|
|
91425
91430
|
return new TokenData(consumeUntil("end"), str);
|
|
91426
91431
|
}
|
|
91427
|
-
function compile(
|
|
91432
|
+
function compile(path16, options = {}) {
|
|
91428
91433
|
const { encode = encodeURIComponent, delimiter = DEFAULT_DELIMITER } = options;
|
|
91429
|
-
const data = typeof
|
|
91434
|
+
const data = typeof path16 === "object" ? path16 : parse4(path16, options);
|
|
91430
91435
|
const fn = tokensToFunction(data.tokens, delimiter, encode);
|
|
91431
|
-
return function
|
|
91432
|
-
const [
|
|
91436
|
+
return function path17(params2 = {}) {
|
|
91437
|
+
const [path18, ...missing] = fn(params2);
|
|
91433
91438
|
if (missing.length) {
|
|
91434
91439
|
throw new TypeError(`Missing parameters: ${missing.join(", ")}`);
|
|
91435
91440
|
}
|
|
91436
|
-
return
|
|
91441
|
+
return path18;
|
|
91437
91442
|
};
|
|
91438
91443
|
}
|
|
91439
91444
|
function tokensToFunction(tokens, delimiter, encode) {
|
|
@@ -91489,9 +91494,9 @@ var require_dist2 = __commonJS({
|
|
|
91489
91494
|
return [encodeValue(value)];
|
|
91490
91495
|
};
|
|
91491
91496
|
}
|
|
91492
|
-
function match(
|
|
91497
|
+
function match(path16, options = {}) {
|
|
91493
91498
|
const { decode: decode2 = decodeURIComponent, delimiter = DEFAULT_DELIMITER } = options;
|
|
91494
|
-
const { regexp, keys: keys4 } = pathToRegexp(
|
|
91499
|
+
const { regexp, keys: keys4 } = pathToRegexp(path16, options);
|
|
91495
91500
|
const decoders = keys4.map((key) => {
|
|
91496
91501
|
if (decode2 === false)
|
|
91497
91502
|
return NOOP_VALUE;
|
|
@@ -91503,7 +91508,7 @@ var require_dist2 = __commonJS({
|
|
|
91503
91508
|
const m = regexp.exec(input);
|
|
91504
91509
|
if (!m)
|
|
91505
91510
|
return false;
|
|
91506
|
-
const
|
|
91511
|
+
const path17 = m[0];
|
|
91507
91512
|
const params2 = /* @__PURE__ */ Object.create(null);
|
|
91508
91513
|
for (let i = 1; i < m.length; i++) {
|
|
91509
91514
|
if (m[i] === void 0)
|
|
@@ -91512,21 +91517,21 @@ var require_dist2 = __commonJS({
|
|
|
91512
91517
|
const decoder = decoders[i - 1];
|
|
91513
91518
|
params2[key.name] = decoder(m[i]);
|
|
91514
91519
|
}
|
|
91515
|
-
return { path:
|
|
91520
|
+
return { path: path17, params: params2 };
|
|
91516
91521
|
};
|
|
91517
91522
|
}
|
|
91518
|
-
function pathToRegexp(
|
|
91523
|
+
function pathToRegexp(path16, options = {}) {
|
|
91519
91524
|
const { delimiter = DEFAULT_DELIMITER, end = true, sensitive = false, trailing = true } = options;
|
|
91520
91525
|
const root3 = new SourceNode("^");
|
|
91521
|
-
const paths = [
|
|
91526
|
+
const paths = [path16];
|
|
91522
91527
|
let combinations = 0;
|
|
91523
91528
|
while (paths.length) {
|
|
91524
|
-
const
|
|
91525
|
-
if (Array.isArray(
|
|
91526
|
-
paths.push(...
|
|
91529
|
+
const path17 = paths.shift();
|
|
91530
|
+
if (Array.isArray(path17)) {
|
|
91531
|
+
paths.push(...path17);
|
|
91527
91532
|
continue;
|
|
91528
91533
|
}
|
|
91529
|
-
const data = typeof
|
|
91534
|
+
const data = typeof path17 === "object" ? path17 : parse4(path17, options);
|
|
91530
91535
|
flatten3(data.tokens, 0, [], (tokens) => {
|
|
91531
91536
|
if (combinations++ >= 256) {
|
|
91532
91537
|
throw new PathError("Too many path combinations", data.originalPath);
|
|
@@ -91700,18 +91705,18 @@ var require_layer = __commonJS({
|
|
|
91700
91705
|
var TRAILING_SLASH_REGEXP = /\/+$/;
|
|
91701
91706
|
var MATCHING_GROUP_REGEXP = /\((?:\?<(.*?)>)?(?!\?)/g;
|
|
91702
91707
|
module3.exports = Layer;
|
|
91703
|
-
function Layer(
|
|
91708
|
+
function Layer(path16, options, fn) {
|
|
91704
91709
|
if (!(this instanceof Layer)) {
|
|
91705
|
-
return new Layer(
|
|
91710
|
+
return new Layer(path16, options, fn);
|
|
91706
91711
|
}
|
|
91707
|
-
debug("new %o",
|
|
91712
|
+
debug("new %o", path16);
|
|
91708
91713
|
const opts = options || {};
|
|
91709
91714
|
this.handle = fn;
|
|
91710
91715
|
this.keys = [];
|
|
91711
91716
|
this.name = fn.name || "<anonymous>";
|
|
91712
91717
|
this.params = void 0;
|
|
91713
91718
|
this.path = void 0;
|
|
91714
|
-
this.slash =
|
|
91719
|
+
this.slash = path16 === "/" && opts.end === false;
|
|
91715
91720
|
function matcher2(_path) {
|
|
91716
91721
|
if (_path instanceof RegExp) {
|
|
91717
91722
|
const keys4 = [];
|
|
@@ -91750,7 +91755,7 @@ var require_layer = __commonJS({
|
|
|
91750
91755
|
decode: decodeParam
|
|
91751
91756
|
});
|
|
91752
91757
|
}
|
|
91753
|
-
this.matchers = Array.isArray(
|
|
91758
|
+
this.matchers = Array.isArray(path16) ? path16.map(matcher2) : [matcher2(path16)];
|
|
91754
91759
|
}
|
|
91755
91760
|
Layer.prototype.handleError = function handleError(error2, req, res, next) {
|
|
91756
91761
|
const fn = this.handle;
|
|
@@ -91790,9 +91795,9 @@ var require_layer = __commonJS({
|
|
|
91790
91795
|
next(err);
|
|
91791
91796
|
}
|
|
91792
91797
|
};
|
|
91793
|
-
Layer.prototype.match = function match(
|
|
91798
|
+
Layer.prototype.match = function match(path16) {
|
|
91794
91799
|
let match2;
|
|
91795
|
-
if (
|
|
91800
|
+
if (path16 != null) {
|
|
91796
91801
|
if (this.slash) {
|
|
91797
91802
|
this.params = {};
|
|
91798
91803
|
this.path = "";
|
|
@@ -91800,7 +91805,7 @@ var require_layer = __commonJS({
|
|
|
91800
91805
|
}
|
|
91801
91806
|
let i = 0;
|
|
91802
91807
|
while (!match2 && i < this.matchers.length) {
|
|
91803
|
-
match2 = this.matchers[i](
|
|
91808
|
+
match2 = this.matchers[i](path16);
|
|
91804
91809
|
i++;
|
|
91805
91810
|
}
|
|
91806
91811
|
}
|
|
@@ -91828,13 +91833,13 @@ var require_layer = __commonJS({
|
|
|
91828
91833
|
throw err;
|
|
91829
91834
|
}
|
|
91830
91835
|
}
|
|
91831
|
-
function loosen(
|
|
91832
|
-
if (
|
|
91833
|
-
return
|
|
91836
|
+
function loosen(path16) {
|
|
91837
|
+
if (path16 instanceof RegExp || path16 === "/") {
|
|
91838
|
+
return path16;
|
|
91834
91839
|
}
|
|
91835
|
-
return Array.isArray(
|
|
91840
|
+
return Array.isArray(path16) ? path16.map(function(p) {
|
|
91836
91841
|
return loosen(p);
|
|
91837
|
-
}) : String(
|
|
91842
|
+
}) : String(path16).replace(TRAILING_SLASH_REGEXP, "");
|
|
91838
91843
|
}
|
|
91839
91844
|
}
|
|
91840
91845
|
});
|
|
@@ -91850,9 +91855,9 @@ var require_route = __commonJS({
|
|
|
91850
91855
|
var flatten3 = Array.prototype.flat;
|
|
91851
91856
|
var methods = METHODS.map((method) => method.toLowerCase());
|
|
91852
91857
|
module3.exports = Route;
|
|
91853
|
-
function Route(
|
|
91854
|
-
debug("new %o",
|
|
91855
|
-
this.path =
|
|
91858
|
+
function Route(path16) {
|
|
91859
|
+
debug("new %o", path16);
|
|
91860
|
+
this.path = path16;
|
|
91856
91861
|
this.stack = [];
|
|
91857
91862
|
this.methods = /* @__PURE__ */ Object.create(null);
|
|
91858
91863
|
}
|
|
@@ -92060,8 +92065,8 @@ var require_router = __commonJS({
|
|
|
92060
92065
|
if (++sync > 100) {
|
|
92061
92066
|
return setImmediate(next, err);
|
|
92062
92067
|
}
|
|
92063
|
-
const
|
|
92064
|
-
if (
|
|
92068
|
+
const path16 = getPathname(req);
|
|
92069
|
+
if (path16 == null) {
|
|
92065
92070
|
return done(layerError);
|
|
92066
92071
|
}
|
|
92067
92072
|
let layer;
|
|
@@ -92069,7 +92074,7 @@ var require_router = __commonJS({
|
|
|
92069
92074
|
let route;
|
|
92070
92075
|
while (match !== true && idx < stack.length) {
|
|
92071
92076
|
layer = stack[idx++];
|
|
92072
|
-
match = matchLayer(layer,
|
|
92077
|
+
match = matchLayer(layer, path16);
|
|
92073
92078
|
route = layer.route;
|
|
92074
92079
|
if (typeof match !== "boolean") {
|
|
92075
92080
|
layerError = layerError || match;
|
|
@@ -92107,18 +92112,18 @@ var require_router = __commonJS({
|
|
|
92107
92112
|
} else if (route) {
|
|
92108
92113
|
layer.handleRequest(req, res, next);
|
|
92109
92114
|
} else {
|
|
92110
|
-
trimPrefix(layer, layerError, layerPath,
|
|
92115
|
+
trimPrefix(layer, layerError, layerPath, path16);
|
|
92111
92116
|
}
|
|
92112
92117
|
sync = 0;
|
|
92113
92118
|
});
|
|
92114
92119
|
}
|
|
92115
|
-
function trimPrefix(layer, layerError, layerPath,
|
|
92120
|
+
function trimPrefix(layer, layerError, layerPath, path16) {
|
|
92116
92121
|
if (layerPath.length !== 0) {
|
|
92117
|
-
if (layerPath !==
|
|
92122
|
+
if (layerPath !== path16.substring(0, layerPath.length)) {
|
|
92118
92123
|
next(layerError);
|
|
92119
92124
|
return;
|
|
92120
92125
|
}
|
|
92121
|
-
const c =
|
|
92126
|
+
const c = path16[layerPath.length];
|
|
92122
92127
|
if (c && c !== "/") {
|
|
92123
92128
|
next(layerError);
|
|
92124
92129
|
return;
|
|
@@ -92142,7 +92147,7 @@ var require_router = __commonJS({
|
|
|
92142
92147
|
};
|
|
92143
92148
|
Router.prototype.use = function use(handler) {
|
|
92144
92149
|
let offset = 0;
|
|
92145
|
-
let
|
|
92150
|
+
let path16 = "/";
|
|
92146
92151
|
if (typeof handler !== "function") {
|
|
92147
92152
|
let arg = handler;
|
|
92148
92153
|
while (Array.isArray(arg) && arg.length !== 0) {
|
|
@@ -92150,7 +92155,7 @@ var require_router = __commonJS({
|
|
|
92150
92155
|
}
|
|
92151
92156
|
if (typeof arg !== "function") {
|
|
92152
92157
|
offset = 1;
|
|
92153
|
-
|
|
92158
|
+
path16 = handler;
|
|
92154
92159
|
}
|
|
92155
92160
|
}
|
|
92156
92161
|
const callbacks = flatten3.call(slice2.call(arguments, offset), Infinity);
|
|
@@ -92162,8 +92167,8 @@ var require_router = __commonJS({
|
|
|
92162
92167
|
if (typeof fn !== "function") {
|
|
92163
92168
|
throw new TypeError("argument handler must be a function");
|
|
92164
92169
|
}
|
|
92165
|
-
debug("use %o %s",
|
|
92166
|
-
const layer = new Layer(
|
|
92170
|
+
debug("use %o %s", path16, fn.name || "<anonymous>");
|
|
92171
|
+
const layer = new Layer(path16, {
|
|
92167
92172
|
sensitive: this.caseSensitive,
|
|
92168
92173
|
strict: false,
|
|
92169
92174
|
end: false
|
|
@@ -92173,9 +92178,9 @@ var require_router = __commonJS({
|
|
|
92173
92178
|
}
|
|
92174
92179
|
return this;
|
|
92175
92180
|
};
|
|
92176
|
-
Router.prototype.route = function route(
|
|
92177
|
-
const route2 = new Route(
|
|
92178
|
-
const layer = new Layer(
|
|
92181
|
+
Router.prototype.route = function route(path16) {
|
|
92182
|
+
const route2 = new Route(path16);
|
|
92183
|
+
const layer = new Layer(path16, {
|
|
92179
92184
|
sensitive: this.caseSensitive,
|
|
92180
92185
|
strict: this.strict,
|
|
92181
92186
|
end: true
|
|
@@ -92188,8 +92193,8 @@ var require_router = __commonJS({
|
|
|
92188
92193
|
return route2;
|
|
92189
92194
|
};
|
|
92190
92195
|
methods.concat("all").forEach(function(method) {
|
|
92191
|
-
Router.prototype[method] = function(
|
|
92192
|
-
const route = this.route(
|
|
92196
|
+
Router.prototype[method] = function(path16) {
|
|
92197
|
+
const route = this.route(path16);
|
|
92193
92198
|
route[method].apply(route, slice2.call(arguments, 1));
|
|
92194
92199
|
return this;
|
|
92195
92200
|
};
|
|
@@ -92218,9 +92223,9 @@ var require_router = __commonJS({
|
|
|
92218
92223
|
const fqdnIndex = url.substring(0, pathLength).indexOf("://");
|
|
92219
92224
|
return fqdnIndex !== -1 ? url.substring(0, url.indexOf("/", 3 + fqdnIndex)) : void 0;
|
|
92220
92225
|
}
|
|
92221
|
-
function matchLayer(layer,
|
|
92226
|
+
function matchLayer(layer, path16) {
|
|
92222
92227
|
try {
|
|
92223
|
-
return layer.match(
|
|
92228
|
+
return layer.match(path16);
|
|
92224
92229
|
} catch (err) {
|
|
92225
92230
|
return err;
|
|
92226
92231
|
}
|
|
@@ -92448,7 +92453,7 @@ var require_application = __commonJS({
|
|
|
92448
92453
|
};
|
|
92449
92454
|
app.use = function use(fn) {
|
|
92450
92455
|
var offset = 0;
|
|
92451
|
-
var
|
|
92456
|
+
var path16 = "/";
|
|
92452
92457
|
if (typeof fn !== "function") {
|
|
92453
92458
|
var arg = fn;
|
|
92454
92459
|
while (Array.isArray(arg) && arg.length !== 0) {
|
|
@@ -92456,7 +92461,7 @@ var require_application = __commonJS({
|
|
|
92456
92461
|
}
|
|
92457
92462
|
if (typeof arg !== "function") {
|
|
92458
92463
|
offset = 1;
|
|
92459
|
-
|
|
92464
|
+
path16 = fn;
|
|
92460
92465
|
}
|
|
92461
92466
|
}
|
|
92462
92467
|
var fns = flatten3.call(slice2.call(arguments, offset), Infinity);
|
|
@@ -92466,12 +92471,12 @@ var require_application = __commonJS({
|
|
|
92466
92471
|
var router = this.router;
|
|
92467
92472
|
fns.forEach(function(fn2) {
|
|
92468
92473
|
if (!fn2 || !fn2.handle || !fn2.set) {
|
|
92469
|
-
return router.use(
|
|
92474
|
+
return router.use(path16, fn2);
|
|
92470
92475
|
}
|
|
92471
|
-
debug(".use app under %s",
|
|
92472
|
-
fn2.mountpath =
|
|
92476
|
+
debug(".use app under %s", path16);
|
|
92477
|
+
fn2.mountpath = path16;
|
|
92473
92478
|
fn2.parent = this;
|
|
92474
|
-
router.use(
|
|
92479
|
+
router.use(path16, function mounted_app(req, res, next) {
|
|
92475
92480
|
var orig = req.app;
|
|
92476
92481
|
fn2.handle(req, res, function(err) {
|
|
92477
92482
|
Object.setPrototypeOf(req, orig.request);
|
|
@@ -92483,8 +92488,8 @@ var require_application = __commonJS({
|
|
|
92483
92488
|
}, this);
|
|
92484
92489
|
return this;
|
|
92485
92490
|
};
|
|
92486
|
-
app.route = function route(
|
|
92487
|
-
return this.router.route(
|
|
92491
|
+
app.route = function route(path16) {
|
|
92492
|
+
return this.router.route(path16);
|
|
92488
92493
|
};
|
|
92489
92494
|
app.engine = function engine(ext, fn) {
|
|
92490
92495
|
if (typeof fn !== "function") {
|
|
@@ -92527,7 +92532,7 @@ var require_application = __commonJS({
|
|
|
92527
92532
|
}
|
|
92528
92533
|
return this;
|
|
92529
92534
|
};
|
|
92530
|
-
app.path = function
|
|
92535
|
+
app.path = function path16() {
|
|
92531
92536
|
return this.parent ? this.parent.path() + this.mountpath : "";
|
|
92532
92537
|
};
|
|
92533
92538
|
app.enabled = function enabled(setting) {
|
|
@@ -92543,17 +92548,17 @@ var require_application = __commonJS({
|
|
|
92543
92548
|
return this.set(setting, false);
|
|
92544
92549
|
};
|
|
92545
92550
|
methods.forEach(function(method) {
|
|
92546
|
-
app[method] = function(
|
|
92551
|
+
app[method] = function(path16) {
|
|
92547
92552
|
if (method === "get" && arguments.length === 1) {
|
|
92548
|
-
return this.set(
|
|
92553
|
+
return this.set(path16);
|
|
92549
92554
|
}
|
|
92550
|
-
var route = this.route(
|
|
92555
|
+
var route = this.route(path16);
|
|
92551
92556
|
route[method].apply(route, slice2.call(arguments, 1));
|
|
92552
92557
|
return this;
|
|
92553
92558
|
};
|
|
92554
92559
|
});
|
|
92555
|
-
app.all = function all3(
|
|
92556
|
-
var route = this.route(
|
|
92560
|
+
app.all = function all3(path16) {
|
|
92561
|
+
var route = this.route(path16);
|
|
92557
92562
|
var args2 = slice2.call(arguments, 1);
|
|
92558
92563
|
for (var i = 0; i < methods.length; i++) {
|
|
92559
92564
|
route[methods[i]].apply(route, args2);
|
|
@@ -93370,7 +93375,7 @@ var require_request = __commonJS({
|
|
|
93370
93375
|
"node_modules/express/lib/request.js"(exports3, module3) {
|
|
93371
93376
|
"use strict";
|
|
93372
93377
|
var accepts = require_accepts();
|
|
93373
|
-
var
|
|
93378
|
+
var isIP2 = __require("net").isIP;
|
|
93374
93379
|
var typeis = require_type_is();
|
|
93375
93380
|
var http = __require("http");
|
|
93376
93381
|
var fresh = require_fresh();
|
|
@@ -93460,10 +93465,10 @@ var require_request = __commonJS({
|
|
|
93460
93465
|
var hostname2 = this.hostname;
|
|
93461
93466
|
if (!hostname2) return [];
|
|
93462
93467
|
var offset = this.app.get("subdomain offset");
|
|
93463
|
-
var subdomains2 = !
|
|
93468
|
+
var subdomains2 = !isIP2(hostname2) ? hostname2.split(".").reverse() : [hostname2];
|
|
93464
93469
|
return subdomains2.slice(offset);
|
|
93465
93470
|
});
|
|
93466
|
-
defineGetter(req, "path", function
|
|
93471
|
+
defineGetter(req, "path", function path16() {
|
|
93467
93472
|
return parse4(this).pathname;
|
|
93468
93473
|
});
|
|
93469
93474
|
defineGetter(req, "host", function host() {
|
|
@@ -93680,17 +93685,17 @@ var require_content_disposition = __commonJS({
|
|
|
93680
93685
|
var require_cookie_signature = __commonJS({
|
|
93681
93686
|
"node_modules/cookie-signature/index.js"(exports3) {
|
|
93682
93687
|
"use strict";
|
|
93683
|
-
var
|
|
93688
|
+
var crypto8 = __require("crypto");
|
|
93684
93689
|
exports3.sign = function(val, secret) {
|
|
93685
93690
|
if ("string" != typeof val) throw new TypeError("Cookie value must be provided as a string.");
|
|
93686
93691
|
if (null == secret) throw new TypeError("Secret key must be provided.");
|
|
93687
|
-
return val + "." +
|
|
93692
|
+
return val + "." + crypto8.createHmac("sha256", secret).update(val).digest("base64").replace(/\=+$/, "");
|
|
93688
93693
|
};
|
|
93689
93694
|
exports3.unsign = function(input, secret) {
|
|
93690
93695
|
if ("string" != typeof input) throw new TypeError("Signed cookie string must be provided.");
|
|
93691
93696
|
if (null == secret) throw new TypeError("Secret key must be provided.");
|
|
93692
93697
|
var tentativeValue = input.slice(0, input.lastIndexOf(".")), expectedInput = exports3.sign(tentativeValue, secret), expectedBuffer = Buffer.from(expectedInput), inputBuffer = Buffer.from(input);
|
|
93693
|
-
return expectedBuffer.length === inputBuffer.length &&
|
|
93698
|
+
return expectedBuffer.length === inputBuffer.length && crypto8.timingSafeEqual(expectedBuffer, inputBuffer) ? tentativeValue : false;
|
|
93694
93699
|
};
|
|
93695
93700
|
}
|
|
93696
93701
|
});
|
|
@@ -93871,32 +93876,32 @@ var require_send = __commonJS({
|
|
|
93871
93876
|
var escapeHtml = require_escape_html();
|
|
93872
93877
|
var etag = require_etag();
|
|
93873
93878
|
var fresh = require_fresh();
|
|
93874
|
-
var
|
|
93879
|
+
var fs11 = __require("fs");
|
|
93875
93880
|
var mime = require_mime_types();
|
|
93876
93881
|
var ms = require_ms();
|
|
93877
93882
|
var onFinished = require_on_finished();
|
|
93878
93883
|
var parseRange = require_range_parser();
|
|
93879
|
-
var
|
|
93884
|
+
var path16 = __require("path");
|
|
93880
93885
|
var statuses = require_statuses();
|
|
93881
93886
|
var Stream = __require("stream");
|
|
93882
93887
|
var util2 = __require("util");
|
|
93883
|
-
var extname =
|
|
93884
|
-
var join4 =
|
|
93885
|
-
var normalize =
|
|
93886
|
-
var resolve4 =
|
|
93887
|
-
var sep =
|
|
93888
|
+
var extname = path16.extname;
|
|
93889
|
+
var join4 = path16.join;
|
|
93890
|
+
var normalize = path16.normalize;
|
|
93891
|
+
var resolve4 = path16.resolve;
|
|
93892
|
+
var sep = path16.sep;
|
|
93888
93893
|
var BYTES_RANGE_REGEXP = /^ *bytes=/;
|
|
93889
93894
|
var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1e3;
|
|
93890
93895
|
var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
|
|
93891
93896
|
module3.exports = send;
|
|
93892
|
-
function send(req,
|
|
93893
|
-
return new SendStream(req,
|
|
93897
|
+
function send(req, path17, options) {
|
|
93898
|
+
return new SendStream(req, path17, options);
|
|
93894
93899
|
}
|
|
93895
|
-
function SendStream(req,
|
|
93900
|
+
function SendStream(req, path17, options) {
|
|
93896
93901
|
Stream.call(this);
|
|
93897
93902
|
var opts = options || {};
|
|
93898
93903
|
this.options = opts;
|
|
93899
|
-
this.path =
|
|
93904
|
+
this.path = path17;
|
|
93900
93905
|
this.req = req;
|
|
93901
93906
|
this._acceptRanges = opts.acceptRanges !== void 0 ? Boolean(opts.acceptRanges) : true;
|
|
93902
93907
|
this._cacheControl = opts.cacheControl !== void 0 ? Boolean(opts.cacheControl) : true;
|
|
@@ -94010,10 +94015,10 @@ var require_send = __commonJS({
|
|
|
94010
94015
|
var lastModified = this.res.getHeader("Last-Modified");
|
|
94011
94016
|
return parseHttpDate(lastModified) <= parseHttpDate(ifRange);
|
|
94012
94017
|
};
|
|
94013
|
-
SendStream.prototype.redirect = function redirect(
|
|
94018
|
+
SendStream.prototype.redirect = function redirect(path17) {
|
|
94014
94019
|
var res = this.res;
|
|
94015
94020
|
if (hasListeners(this, "directory")) {
|
|
94016
|
-
this.emit("directory", res,
|
|
94021
|
+
this.emit("directory", res, path17);
|
|
94017
94022
|
return;
|
|
94018
94023
|
}
|
|
94019
94024
|
if (this.hasTrailingSlash()) {
|
|
@@ -94033,38 +94038,38 @@ var require_send = __commonJS({
|
|
|
94033
94038
|
SendStream.prototype.pipe = function pipe2(res) {
|
|
94034
94039
|
var root3 = this._root;
|
|
94035
94040
|
this.res = res;
|
|
94036
|
-
var
|
|
94037
|
-
if (
|
|
94041
|
+
var path17 = decode2(this.path);
|
|
94042
|
+
if (path17 === -1) {
|
|
94038
94043
|
this.error(400);
|
|
94039
94044
|
return res;
|
|
94040
94045
|
}
|
|
94041
|
-
if (~
|
|
94046
|
+
if (~path17.indexOf("\0")) {
|
|
94042
94047
|
this.error(400);
|
|
94043
94048
|
return res;
|
|
94044
94049
|
}
|
|
94045
94050
|
var parts;
|
|
94046
94051
|
if (root3 !== null) {
|
|
94047
|
-
if (
|
|
94048
|
-
|
|
94052
|
+
if (path17) {
|
|
94053
|
+
path17 = normalize("." + sep + path17);
|
|
94049
94054
|
}
|
|
94050
|
-
if (UP_PATH_REGEXP.test(
|
|
94051
|
-
debug('malicious path "%s"',
|
|
94055
|
+
if (UP_PATH_REGEXP.test(path17)) {
|
|
94056
|
+
debug('malicious path "%s"', path17);
|
|
94052
94057
|
this.error(403);
|
|
94053
94058
|
return res;
|
|
94054
94059
|
}
|
|
94055
|
-
parts =
|
|
94056
|
-
|
|
94060
|
+
parts = path17.split(sep);
|
|
94061
|
+
path17 = normalize(join4(root3, path17));
|
|
94057
94062
|
} else {
|
|
94058
|
-
if (UP_PATH_REGEXP.test(
|
|
94059
|
-
debug('malicious path "%s"',
|
|
94063
|
+
if (UP_PATH_REGEXP.test(path17)) {
|
|
94064
|
+
debug('malicious path "%s"', path17);
|
|
94060
94065
|
this.error(403);
|
|
94061
94066
|
return res;
|
|
94062
94067
|
}
|
|
94063
|
-
parts = normalize(
|
|
94064
|
-
|
|
94068
|
+
parts = normalize(path17).split(sep);
|
|
94069
|
+
path17 = resolve4(path17);
|
|
94065
94070
|
}
|
|
94066
94071
|
if (containsDotFile(parts)) {
|
|
94067
|
-
debug('%s dotfile "%s"', this._dotfiles,
|
|
94072
|
+
debug('%s dotfile "%s"', this._dotfiles, path17);
|
|
94068
94073
|
switch (this._dotfiles) {
|
|
94069
94074
|
case "allow":
|
|
94070
94075
|
break;
|
|
@@ -94078,13 +94083,13 @@ var require_send = __commonJS({
|
|
|
94078
94083
|
}
|
|
94079
94084
|
}
|
|
94080
94085
|
if (this._index.length && this.hasTrailingSlash()) {
|
|
94081
|
-
this.sendIndex(
|
|
94086
|
+
this.sendIndex(path17);
|
|
94082
94087
|
return res;
|
|
94083
94088
|
}
|
|
94084
|
-
this.sendFile(
|
|
94089
|
+
this.sendFile(path17);
|
|
94085
94090
|
return res;
|
|
94086
94091
|
};
|
|
94087
|
-
SendStream.prototype.send = function send2(
|
|
94092
|
+
SendStream.prototype.send = function send2(path17, stat) {
|
|
94088
94093
|
var len = stat.size;
|
|
94089
94094
|
var options = this.options;
|
|
94090
94095
|
var opts = {};
|
|
@@ -94096,9 +94101,9 @@ var require_send = __commonJS({
|
|
|
94096
94101
|
this.headersAlreadySent();
|
|
94097
94102
|
return;
|
|
94098
94103
|
}
|
|
94099
|
-
debug('pipe "%s"',
|
|
94100
|
-
this.setHeader(
|
|
94101
|
-
this.type(
|
|
94104
|
+
debug('pipe "%s"', path17);
|
|
94105
|
+
this.setHeader(path17, stat);
|
|
94106
|
+
this.type(path17);
|
|
94102
94107
|
if (this.isConditionalGET()) {
|
|
94103
94108
|
if (this.isPreconditionFailure()) {
|
|
94104
94109
|
this.error(412);
|
|
@@ -94147,30 +94152,30 @@ var require_send = __commonJS({
|
|
|
94147
94152
|
res.end();
|
|
94148
94153
|
return;
|
|
94149
94154
|
}
|
|
94150
|
-
this.stream(
|
|
94155
|
+
this.stream(path17, opts);
|
|
94151
94156
|
};
|
|
94152
|
-
SendStream.prototype.sendFile = function sendFile(
|
|
94157
|
+
SendStream.prototype.sendFile = function sendFile(path17) {
|
|
94153
94158
|
var i = 0;
|
|
94154
94159
|
var self2 = this;
|
|
94155
|
-
debug('stat "%s"',
|
|
94156
|
-
|
|
94157
|
-
var pathEndsWithSep =
|
|
94158
|
-
if (err && err.code === "ENOENT" && !extname(
|
|
94160
|
+
debug('stat "%s"', path17);
|
|
94161
|
+
fs11.stat(path17, function onstat(err, stat) {
|
|
94162
|
+
var pathEndsWithSep = path17[path17.length - 1] === sep;
|
|
94163
|
+
if (err && err.code === "ENOENT" && !extname(path17) && !pathEndsWithSep) {
|
|
94159
94164
|
return next(err);
|
|
94160
94165
|
}
|
|
94161
94166
|
if (err) return self2.onStatError(err);
|
|
94162
|
-
if (stat.isDirectory()) return self2.redirect(
|
|
94167
|
+
if (stat.isDirectory()) return self2.redirect(path17);
|
|
94163
94168
|
if (pathEndsWithSep) return self2.error(404);
|
|
94164
|
-
self2.emit("file",
|
|
94165
|
-
self2.send(
|
|
94169
|
+
self2.emit("file", path17, stat);
|
|
94170
|
+
self2.send(path17, stat);
|
|
94166
94171
|
});
|
|
94167
94172
|
function next(err) {
|
|
94168
94173
|
if (self2._extensions.length <= i) {
|
|
94169
94174
|
return err ? self2.onStatError(err) : self2.error(404);
|
|
94170
94175
|
}
|
|
94171
|
-
var p =
|
|
94176
|
+
var p = path17 + "." + self2._extensions[i++];
|
|
94172
94177
|
debug('stat "%s"', p);
|
|
94173
|
-
|
|
94178
|
+
fs11.stat(p, function(err2, stat) {
|
|
94174
94179
|
if (err2) return next(err2);
|
|
94175
94180
|
if (stat.isDirectory()) return next();
|
|
94176
94181
|
self2.emit("file", p, stat);
|
|
@@ -94178,7 +94183,7 @@ var require_send = __commonJS({
|
|
|
94178
94183
|
});
|
|
94179
94184
|
}
|
|
94180
94185
|
};
|
|
94181
|
-
SendStream.prototype.sendIndex = function sendIndex(
|
|
94186
|
+
SendStream.prototype.sendIndex = function sendIndex(path17) {
|
|
94182
94187
|
var i = -1;
|
|
94183
94188
|
var self2 = this;
|
|
94184
94189
|
function next(err) {
|
|
@@ -94186,9 +94191,9 @@ var require_send = __commonJS({
|
|
|
94186
94191
|
if (err) return self2.onStatError(err);
|
|
94187
94192
|
return self2.error(404);
|
|
94188
94193
|
}
|
|
94189
|
-
var p = join4(
|
|
94194
|
+
var p = join4(path17, self2._index[i]);
|
|
94190
94195
|
debug('stat "%s"', p);
|
|
94191
|
-
|
|
94196
|
+
fs11.stat(p, function(err2, stat) {
|
|
94192
94197
|
if (err2) return next(err2);
|
|
94193
94198
|
if (stat.isDirectory()) return next();
|
|
94194
94199
|
self2.emit("file", p, stat);
|
|
@@ -94197,10 +94202,10 @@ var require_send = __commonJS({
|
|
|
94197
94202
|
}
|
|
94198
94203
|
next();
|
|
94199
94204
|
};
|
|
94200
|
-
SendStream.prototype.stream = function stream(
|
|
94205
|
+
SendStream.prototype.stream = function stream(path17, options) {
|
|
94201
94206
|
var self2 = this;
|
|
94202
94207
|
var res = this.res;
|
|
94203
|
-
var stream2 =
|
|
94208
|
+
var stream2 = fs11.createReadStream(path17, options);
|
|
94204
94209
|
this.emit("stream", stream2);
|
|
94205
94210
|
stream2.pipe(res);
|
|
94206
94211
|
function cleanup() {
|
|
@@ -94215,17 +94220,17 @@ var require_send = __commonJS({
|
|
|
94215
94220
|
self2.emit("end");
|
|
94216
94221
|
});
|
|
94217
94222
|
};
|
|
94218
|
-
SendStream.prototype.type = function type2(
|
|
94223
|
+
SendStream.prototype.type = function type2(path17) {
|
|
94219
94224
|
var res = this.res;
|
|
94220
94225
|
if (res.getHeader("Content-Type")) return;
|
|
94221
|
-
var ext = extname(
|
|
94226
|
+
var ext = extname(path17);
|
|
94222
94227
|
var type3 = mime.contentType(ext) || "application/octet-stream";
|
|
94223
94228
|
debug("content-type %s", type3);
|
|
94224
94229
|
res.setHeader("Content-Type", type3);
|
|
94225
94230
|
};
|
|
94226
|
-
SendStream.prototype.setHeader = function setHeader(
|
|
94231
|
+
SendStream.prototype.setHeader = function setHeader(path17, stat) {
|
|
94227
94232
|
var res = this.res;
|
|
94228
|
-
this.emit("headers", res,
|
|
94233
|
+
this.emit("headers", res, path17, stat);
|
|
94229
94234
|
if (this._acceptRanges && !res.getHeader("Accept-Ranges")) {
|
|
94230
94235
|
debug("accept ranges");
|
|
94231
94236
|
res.setHeader("Accept-Ranges", "bytes");
|
|
@@ -94283,9 +94288,9 @@ var require_send = __commonJS({
|
|
|
94283
94288
|
}
|
|
94284
94289
|
return err instanceof Error ? createError(status, err, { expose: false }) : createError(status, err);
|
|
94285
94290
|
}
|
|
94286
|
-
function decode2(
|
|
94291
|
+
function decode2(path17) {
|
|
94287
94292
|
try {
|
|
94288
|
-
return decodeURIComponent(
|
|
94293
|
+
return decodeURIComponent(path17);
|
|
94289
94294
|
} catch (err) {
|
|
94290
94295
|
return -1;
|
|
94291
94296
|
}
|
|
@@ -94429,7 +94434,7 @@ var require_response = __commonJS({
|
|
|
94429
94434
|
var http = __require("http");
|
|
94430
94435
|
var onFinished = require_on_finished();
|
|
94431
94436
|
var mime = require_mime_types();
|
|
94432
|
-
var
|
|
94437
|
+
var path16 = __require("path");
|
|
94433
94438
|
var pathIsAbsolute = __require("path").isAbsolute;
|
|
94434
94439
|
var statuses = require_statuses();
|
|
94435
94440
|
var sign = require_cookie_signature().sign;
|
|
@@ -94438,8 +94443,8 @@ var require_response = __commonJS({
|
|
|
94438
94443
|
var setCharset = require_utils4().setCharset;
|
|
94439
94444
|
var cookie = require_cookie();
|
|
94440
94445
|
var send = require_send();
|
|
94441
|
-
var extname =
|
|
94442
|
-
var resolve4 =
|
|
94446
|
+
var extname = path16.extname;
|
|
94447
|
+
var resolve4 = path16.resolve;
|
|
94443
94448
|
var vary = require_vary();
|
|
94444
94449
|
var { Buffer: Buffer2 } = __require("buffer");
|
|
94445
94450
|
var res = Object.create(http.ServerResponse.prototype);
|
|
@@ -94585,26 +94590,26 @@ var require_response = __commonJS({
|
|
|
94585
94590
|
this.type("txt");
|
|
94586
94591
|
return this.send(body);
|
|
94587
94592
|
};
|
|
94588
|
-
res.sendFile = function sendFile(
|
|
94593
|
+
res.sendFile = function sendFile(path17, options, callback) {
|
|
94589
94594
|
var done = callback;
|
|
94590
94595
|
var req = this.req;
|
|
94591
94596
|
var res2 = this;
|
|
94592
94597
|
var next = req.next;
|
|
94593
94598
|
var opts = options || {};
|
|
94594
|
-
if (!
|
|
94599
|
+
if (!path17) {
|
|
94595
94600
|
throw new TypeError("path argument is required to res.sendFile");
|
|
94596
94601
|
}
|
|
94597
|
-
if (typeof
|
|
94602
|
+
if (typeof path17 !== "string") {
|
|
94598
94603
|
throw new TypeError("path must be a string to res.sendFile");
|
|
94599
94604
|
}
|
|
94600
94605
|
if (typeof options === "function") {
|
|
94601
94606
|
done = options;
|
|
94602
94607
|
opts = {};
|
|
94603
94608
|
}
|
|
94604
|
-
if (!opts.root && !pathIsAbsolute(
|
|
94609
|
+
if (!opts.root && !pathIsAbsolute(path17)) {
|
|
94605
94610
|
throw new TypeError("path must be absolute or specify root to res.sendFile");
|
|
94606
94611
|
}
|
|
94607
|
-
var pathname = encodeURI(
|
|
94612
|
+
var pathname = encodeURI(path17);
|
|
94608
94613
|
opts.etag = this.app.enabled("etag");
|
|
94609
94614
|
var file = send(req, pathname, opts);
|
|
94610
94615
|
sendfile(res2, file, opts, function(err) {
|
|
@@ -94615,7 +94620,7 @@ var require_response = __commonJS({
|
|
|
94615
94620
|
}
|
|
94616
94621
|
});
|
|
94617
94622
|
};
|
|
94618
|
-
res.download = function download(
|
|
94623
|
+
res.download = function download(path17, filename, options, callback) {
|
|
94619
94624
|
var done = callback;
|
|
94620
94625
|
var name2 = filename;
|
|
94621
94626
|
var opts = options || null;
|
|
@@ -94632,7 +94637,7 @@ var require_response = __commonJS({
|
|
|
94632
94637
|
opts = filename;
|
|
94633
94638
|
}
|
|
94634
94639
|
var headers = {
|
|
94635
|
-
"Content-Disposition": contentDisposition(name2 ||
|
|
94640
|
+
"Content-Disposition": contentDisposition(name2 || path17)
|
|
94636
94641
|
};
|
|
94637
94642
|
if (opts && opts.headers) {
|
|
94638
94643
|
var keys4 = Object.keys(opts.headers);
|
|
@@ -94645,7 +94650,7 @@ var require_response = __commonJS({
|
|
|
94645
94650
|
}
|
|
94646
94651
|
opts = Object.create(opts);
|
|
94647
94652
|
opts.headers = headers;
|
|
94648
|
-
var fullPath = !opts.root ? resolve4(
|
|
94653
|
+
var fullPath = !opts.root ? resolve4(path17) : path17;
|
|
94649
94654
|
return this.sendFile(fullPath, opts, done);
|
|
94650
94655
|
};
|
|
94651
94656
|
res.contentType = res.type = function contentType(type2) {
|
|
@@ -94928,11 +94933,11 @@ var require_serve_static = __commonJS({
|
|
|
94928
94933
|
}
|
|
94929
94934
|
var forwardError = !fallthrough;
|
|
94930
94935
|
var originalUrl = parseUrl.original(req);
|
|
94931
|
-
var
|
|
94932
|
-
if (
|
|
94933
|
-
|
|
94936
|
+
var path16 = parseUrl(req).pathname;
|
|
94937
|
+
if (path16 === "/" && originalUrl.pathname.substr(-1) !== "/") {
|
|
94938
|
+
path16 = "";
|
|
94934
94939
|
}
|
|
94935
|
-
var stream = send(req,
|
|
94940
|
+
var stream = send(req, path16, opts);
|
|
94936
94941
|
stream.on("directory", onDirectory);
|
|
94937
94942
|
if (setHeaders) {
|
|
94938
94943
|
stream.on("headers", setHeaders);
|
|
@@ -98232,8 +98237,8 @@ var require_utils5 = __commonJS({
|
|
|
98232
98237
|
}
|
|
98233
98238
|
return ind;
|
|
98234
98239
|
}
|
|
98235
|
-
function removeDotSegments(
|
|
98236
|
-
let input =
|
|
98240
|
+
function removeDotSegments(path16) {
|
|
98241
|
+
let input = path16;
|
|
98237
98242
|
const output = [];
|
|
98238
98243
|
let nextSlash = -1;
|
|
98239
98244
|
let len = 0;
|
|
@@ -98432,8 +98437,8 @@ var require_schemes = __commonJS({
|
|
|
98432
98437
|
wsComponent.secure = void 0;
|
|
98433
98438
|
}
|
|
98434
98439
|
if (wsComponent.resourceName) {
|
|
98435
|
-
const [
|
|
98436
|
-
wsComponent.path =
|
|
98440
|
+
const [path16, query] = wsComponent.resourceName.split("?");
|
|
98441
|
+
wsComponent.path = path16 && path16 !== "/" ? path16 : void 0;
|
|
98437
98442
|
wsComponent.query = query;
|
|
98438
98443
|
wsComponent.resourceName = void 0;
|
|
98439
98444
|
}
|
|
@@ -98740,7 +98745,7 @@ var require_fast_uri = __commonJS({
|
|
|
98740
98745
|
query: void 0,
|
|
98741
98746
|
fragment: void 0
|
|
98742
98747
|
};
|
|
98743
|
-
let
|
|
98748
|
+
let isIP2 = false;
|
|
98744
98749
|
if (options.reference === "suffix") {
|
|
98745
98750
|
if (options.scheme) {
|
|
98746
98751
|
uri = options.scheme + ":" + uri;
|
|
@@ -98765,9 +98770,9 @@ var require_fast_uri = __commonJS({
|
|
|
98765
98770
|
if (ipv4result === false) {
|
|
98766
98771
|
const ipv6result = normalizeIPv6(parsed.host);
|
|
98767
98772
|
parsed.host = ipv6result.host.toLowerCase();
|
|
98768
|
-
|
|
98773
|
+
isIP2 = ipv6result.isIPV6;
|
|
98769
98774
|
} else {
|
|
98770
|
-
|
|
98775
|
+
isIP2 = true;
|
|
98771
98776
|
}
|
|
98772
98777
|
}
|
|
98773
98778
|
if (parsed.scheme === void 0 && parsed.userinfo === void 0 && parsed.host === void 0 && parsed.port === void 0 && parsed.query === void 0 && !parsed.path) {
|
|
@@ -98784,7 +98789,7 @@ var require_fast_uri = __commonJS({
|
|
|
98784
98789
|
}
|
|
98785
98790
|
const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
|
|
98786
98791
|
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
|
|
98787
|
-
if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) &&
|
|
98792
|
+
if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP2 === false && nonSimpleDomain(parsed.host)) {
|
|
98788
98793
|
try {
|
|
98789
98794
|
parsed.host = URL.domainToASCII(parsed.host.toLowerCase());
|
|
98790
98795
|
} catch (e) {
|
|
@@ -101795,12 +101800,12 @@ var require_dist3 = __commonJS({
|
|
|
101795
101800
|
throw new Error(`Unknown format "${name2}"`);
|
|
101796
101801
|
return f;
|
|
101797
101802
|
};
|
|
101798
|
-
function addFormats(ajv, list4,
|
|
101803
|
+
function addFormats(ajv, list4, fs11, exportName) {
|
|
101799
101804
|
var _a;
|
|
101800
101805
|
var _b;
|
|
101801
101806
|
(_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
101802
101807
|
for (const f of list4)
|
|
101803
|
-
ajv.addFormat(f,
|
|
101808
|
+
ajv.addFormat(f, fs11[f]);
|
|
101804
101809
|
}
|
|
101805
101810
|
module3.exports = exports3 = formatsPlugin;
|
|
101806
101811
|
Object.defineProperty(exports3, "__esModule", { value: true });
|
|
@@ -101900,9 +101905,159 @@ var init_launcher = __esm({
|
|
|
101900
101905
|
// src/server/index.ts
|
|
101901
101906
|
init_constants();
|
|
101902
101907
|
init_store();
|
|
101903
|
-
import
|
|
101908
|
+
import { isIP } from "net";
|
|
101909
|
+
import path15 from "path";
|
|
101904
101910
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
101905
101911
|
|
|
101912
|
+
// src/server/auth/token-store.ts
|
|
101913
|
+
init_env_paths();
|
|
101914
|
+
init_constants();
|
|
101915
|
+
import crypto6 from "crypto";
|
|
101916
|
+
import fs8 from "fs";
|
|
101917
|
+
import path12 from "path";
|
|
101918
|
+
function getTokenFilePath() {
|
|
101919
|
+
return path12.join(envPaths("tandem", { suffix: "" }).data, TOKEN_FILE_NAME);
|
|
101920
|
+
}
|
|
101921
|
+
async function readTokenFromFile() {
|
|
101922
|
+
const filePath = getTokenFilePath();
|
|
101923
|
+
try {
|
|
101924
|
+
const content3 = await fs8.promises.readFile(filePath, "utf8");
|
|
101925
|
+
if (process.platform !== "win32") {
|
|
101926
|
+
try {
|
|
101927
|
+
const stat = await fs8.promises.stat(filePath);
|
|
101928
|
+
if ((stat.mode & 63) !== 0) {
|
|
101929
|
+
console.error("[tandem] auth token file has insecure permissions; attempting chmod 0600");
|
|
101930
|
+
await fs8.promises.chmod(filePath, 384);
|
|
101931
|
+
}
|
|
101932
|
+
} catch {
|
|
101933
|
+
}
|
|
101934
|
+
}
|
|
101935
|
+
const trimmed = content3.trim();
|
|
101936
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
101937
|
+
} catch (err) {
|
|
101938
|
+
if (err.code === "ENOENT") return null;
|
|
101939
|
+
throw err;
|
|
101940
|
+
}
|
|
101941
|
+
}
|
|
101942
|
+
async function writeTokenToFile(token) {
|
|
101943
|
+
const filePath = getTokenFilePath();
|
|
101944
|
+
const dir = path12.dirname(filePath);
|
|
101945
|
+
await fs8.promises.mkdir(dir, { recursive: true });
|
|
101946
|
+
if (process.platform === "win32") {
|
|
101947
|
+
const localAppData = process.env.LOCALAPPDATA;
|
|
101948
|
+
if (localAppData) {
|
|
101949
|
+
const normalizedDir = path12.resolve(dir).toLowerCase();
|
|
101950
|
+
const normalizedLocal = path12.resolve(localAppData).toLowerCase();
|
|
101951
|
+
if (!normalizedDir.startsWith(normalizedLocal)) {
|
|
101952
|
+
console.warn(
|
|
101953
|
+
`[Tandem] auth token dir is outside %LOCALAPPDATA% (${dir}); NTFS ACL inheritance may not restrict access to current user`
|
|
101954
|
+
);
|
|
101955
|
+
}
|
|
101956
|
+
}
|
|
101957
|
+
}
|
|
101958
|
+
let fh;
|
|
101959
|
+
try {
|
|
101960
|
+
fh = await fs8.promises.open(filePath, "wx", 384);
|
|
101961
|
+
} catch (err) {
|
|
101962
|
+
if (err.code === "EEXIST") {
|
|
101963
|
+
const existing = await readTokenFromFile();
|
|
101964
|
+
if (existing) return existing;
|
|
101965
|
+
fh = await fs8.promises.open(filePath, "w");
|
|
101966
|
+
} else {
|
|
101967
|
+
throw err;
|
|
101968
|
+
}
|
|
101969
|
+
}
|
|
101970
|
+
try {
|
|
101971
|
+
await fh.writeFile(token, "utf8");
|
|
101972
|
+
} finally {
|
|
101973
|
+
await fh.close();
|
|
101974
|
+
}
|
|
101975
|
+
if (process.platform !== "win32") {
|
|
101976
|
+
await fs8.promises.chmod(filePath, 384);
|
|
101977
|
+
}
|
|
101978
|
+
return token;
|
|
101979
|
+
}
|
|
101980
|
+
async function loadOrCreateToken() {
|
|
101981
|
+
const envToken = process.env.TANDEM_AUTH_TOKEN;
|
|
101982
|
+
if (envToken && envToken.trim().length > 0) {
|
|
101983
|
+
console.error("[Tandem] auth token loaded from env");
|
|
101984
|
+
return envToken.trim();
|
|
101985
|
+
}
|
|
101986
|
+
const existing = await readTokenFromFile();
|
|
101987
|
+
if (existing) {
|
|
101988
|
+
console.error("[Tandem] auth token loaded from file");
|
|
101989
|
+
return existing;
|
|
101990
|
+
}
|
|
101991
|
+
let raw;
|
|
101992
|
+
try {
|
|
101993
|
+
raw = crypto6.randomBytes(32);
|
|
101994
|
+
} catch (err) {
|
|
101995
|
+
console.error("[Tandem] FATAL: crypto.randomBytes failed:", err);
|
|
101996
|
+
process.exit(1);
|
|
101997
|
+
}
|
|
101998
|
+
const token = raw.toString("base64url");
|
|
101999
|
+
try {
|
|
102000
|
+
const written = await writeTokenToFile(token);
|
|
102001
|
+
console.error("[Tandem] auth token written to file");
|
|
102002
|
+
return written;
|
|
102003
|
+
} catch (err) {
|
|
102004
|
+
console.error("[Tandem] FATAL: cannot write auth token:", err);
|
|
102005
|
+
process.exit(1);
|
|
102006
|
+
}
|
|
102007
|
+
}
|
|
102008
|
+
|
|
102009
|
+
// src/server/bind-check.ts
|
|
102010
|
+
import { networkInterfaces as osNetworkInterfaces } from "os";
|
|
102011
|
+
var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["127.0.0.1", "localhost", "::1"]);
|
|
102012
|
+
function isNonLoopback(bindHost) {
|
|
102013
|
+
return !LOOPBACK_HOSTS.has(bindHost);
|
|
102014
|
+
}
|
|
102015
|
+
function checkBindConfig(opts) {
|
|
102016
|
+
const { bindHost, port, authToken, allowUnauthLAN, lanIP } = opts;
|
|
102017
|
+
if (!isNonLoopback(bindHost)) {
|
|
102018
|
+
return { ok: true };
|
|
102019
|
+
}
|
|
102020
|
+
if (!authToken && !allowUnauthLAN) {
|
|
102021
|
+
return {
|
|
102022
|
+
ok: false,
|
|
102023
|
+
exitCode: 1,
|
|
102024
|
+
stderrMessage: `[tandem] Refusing to bind on ${bindHost}:${port} without an auth token.
|
|
102025
|
+
Set TANDEM_ALLOW_UNAUTHENTICATED_LAN=1 to explicitly opt in to insecure mode,
|
|
102026
|
+
or run \`tandem setup\` (CLI) / launch Tauri once to provision a token.
|
|
102027
|
+
`
|
|
102028
|
+
};
|
|
102029
|
+
}
|
|
102030
|
+
const isWildcard = bindHost === "0.0.0.0" || bindHost === "::";
|
|
102031
|
+
const getInterfaces = opts.networkInterfaces ?? osNetworkInterfaces;
|
|
102032
|
+
let detectedIPs = [];
|
|
102033
|
+
let resolvedLanIP;
|
|
102034
|
+
if (isWildcard) {
|
|
102035
|
+
const ifaceMap = getInterfaces();
|
|
102036
|
+
detectedIPs = Object.values(ifaceMap).flat().filter(
|
|
102037
|
+
(iface) => !!iface && iface.family === "IPv4" && !iface.internal
|
|
102038
|
+
).map((i) => i.address);
|
|
102039
|
+
if (detectedIPs.length > 1 && !lanIP) {
|
|
102040
|
+
return {
|
|
102041
|
+
ok: false,
|
|
102042
|
+
exitCode: 1,
|
|
102043
|
+
stderrMessage: `[tandem] Multiple non-internal IPv4 addresses detected: ${detectedIPs.join(", ")}.
|
|
102044
|
+
Set TANDEM_LAN_IP=<address> to specify which address to advertise.
|
|
102045
|
+
`,
|
|
102046
|
+
detectedIPs
|
|
102047
|
+
};
|
|
102048
|
+
}
|
|
102049
|
+
resolvedLanIP = lanIP ?? detectedIPs[0];
|
|
102050
|
+
} else {
|
|
102051
|
+
resolvedLanIP = bindHost;
|
|
102052
|
+
}
|
|
102053
|
+
let lanWarning;
|
|
102054
|
+
if (authToken) {
|
|
102055
|
+
lanWarning = `[tandem] WARNING: Tandem is listening on ${bindHost}:${port}. Tokens and document content transit unencrypted; do not use on untrusted networks (public Wi-Fi, shared LAN).
|
|
102056
|
+
`;
|
|
102057
|
+
}
|
|
102058
|
+
return { ok: true, lanWarning, resolvedLanIP, detectedIPs };
|
|
102059
|
+
}
|
|
102060
|
+
|
|
101906
102061
|
// src/server/error-filter.ts
|
|
101907
102062
|
function isKnownHocuspocusError(err) {
|
|
101908
102063
|
if (!(err instanceof Error)) return false;
|
|
@@ -102195,10 +102350,10 @@ function assignProp(target, prop, value) {
|
|
|
102195
102350
|
configurable: true
|
|
102196
102351
|
});
|
|
102197
102352
|
}
|
|
102198
|
-
function getElementAtPath(obj2,
|
|
102199
|
-
if (!
|
|
102353
|
+
function getElementAtPath(obj2, path16) {
|
|
102354
|
+
if (!path16)
|
|
102200
102355
|
return obj2;
|
|
102201
|
-
return
|
|
102356
|
+
return path16.reduce((acc, key) => acc?.[key], obj2);
|
|
102202
102357
|
}
|
|
102203
102358
|
function promiseAllObject(promisesObj) {
|
|
102204
102359
|
const keys4 = Object.keys(promisesObj);
|
|
@@ -102518,11 +102673,11 @@ function aborted(x, startIndex = 0) {
|
|
|
102518
102673
|
}
|
|
102519
102674
|
return false;
|
|
102520
102675
|
}
|
|
102521
|
-
function prefixIssues(
|
|
102676
|
+
function prefixIssues(path16, issues) {
|
|
102522
102677
|
return issues.map((iss) => {
|
|
102523
102678
|
var _a;
|
|
102524
102679
|
(_a = iss).path ?? (_a.path = []);
|
|
102525
|
-
iss.path.unshift(
|
|
102680
|
+
iss.path.unshift(path16);
|
|
102526
102681
|
return iss;
|
|
102527
102682
|
});
|
|
102528
102683
|
}
|
|
@@ -112153,7 +112308,7 @@ var StdioServerTransport = class {
|
|
|
112153
112308
|
import { Http2ServerRequest as Http2ServerRequest2, constants as h2constants } from "http2";
|
|
112154
112309
|
import { Http2ServerRequest } from "http2";
|
|
112155
112310
|
import { Readable } from "stream";
|
|
112156
|
-
import
|
|
112311
|
+
import crypto7 from "crypto";
|
|
112157
112312
|
var RequestError = class extends Error {
|
|
112158
112313
|
constructor(message, options) {
|
|
112159
112314
|
super(message, options);
|
|
@@ -112470,7 +112625,7 @@ var buildOutgoingHttpHeaders = (headers) => {
|
|
|
112470
112625
|
};
|
|
112471
112626
|
var X_ALREADY_SENT = "x-hono-already-sent";
|
|
112472
112627
|
if (typeof global.crypto === "undefined") {
|
|
112473
|
-
global.crypto =
|
|
112628
|
+
global.crypto = crypto7;
|
|
112474
112629
|
}
|
|
112475
112630
|
var outgoingEnded = /* @__PURE__ */ Symbol("outgoingEnded");
|
|
112476
112631
|
var incomingDraining = /* @__PURE__ */ Symbol("incomingDraining");
|
|
@@ -113453,9 +113608,149 @@ var StreamableHTTPServerTransport = class {
|
|
|
113453
113608
|
};
|
|
113454
113609
|
|
|
113455
113610
|
// src/server/mcp/server.ts
|
|
113611
|
+
init_constants();
|
|
113456
113612
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
113457
113613
|
import { createRequire } from "module";
|
|
113458
113614
|
|
|
113615
|
+
// src/server/auth/middleware.ts
|
|
113616
|
+
import { createHash as createHash3, timingSafeEqual } from "crypto";
|
|
113617
|
+
var _previousToken;
|
|
113618
|
+
function setPreviousToken(token, ttlMs = 6e4) {
|
|
113619
|
+
_previousToken = { value: token, expiresAt: Date.now() + ttlMs };
|
|
113620
|
+
}
|
|
113621
|
+
function getPreviousToken() {
|
|
113622
|
+
if (!_previousToken) return void 0;
|
|
113623
|
+
if (Date.now() >= _previousToken.expiresAt) {
|
|
113624
|
+
_previousToken = void 0;
|
|
113625
|
+
return void 0;
|
|
113626
|
+
}
|
|
113627
|
+
return _previousToken;
|
|
113628
|
+
}
|
|
113629
|
+
var RATE_LIMIT_WINDOW_MS = 10 * 60 * 1e3;
|
|
113630
|
+
var RATE_LIMIT_MAX_FAILURES = 5;
|
|
113631
|
+
var RATE_LIMIT_MAX_ENTRIES = 1e3;
|
|
113632
|
+
function rateLimitKey(addr) {
|
|
113633
|
+
if (!addr.includes(":")) return addr;
|
|
113634
|
+
const bare = addr.split("%")[0];
|
|
113635
|
+
const v4mapped = bare.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/i);
|
|
113636
|
+
if (v4mapped) return v4mapped[1];
|
|
113637
|
+
if (bare.includes("::")) {
|
|
113638
|
+
const [left, right] = bare.split("::");
|
|
113639
|
+
const head = left ? left.split(":") : [];
|
|
113640
|
+
const tail = right ? right.split(":") : [];
|
|
113641
|
+
const fill = Array(8 - head.length - tail.length).fill("0");
|
|
113642
|
+
const full = [...head, ...fill, ...tail];
|
|
113643
|
+
return full.slice(0, 4).join(":");
|
|
113644
|
+
}
|
|
113645
|
+
return addr.split(":").slice(0, 4).join(":");
|
|
113646
|
+
}
|
|
113647
|
+
var RateLimiter = class {
|
|
113648
|
+
failures = /* @__PURE__ */ new Map();
|
|
113649
|
+
/** Returns true if the address is over the rate limit. Always call before the token compare. */
|
|
113650
|
+
isOverLimit(addr) {
|
|
113651
|
+
const key = rateLimitKey(addr);
|
|
113652
|
+
const now = Date.now();
|
|
113653
|
+
const entry = this.failures.get(key);
|
|
113654
|
+
if (!entry) return false;
|
|
113655
|
+
if (now - entry.windowStart > RATE_LIMIT_WINDOW_MS) {
|
|
113656
|
+
this.failures.delete(key);
|
|
113657
|
+
return false;
|
|
113658
|
+
}
|
|
113659
|
+
return entry.count >= RATE_LIMIT_MAX_FAILURES;
|
|
113660
|
+
}
|
|
113661
|
+
/** Record a failure for the given address. */
|
|
113662
|
+
recordFailure(addr) {
|
|
113663
|
+
const key = rateLimitKey(addr);
|
|
113664
|
+
const now = Date.now();
|
|
113665
|
+
const existing = this.failures.get(key);
|
|
113666
|
+
if (existing && now - existing.windowStart <= RATE_LIMIT_WINDOW_MS) {
|
|
113667
|
+
existing.count += 1;
|
|
113668
|
+
} else {
|
|
113669
|
+
if (this.failures.size >= RATE_LIMIT_MAX_ENTRIES) {
|
|
113670
|
+
const firstKey = this.failures.keys().next().value;
|
|
113671
|
+
if (firstKey !== void 0) this.failures.delete(firstKey);
|
|
113672
|
+
}
|
|
113673
|
+
this.failures.set(key, { count: 1, windowStart: now });
|
|
113674
|
+
}
|
|
113675
|
+
}
|
|
113676
|
+
/** Reset failures on successful auth. */
|
|
113677
|
+
reset(addr) {
|
|
113678
|
+
this.failures.delete(rateLimitKey(addr));
|
|
113679
|
+
}
|
|
113680
|
+
};
|
|
113681
|
+
function normalizeAddress(addr) {
|
|
113682
|
+
if (addr === "::1") return "127.0.0.1";
|
|
113683
|
+
if (addr === "::ffff:127.0.0.1") return "127.0.0.1";
|
|
113684
|
+
return addr;
|
|
113685
|
+
}
|
|
113686
|
+
function isLoopback(remoteAddress) {
|
|
113687
|
+
if (remoteAddress === void 0) return false;
|
|
113688
|
+
return normalizeAddress(remoteAddress) === "127.0.0.1";
|
|
113689
|
+
}
|
|
113690
|
+
function sha256(s) {
|
|
113691
|
+
return createHash3("sha256").update(s, "utf8").digest();
|
|
113692
|
+
}
|
|
113693
|
+
function createAuthMiddleware(getToken) {
|
|
113694
|
+
const limiter = new RateLimiter();
|
|
113695
|
+
return (req, res, next) => {
|
|
113696
|
+
const addr = req.socket.remoteAddress;
|
|
113697
|
+
if (isLoopback(addr)) {
|
|
113698
|
+
next();
|
|
113699
|
+
return;
|
|
113700
|
+
}
|
|
113701
|
+
const normalizedAddr = addr !== void 0 ? normalizeAddress(addr) : "<unknown>";
|
|
113702
|
+
if (limiter.isOverLimit(normalizedAddr)) {
|
|
113703
|
+
res.status(429).json({ error: "Too Many Requests" });
|
|
113704
|
+
return;
|
|
113705
|
+
}
|
|
113706
|
+
const authHeader = req.headers.authorization;
|
|
113707
|
+
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
|
113708
|
+
limiter.recordFailure(normalizedAddr);
|
|
113709
|
+
console.error(`[tandem] auth: rejected request from ${normalizedAddr} (no/bad token header)`);
|
|
113710
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
113711
|
+
return;
|
|
113712
|
+
}
|
|
113713
|
+
const presented = authHeader.slice("Bearer ".length);
|
|
113714
|
+
if (!presented) {
|
|
113715
|
+
limiter.recordFailure(normalizedAddr);
|
|
113716
|
+
console.error(`[tandem] auth: rejected request from ${normalizedAddr} (no/bad token header)`);
|
|
113717
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
113718
|
+
return;
|
|
113719
|
+
}
|
|
113720
|
+
const storedToken = getToken();
|
|
113721
|
+
if (!storedToken) {
|
|
113722
|
+
limiter.recordFailure(normalizedAddr);
|
|
113723
|
+
console.error(`[tandem] auth: rejected request from ${normalizedAddr} (no server token)`);
|
|
113724
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
113725
|
+
return;
|
|
113726
|
+
}
|
|
113727
|
+
const presentedDigest = sha256(presented);
|
|
113728
|
+
function digestsMatch(candidate) {
|
|
113729
|
+
const candidateDigest = sha256(candidate);
|
|
113730
|
+
try {
|
|
113731
|
+
return timingSafeEqual(candidateDigest, presentedDigest);
|
|
113732
|
+
} catch {
|
|
113733
|
+
return false;
|
|
113734
|
+
}
|
|
113735
|
+
}
|
|
113736
|
+
let match = digestsMatch(storedToken);
|
|
113737
|
+
if (!match) {
|
|
113738
|
+
const prev = getPreviousToken();
|
|
113739
|
+
if (prev) {
|
|
113740
|
+
match = digestsMatch(prev.value);
|
|
113741
|
+
}
|
|
113742
|
+
}
|
|
113743
|
+
if (!match) {
|
|
113744
|
+
limiter.recordFailure(normalizedAddr);
|
|
113745
|
+
console.error(`[tandem] auth: rejected request from ${normalizedAddr} (invalid token)`);
|
|
113746
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
113747
|
+
return;
|
|
113748
|
+
}
|
|
113749
|
+
limiter.reset(normalizedAddr);
|
|
113750
|
+
next();
|
|
113751
|
+
};
|
|
113752
|
+
}
|
|
113753
|
+
|
|
113459
113754
|
// src/server/open-browser.ts
|
|
113460
113755
|
import { execFile } from "child_process";
|
|
113461
113756
|
function openBrowser(url) {
|
|
@@ -113505,14 +113800,20 @@ var PACKAGE_ROOT = resolve3(__dirname2, "../..");
|
|
|
113505
113800
|
var CHANNEL_DIST = resolve3(PACKAGE_ROOT, "dist/channel/index.js");
|
|
113506
113801
|
var MCP_URL = `http://localhost:${DEFAULT_MCP_PORT}`;
|
|
113507
113802
|
function buildMcpEntries(channelPath, opts = {}) {
|
|
113508
|
-
const
|
|
113509
|
-
|
|
113510
|
-
|
|
113803
|
+
const tandemEntry = { type: "http", url: `${MCP_URL}/mcp` };
|
|
113804
|
+
if (opts.token) {
|
|
113805
|
+
tandemEntry.headers = { Authorization: `Bearer ${opts.token}` };
|
|
113806
|
+
}
|
|
113807
|
+
const entries = { tandem: tandemEntry };
|
|
113511
113808
|
if (opts.withChannelShim) {
|
|
113809
|
+
const shimEnv = { TANDEM_URL: MCP_URL };
|
|
113810
|
+
if (opts.token) {
|
|
113811
|
+
shimEnv.TANDEM_AUTH_TOKEN = opts.token;
|
|
113812
|
+
}
|
|
113512
113813
|
entries["tandem-channel"] = {
|
|
113513
113814
|
command: opts.nodeBinary ?? "node",
|
|
113514
113815
|
args: [channelPath],
|
|
113515
|
-
env:
|
|
113816
|
+
env: shimEnv
|
|
113516
113817
|
};
|
|
113517
113818
|
}
|
|
113518
113819
|
return entries;
|
|
@@ -113626,8 +113927,8 @@ init_annotations();
|
|
|
113626
113927
|
init_document_model();
|
|
113627
113928
|
init_document_service();
|
|
113628
113929
|
init_response();
|
|
113629
|
-
import
|
|
113630
|
-
import
|
|
113930
|
+
import fs9 from "fs/promises";
|
|
113931
|
+
import path13 from "path";
|
|
113631
113932
|
async function applyChangesCore(documentId, author, backupPath) {
|
|
113632
113933
|
const r = requireDocument(documentId);
|
|
113633
113934
|
if (!r) throw Object.assign(new Error("No document is open."), { code: "NO_DOCUMENT" });
|
|
@@ -113646,7 +113947,7 @@ async function applyChangesCore(documentId, author, backupPath) {
|
|
|
113646
113947
|
});
|
|
113647
113948
|
}
|
|
113648
113949
|
if (backupPath) {
|
|
113649
|
-
const resolvedBp =
|
|
113950
|
+
const resolvedBp = path13.resolve(backupPath);
|
|
113650
113951
|
if (process.platform === "win32" && (resolvedBp.startsWith("\\\\") || resolvedBp.startsWith("//"))) {
|
|
113651
113952
|
throw Object.assign(new Error("UNC paths are not supported for security reasons."), {
|
|
113652
113953
|
code: "INVALID_PATH"
|
|
@@ -113702,21 +114003,21 @@ async function applyChangesCore(documentId, author, backupPath) {
|
|
|
113702
114003
|
throw Object.assign(new Error("No accepted suggestions to apply."), { code: "NO_SUGGESTIONS" });
|
|
113703
114004
|
}
|
|
113704
114005
|
const ydocFlatText = extractText(ydoc);
|
|
113705
|
-
const buffer3 = await
|
|
114006
|
+
const buffer3 = await fs9.readFile(filePath);
|
|
113706
114007
|
const result2 = await applyTrackedChanges(buffer3, suggestions, {
|
|
113707
114008
|
author: author ?? "Tandem Review",
|
|
113708
114009
|
ydocFlatText
|
|
113709
114010
|
});
|
|
113710
114011
|
let resolvedBackup = backupPath ?? filePath.replace(/\.docx$/i, ".backup.docx");
|
|
113711
114012
|
try {
|
|
113712
|
-
await
|
|
113713
|
-
const ext =
|
|
114013
|
+
await fs9.access(resolvedBackup);
|
|
114014
|
+
const ext = path13.extname(resolvedBackup);
|
|
113714
114015
|
const base = resolvedBackup.slice(0, -ext.length);
|
|
113715
114016
|
resolvedBackup = `${base}-${Date.now()}${ext}`;
|
|
113716
114017
|
} catch {
|
|
113717
114018
|
}
|
|
113718
|
-
await
|
|
113719
|
-
const [origStat, backupStat] = await Promise.all([
|
|
114019
|
+
await fs9.copyFile(filePath, resolvedBackup);
|
|
114020
|
+
const [origStat, backupStat] = await Promise.all([fs9.stat(filePath), fs9.stat(resolvedBackup)]);
|
|
113720
114021
|
if (origStat.size !== backupStat.size) {
|
|
113721
114022
|
throw Object.assign(new Error("Backup verification failed: file sizes do not match."), {
|
|
113722
114023
|
code: "BACKUP_FAILED"
|
|
@@ -113771,23 +114072,23 @@ function registerApplyTools(server) {
|
|
|
113771
114072
|
const { filePath } = r;
|
|
113772
114073
|
const backupPath = filePath.replace(/\.docx$/i, ".backup.docx");
|
|
113773
114074
|
try {
|
|
113774
|
-
await
|
|
114075
|
+
await fs9.access(backupPath);
|
|
113775
114076
|
} catch (err) {
|
|
113776
114077
|
if (err.code === "ENOENT") {
|
|
113777
114078
|
return mcpError("FILE_NOT_FOUND", `No backup file found at ${backupPath}`);
|
|
113778
114079
|
}
|
|
113779
114080
|
throw err;
|
|
113780
114081
|
}
|
|
113781
|
-
await
|
|
114082
|
+
await fs9.copyFile(backupPath, filePath);
|
|
113782
114083
|
const [backupStat, restoredStat] = await Promise.all([
|
|
113783
|
-
|
|
113784
|
-
|
|
114084
|
+
fs9.stat(backupPath),
|
|
114085
|
+
fs9.stat(filePath)
|
|
113785
114086
|
]);
|
|
113786
114087
|
if (backupStat.size !== restoredStat.size) {
|
|
113787
114088
|
throw new Error("Restore verification failed: file sizes do not match.");
|
|
113788
114089
|
}
|
|
113789
114090
|
return mcpSuccess({
|
|
113790
|
-
message: `Restored ${
|
|
114091
|
+
message: `Restored ${path13.basename(filePath)} from backup.`,
|
|
113791
114092
|
restoredFrom: backupPath
|
|
113792
114093
|
});
|
|
113793
114094
|
})
|
|
@@ -113796,9 +114097,12 @@ function registerApplyTools(server) {
|
|
|
113796
114097
|
|
|
113797
114098
|
// src/server/mcp/api-routes.ts
|
|
113798
114099
|
init_file_opener();
|
|
113799
|
-
function isHostAllowed(host) {
|
|
114100
|
+
function isHostAllowed(host, extraHosts = []) {
|
|
113800
114101
|
const reqHost = (host ?? "").split(":")[0];
|
|
113801
|
-
|
|
114102
|
+
if (reqHost === "localhost" || reqHost === "127.0.0.1" || reqHost === TAURI_HOSTNAME) {
|
|
114103
|
+
return true;
|
|
114104
|
+
}
|
|
114105
|
+
return extraHosts.includes(reqHost);
|
|
113802
114106
|
}
|
|
113803
114107
|
function escapeRegExp2(s) {
|
|
113804
114108
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -113829,7 +114133,7 @@ function isValidChannelPath(channelPath) {
|
|
|
113829
114133
|
if (hasUncPrefix(channelPath)) return false;
|
|
113830
114134
|
return true;
|
|
113831
114135
|
}
|
|
113832
|
-
async function runSetupHandler(input, homeOverride) {
|
|
114136
|
+
async function runSetupHandler(input, homeOverride, token) {
|
|
113833
114137
|
const { nodeBinary, channelPath } = input;
|
|
113834
114138
|
if (!nodeBinary || typeof nodeBinary !== "string") {
|
|
113835
114139
|
return { status: 400, body: { error: "BAD_REQUEST", message: "nodeBinary is required" } };
|
|
@@ -113853,7 +114157,7 @@ async function runSetupHandler(input, homeOverride) {
|
|
|
113853
114157
|
};
|
|
113854
114158
|
}
|
|
113855
114159
|
const targets = detectTargets({ homeOverride });
|
|
113856
|
-
const entries = buildMcpEntries(channelPath, { withChannelShim: true, nodeBinary });
|
|
114160
|
+
const entries = buildMcpEntries(channelPath, { withChannelShim: true, nodeBinary, token });
|
|
113857
114161
|
const configured = [];
|
|
113858
114162
|
const errors = [];
|
|
113859
114163
|
for (const target of targets) {
|
|
@@ -113908,21 +114212,24 @@ function errorCodeToHttpStatus(code3) {
|
|
|
113908
114212
|
return 500;
|
|
113909
114213
|
}
|
|
113910
114214
|
}
|
|
113911
|
-
function
|
|
113912
|
-
|
|
113913
|
-
|
|
113914
|
-
|
|
113915
|
-
|
|
113916
|
-
|
|
113917
|
-
|
|
113918
|
-
|
|
113919
|
-
|
|
113920
|
-
|
|
113921
|
-
|
|
113922
|
-
|
|
113923
|
-
|
|
113924
|
-
|
|
114215
|
+
function createApiMiddleware(extraHosts = []) {
|
|
114216
|
+
return function apiMiddlewareFn(req, res, next) {
|
|
114217
|
+
if (!isHostAllowed(req.headers.host, extraHosts)) {
|
|
114218
|
+
res.status(403).json({ error: "FORBIDDEN", message: "Host not allowed." });
|
|
114219
|
+
return;
|
|
114220
|
+
}
|
|
114221
|
+
const origin = req.headers.origin;
|
|
114222
|
+
res.header("Access-Control-Allow-Origin", isLocalhostOrigin(origin) ? origin : "null");
|
|
114223
|
+
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
114224
|
+
res.header("Access-Control-Allow-Headers", "Content-Type");
|
|
114225
|
+
if (req.method === "OPTIONS") {
|
|
114226
|
+
res.sendStatus(204);
|
|
114227
|
+
return;
|
|
114228
|
+
}
|
|
114229
|
+
next();
|
|
114230
|
+
};
|
|
113925
114231
|
}
|
|
114232
|
+
var apiMiddleware = createApiMiddleware();
|
|
113926
114233
|
function errorCodeToLabel(code3) {
|
|
113927
114234
|
switch (code3) {
|
|
113928
114235
|
case "ENOENT":
|
|
@@ -113997,10 +114304,11 @@ function notifyStreamHandler(req, res) {
|
|
|
113997
114304
|
});
|
|
113998
114305
|
console.error("[NotifyStream] Client connected to /api/notify-stream");
|
|
113999
114306
|
}
|
|
114000
|
-
function registerApiRoutes(app, largeBody) {
|
|
114001
|
-
|
|
114002
|
-
app.
|
|
114003
|
-
app.
|
|
114307
|
+
function registerApiRoutes(app, largeBody, token, mw = apiMiddleware, setCurrentToken = () => {
|
|
114308
|
+
}, getCurrentToken = () => null) {
|
|
114309
|
+
app.get("/api/notify-stream", mw, notifyStreamHandler);
|
|
114310
|
+
app.options("/api/open", mw);
|
|
114311
|
+
app.post("/api/open", mw, largeBody, async (req, res) => {
|
|
114004
114312
|
const { filePath, force } = req.body ?? {};
|
|
114005
114313
|
if (!filePath || typeof filePath !== "string") {
|
|
114006
114314
|
res.status(400).json({ error: "BAD_REQUEST", message: "filePath is required" });
|
|
@@ -114013,8 +114321,8 @@ function registerApiRoutes(app, largeBody) {
|
|
|
114013
114321
|
sendApiError(res, err);
|
|
114014
114322
|
}
|
|
114015
114323
|
});
|
|
114016
|
-
app.options("/api/close",
|
|
114017
|
-
app.post("/api/close",
|
|
114324
|
+
app.options("/api/close", mw);
|
|
114325
|
+
app.post("/api/close", mw, largeBody, async (req, res) => {
|
|
114018
114326
|
const { documentId } = req.body ?? {};
|
|
114019
114327
|
if (!documentId || typeof documentId !== "string") {
|
|
114020
114328
|
res.status(400).json({ error: "BAD_REQUEST", message: "documentId is required" });
|
|
@@ -114033,8 +114341,8 @@ function registerApiRoutes(app, largeBody) {
|
|
|
114033
114341
|
sendApiError(res, err);
|
|
114034
114342
|
}
|
|
114035
114343
|
});
|
|
114036
|
-
app.options("/api/save",
|
|
114037
|
-
app.post("/api/save",
|
|
114344
|
+
app.options("/api/save", mw);
|
|
114345
|
+
app.post("/api/save", mw, largeBody, async (req, res) => {
|
|
114038
114346
|
const { documentId } = req.body ?? {};
|
|
114039
114347
|
if (documentId !== void 0 && typeof documentId !== "string") {
|
|
114040
114348
|
res.status(400).json({ error: "BAD_REQUEST", message: "documentId must be a string" });
|
|
@@ -114052,8 +114360,8 @@ function registerApiRoutes(app, largeBody) {
|
|
|
114052
114360
|
sendApiError(res, err);
|
|
114053
114361
|
}
|
|
114054
114362
|
});
|
|
114055
|
-
app.options("/api/upload",
|
|
114056
|
-
app.post("/api/upload",
|
|
114363
|
+
app.options("/api/upload", mw);
|
|
114364
|
+
app.post("/api/upload", mw, largeBody, async (req, res) => {
|
|
114057
114365
|
const { fileName, content: content3 } = req.body ?? {};
|
|
114058
114366
|
if (!fileName || typeof fileName !== "string") {
|
|
114059
114367
|
res.status(400).json({ error: "BAD_REQUEST", message: "fileName is required" });
|
|
@@ -114076,8 +114384,8 @@ function registerApiRoutes(app, largeBody) {
|
|
|
114076
114384
|
sendApiError(res, err);
|
|
114077
114385
|
}
|
|
114078
114386
|
});
|
|
114079
|
-
app.options("/api/convert",
|
|
114080
|
-
app.post("/api/convert",
|
|
114387
|
+
app.options("/api/convert", mw);
|
|
114388
|
+
app.post("/api/convert", mw, largeBody, async (req, res) => {
|
|
114081
114389
|
const { documentId, outputPath } = req.body ?? {};
|
|
114082
114390
|
if (documentId !== void 0 && typeof documentId !== "string") {
|
|
114083
114391
|
res.status(400).json({ error: "BAD_REQUEST", message: "documentId must be a string" });
|
|
@@ -114097,14 +114405,14 @@ function registerApiRoutes(app, largeBody) {
|
|
|
114097
114405
|
sendApiError(res, err);
|
|
114098
114406
|
}
|
|
114099
114407
|
});
|
|
114100
|
-
app.get("/api/mode",
|
|
114408
|
+
app.get("/api/mode", mw, (_req, res) => {
|
|
114101
114409
|
const ctrlDoc = getOrCreateDocument(CTRL_ROOM);
|
|
114102
114410
|
const awareness = ctrlDoc.getMap(Y_MAP_USER_AWARENESS);
|
|
114103
114411
|
const mode = TandemModeSchema.catch(TANDEM_MODE_DEFAULT).parse(awareness.get(Y_MAP_MODE));
|
|
114104
114412
|
res.json({ mode });
|
|
114105
114413
|
});
|
|
114106
|
-
app.options("/api/apply-changes",
|
|
114107
|
-
app.post("/api/apply-changes",
|
|
114414
|
+
app.options("/api/apply-changes", mw);
|
|
114415
|
+
app.post("/api/apply-changes", mw, largeBody, async (req, res) => {
|
|
114108
114416
|
const { documentId, author, backupPath } = req.body ?? {};
|
|
114109
114417
|
if (documentId !== void 0 && typeof documentId !== "string") {
|
|
114110
114418
|
res.status(400).json({ error: "BAD_REQUEST", message: "documentId must be a string" });
|
|
@@ -114129,10 +114437,14 @@ function registerApiRoutes(app, largeBody) {
|
|
|
114129
114437
|
sendApiError(res, err);
|
|
114130
114438
|
}
|
|
114131
114439
|
});
|
|
114132
|
-
app.options("/api/setup",
|
|
114133
|
-
app.post("/api/setup",
|
|
114440
|
+
app.options("/api/setup", mw);
|
|
114441
|
+
app.post("/api/setup", mw, largeBody, async (req, res) => {
|
|
114134
114442
|
try {
|
|
114135
|
-
const result2 = await runSetupHandler(
|
|
114443
|
+
const result2 = await runSetupHandler(
|
|
114444
|
+
req.body ?? {},
|
|
114445
|
+
void 0,
|
|
114446
|
+
token
|
|
114447
|
+
);
|
|
114136
114448
|
res.status(result2.status).json(result2.body);
|
|
114137
114449
|
} catch (err) {
|
|
114138
114450
|
console.error("[Tandem] Setup handler threw:", err);
|
|
@@ -114142,8 +114454,8 @@ function registerApiRoutes(app, largeBody) {
|
|
|
114142
114454
|
});
|
|
114143
114455
|
}
|
|
114144
114456
|
});
|
|
114145
|
-
app.options("/api/annotation-reply",
|
|
114146
|
-
app.post("/api/annotation-reply",
|
|
114457
|
+
app.options("/api/annotation-reply", mw);
|
|
114458
|
+
app.post("/api/annotation-reply", mw, largeBody, (req, res) => {
|
|
114147
114459
|
const { annotationId, text: text5, documentId } = req.body ?? {};
|
|
114148
114460
|
if (!annotationId || typeof annotationId !== "string") {
|
|
114149
114461
|
res.status(400).json({ error: "BAD_REQUEST", message: "annotationId is required" });
|
|
@@ -114176,6 +114488,32 @@ function registerApiRoutes(app, largeBody) {
|
|
|
114176
114488
|
}
|
|
114177
114489
|
res.json({ data: { replyId: result2.replyId, annotationId } });
|
|
114178
114490
|
});
|
|
114491
|
+
app.options("/api/rotate-token", mw);
|
|
114492
|
+
app.post("/api/rotate-token", mw, largeBody, async (_req, res) => {
|
|
114493
|
+
if (process.env.TANDEM_AUTH_TOKEN) {
|
|
114494
|
+
res.status(409).json({ error: "Token is managed by Tauri; rotate via the app." });
|
|
114495
|
+
return;
|
|
114496
|
+
}
|
|
114497
|
+
const oldToken = getCurrentToken();
|
|
114498
|
+
let newToken;
|
|
114499
|
+
try {
|
|
114500
|
+
newToken = await readTokenFromFile();
|
|
114501
|
+
} catch (err) {
|
|
114502
|
+
console.error("[tandem] rotate-token: failed to read new token from disk:", err);
|
|
114503
|
+
res.status(500).json({ error: "INTERNAL", message: "Could not read new token from disk." });
|
|
114504
|
+
return;
|
|
114505
|
+
}
|
|
114506
|
+
if (!newToken) {
|
|
114507
|
+
res.status(500).json({ error: "INTERNAL", message: "No token found on disk after rotation." });
|
|
114508
|
+
return;
|
|
114509
|
+
}
|
|
114510
|
+
if (oldToken) {
|
|
114511
|
+
setPreviousToken(oldToken, 6e4);
|
|
114512
|
+
}
|
|
114513
|
+
setCurrentToken(newToken);
|
|
114514
|
+
console.error("[tandem] auth token rotated; 60-second grace window active for old token");
|
|
114515
|
+
res.json({ ok: true });
|
|
114516
|
+
});
|
|
114179
114517
|
}
|
|
114180
114518
|
|
|
114181
114519
|
// src/server/mcp/awareness.ts
|
|
@@ -114769,12 +115107,16 @@ async function startMcpServerStdio() {
|
|
|
114769
115107
|
const transport = new StdioServerTransport();
|
|
114770
115108
|
await server.connect(transport);
|
|
114771
115109
|
}
|
|
114772
|
-
async function startMcpServerHttp(port, host =
|
|
115110
|
+
async function startMcpServerHttp(port, host = DEFAULT_BIND_HOST, token, resolvedLanIP) {
|
|
114773
115111
|
mcpServer = createMcpServer();
|
|
114774
115112
|
const { default: express2 } = await Promise.resolve().then(() => __toESM(require_express2(), 1));
|
|
114775
115113
|
const app = express2();
|
|
115114
|
+
const tokenRef = { current: token ?? null };
|
|
115115
|
+
const authMiddleware = createAuthMiddleware(() => tokenRef.current);
|
|
115116
|
+
const lanAwareApiMiddleware = resolvedLanIP ? createApiMiddleware([resolvedLanIP]) : apiMiddleware;
|
|
114776
115117
|
const largeBody = express2.json({ limit: "70mb" });
|
|
114777
|
-
const
|
|
115118
|
+
const allowedHosts = resolvedLanIP ? ["127.0.0.1", "localhost", "[::1]", resolvedLanIP, TAURI_HOSTNAME] : void 0;
|
|
115119
|
+
const mcpApp = createMcpExpressApp({ host, ...allowedHosts ? { allowedHosts } : {} });
|
|
114778
115120
|
mcpApp.post("/mcp", async (req, res) => {
|
|
114779
115121
|
const body = req.body;
|
|
114780
115122
|
const isInit = isInitializeRequest(body) || Array.isArray(body) && body.some(isInitializeRequest);
|
|
@@ -114809,16 +115151,21 @@ async function startMcpServerHttp(port, host = "127.0.0.1") {
|
|
|
114809
115151
|
await currentTransport.handleRequest(req, res, req.body);
|
|
114810
115152
|
currentTransport = null;
|
|
114811
115153
|
});
|
|
115154
|
+
app.use("/mcp", authMiddleware);
|
|
115155
|
+
app.use("/api", authMiddleware);
|
|
114812
115156
|
app.get(
|
|
114813
115157
|
"/health",
|
|
114814
|
-
|
|
114815
|
-
(
|
|
114816
|
-
|
|
115158
|
+
lanAwareApiMiddleware,
|
|
115159
|
+
(req, res) => {
|
|
115160
|
+
const body = {
|
|
114817
115161
|
status: "ok",
|
|
114818
115162
|
version: APP_VERSION,
|
|
114819
|
-
transport: "http"
|
|
114820
|
-
|
|
114821
|
-
|
|
115163
|
+
transport: "http"
|
|
115164
|
+
};
|
|
115165
|
+
if (isLoopback(req.socket.remoteAddress)) {
|
|
115166
|
+
body.hasSession = currentTransport !== null;
|
|
115167
|
+
}
|
|
115168
|
+
res.json(body);
|
|
114822
115169
|
}
|
|
114823
115170
|
);
|
|
114824
115171
|
app.get(
|
|
@@ -114827,7 +115174,8 @@ async function startMcpServerHttp(port, host = "127.0.0.1") {
|
|
|
114827
115174
|
res.header("Access-Control-Allow-Origin", "*");
|
|
114828
115175
|
res.json({
|
|
114829
115176
|
resource: `http://localhost:${port}/mcp`,
|
|
114830
|
-
bearer_methods_supported: []
|
|
115177
|
+
bearer_methods_supported: ["header"],
|
|
115178
|
+
authorization_servers: [`http://localhost:${port}`]
|
|
114831
115179
|
});
|
|
114832
115180
|
}
|
|
114833
115181
|
);
|
|
@@ -114837,13 +115185,23 @@ async function startMcpServerHttp(port, host = "127.0.0.1") {
|
|
|
114837
115185
|
res.header("Access-Control-Allow-Origin", "*");
|
|
114838
115186
|
res.json({
|
|
114839
115187
|
resource: `http://localhost:${port}/mcp`,
|
|
114840
|
-
bearer_methods_supported: []
|
|
115188
|
+
bearer_methods_supported: ["header"],
|
|
115189
|
+
authorization_servers: [`http://localhost:${port}`]
|
|
114841
115190
|
});
|
|
114842
115191
|
}
|
|
114843
115192
|
);
|
|
114844
115193
|
app.use(mcpApp);
|
|
114845
|
-
registerApiRoutes(
|
|
114846
|
-
|
|
115194
|
+
registerApiRoutes(
|
|
115195
|
+
app,
|
|
115196
|
+
largeBody,
|
|
115197
|
+
token,
|
|
115198
|
+
lanAwareApiMiddleware,
|
|
115199
|
+
(newToken) => {
|
|
115200
|
+
tokenRef.current = newToken;
|
|
115201
|
+
},
|
|
115202
|
+
() => tokenRef.current
|
|
115203
|
+
);
|
|
115204
|
+
registerChannelRoutes(app, lanAwareApiMiddleware);
|
|
114847
115205
|
if (existsSync2(CLIENT_DIST)) {
|
|
114848
115206
|
app.use(express2.static(CLIENT_DIST, { index: "index.html" }));
|
|
114849
115207
|
const indexPath = join3(CLIENT_DIST, "index.html");
|
|
@@ -114958,12 +115316,12 @@ init_platform();
|
|
|
114958
115316
|
init_manager();
|
|
114959
115317
|
|
|
114960
115318
|
// src/server/version-check.ts
|
|
114961
|
-
import
|
|
114962
|
-
import
|
|
115319
|
+
import fs10 from "fs/promises";
|
|
115320
|
+
import path14 from "path";
|
|
114963
115321
|
async function checkVersionChange(currentVersion, versionFilePath) {
|
|
114964
115322
|
let storedVersion = null;
|
|
114965
115323
|
try {
|
|
114966
|
-
storedVersion = (await
|
|
115324
|
+
storedVersion = (await fs10.readFile(versionFilePath, "utf-8")).trim();
|
|
114967
115325
|
} catch (err) {
|
|
114968
115326
|
if (err.code !== "ENOENT") {
|
|
114969
115327
|
console.error("[Tandem] Failed to read last-seen-version:", err);
|
|
@@ -114971,8 +115329,8 @@ async function checkVersionChange(currentVersion, versionFilePath) {
|
|
|
114971
115329
|
}
|
|
114972
115330
|
const result2 = storedVersion === null ? "first-install" : storedVersion === currentVersion ? "current" : "upgraded";
|
|
114973
115331
|
if (result2 !== "current") {
|
|
114974
|
-
await
|
|
114975
|
-
await
|
|
115332
|
+
await fs10.mkdir(path14.dirname(versionFilePath), { recursive: true });
|
|
115333
|
+
await fs10.writeFile(versionFilePath, currentVersion, "utf-8");
|
|
114976
115334
|
}
|
|
114977
115335
|
return result2;
|
|
114978
115336
|
}
|
|
@@ -115121,6 +115479,43 @@ async function main2() {
|
|
|
115121
115479
|
detachObservers(docName);
|
|
115122
115480
|
}
|
|
115123
115481
|
);
|
|
115482
|
+
const bindHost = process.env.TANDEM_BIND_HOST ?? DEFAULT_BIND_HOST;
|
|
115483
|
+
const LOOPBACK_AND_WILDCARD = /* @__PURE__ */ new Set(["127.0.0.1", "localhost", "::1", "0.0.0.0", "::"]);
|
|
115484
|
+
if (!LOOPBACK_AND_WILDCARD.has(bindHost) && isIP(bindHost) === 0) {
|
|
115485
|
+
process.stderr.write(
|
|
115486
|
+
`[tandem] TANDEM_BIND_HOST="${bindHost}" is not a valid IP address. Exiting.
|
|
115487
|
+
`
|
|
115488
|
+
);
|
|
115489
|
+
process.exit(1);
|
|
115490
|
+
}
|
|
115491
|
+
const lanIP = process.env.TANDEM_LAN_IP || void 0;
|
|
115492
|
+
if (lanIP && isIP(lanIP) === 0) {
|
|
115493
|
+
process.stderr.write(`[tandem] TANDEM_LAN_IP="${lanIP}" is not a valid IP address. Exiting.
|
|
115494
|
+
`);
|
|
115495
|
+
process.exit(1);
|
|
115496
|
+
}
|
|
115497
|
+
const existingToken = process.env.TANDEM_AUTH_TOKEN || await readTokenFromFile();
|
|
115498
|
+
const bindCheck = checkBindConfig({
|
|
115499
|
+
bindHost,
|
|
115500
|
+
port: mcpPort,
|
|
115501
|
+
authToken: existingToken,
|
|
115502
|
+
// Fix 3: Only treat the env var as truthy when it equals exactly "1".
|
|
115503
|
+
allowUnauthLAN: process.env[TANDEM_ALLOW_UNAUTHENTICATED_LAN_ENV] === "1",
|
|
115504
|
+
lanIP
|
|
115505
|
+
});
|
|
115506
|
+
if (!bindCheck.ok) {
|
|
115507
|
+
process.stderr.write(bindCheck.stderrMessage ?? "");
|
|
115508
|
+
process.exit(bindCheck.exitCode ?? 1);
|
|
115509
|
+
}
|
|
115510
|
+
const authToken = await loadOrCreateToken();
|
|
115511
|
+
if (bindCheck.lanWarning) {
|
|
115512
|
+
process.stderr.write(bindCheck.lanWarning);
|
|
115513
|
+
}
|
|
115514
|
+
if (isNonLoopback(bindHost) && bindCheck.detectedIPs && bindCheck.detectedIPs.length === 1) {
|
|
115515
|
+
process.stderr.write(`[tandem] Detected LAN interface: ${bindCheck.detectedIPs[0]}
|
|
115516
|
+
`);
|
|
115517
|
+
}
|
|
115518
|
+
const resolvedLanIP = bindCheck.resolvedLanIP;
|
|
115124
115519
|
if (transportMode === "http") {
|
|
115125
115520
|
freePort(wsPort);
|
|
115126
115521
|
freePort(mcpPort);
|
|
@@ -115129,11 +115524,11 @@ async function main2() {
|
|
|
115129
115524
|
} catch (err) {
|
|
115130
115525
|
console.error(`[Tandem] ${err instanceof Error ? err.message : err} \u2014 proceeding anyway`);
|
|
115131
115526
|
}
|
|
115132
|
-
const projectRoot =
|
|
115527
|
+
const projectRoot = path15.resolve(path15.dirname(fileURLToPath5(import.meta.url)), "../..");
|
|
115133
115528
|
try {
|
|
115134
115529
|
const versionStatus = await checkVersionChange(APP_VERSION, LAST_SEEN_VERSION_FILE);
|
|
115135
115530
|
if (versionStatus === "upgraded") {
|
|
115136
|
-
await openFileByPath(
|
|
115531
|
+
await openFileByPath(path15.join(projectRoot, "CHANGELOG.md"));
|
|
115137
115532
|
console.error(`[Tandem] Opened CHANGELOG.md (upgraded to v${APP_VERSION})`);
|
|
115138
115533
|
}
|
|
115139
115534
|
} catch (err) {
|
|
@@ -115141,7 +115536,7 @@ async function main2() {
|
|
|
115141
115536
|
}
|
|
115142
115537
|
if (docCount() === 0 && !process.env.TANDEM_NO_SAMPLE) {
|
|
115143
115538
|
const sampleBase = process.env.TANDEM_DATA_DIR || projectRoot;
|
|
115144
|
-
const samplePath =
|
|
115539
|
+
const samplePath = path15.join(sampleBase, "sample/welcome.md");
|
|
115145
115540
|
try {
|
|
115146
115541
|
await openFileByPath(samplePath);
|
|
115147
115542
|
try {
|
|
@@ -115159,7 +115554,7 @@ async function main2() {
|
|
|
115159
115554
|
}
|
|
115160
115555
|
}
|
|
115161
115556
|
const [srv] = await Promise.all([
|
|
115162
|
-
startMcpServerHttp(mcpPort),
|
|
115557
|
+
startMcpServerHttp(mcpPort, bindHost, authToken, resolvedLanIP),
|
|
115163
115558
|
startHocuspocus(wsPort).then(() => {
|
|
115164
115559
|
console.error(`[Tandem] Hocuspocus WebSocket server running on ws://localhost:${wsPort}`);
|
|
115165
115560
|
})
|