@maintainer-pro/ai-bridge 0.1.16 → 0.1.19

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.
@@ -79,7 +79,8 @@ export function prepareShareHttpRequest(
79
79
  headers,
80
80
  publicBase,
81
81
  acceptEncodingHint,
82
- path
82
+ path,
83
+ portUrls
83
84
  ) {
84
85
  const out = { ...headers };
85
86
  const acceptEncoding = String(
@@ -116,6 +117,13 @@ export function prepareShareHttpRequest(
116
117
  /* ignore */
117
118
  }
118
119
  }
120
+ if (portUrls && typeof portUrls === "object") {
121
+ for (const key of Object.keys(out)) {
122
+ const lower = key.toLowerCase();
123
+ if (lower === "host" || lower === "content-length") continue;
124
+ out[key] = rewriteMappedLocalUrls(out[key], portUrls);
125
+ }
126
+ }
119
127
  return { headers: out, acceptEncoding, ifNoneMatch };
120
128
  }
121
129
 
@@ -123,14 +131,23 @@ export function shouldRewriteBody(headers) {
123
131
  const enc = headerGet(headers, "content-encoding").toLowerCase();
124
132
  if (enc && enc !== "identity") return false;
125
133
  const ct = headerGet(headers, "content-type").toLowerCase();
126
- return /html|javascript|ecmascript|css|json|svg|xml|text\/plain|text\/x-component|text\/x-ref|\brsc\b/.test(
134
+ if (/event-stream|octet-stream|image\/|audio\/|video\/|font\/|wasm/.test(ct)) {
135
+ return false;
136
+ }
137
+ return /html|javascript|ecmascript|css|json|svg|xml|text\/|urlencoded|x-component|x-ref|\brsc\b/.test(
127
138
  ct
128
139
  );
129
140
  }
130
141
 
131
142
  /** Redirects have no Content-Type, but Location still has to stay under the share prefix. */
132
143
  export function shouldProcessShareResponse(headers) {
133
- return Boolean(headerGet(headers, "location")) || shouldRewriteBody(headers);
144
+ if (headerGet(headers, "location")) return true;
145
+ if (shouldRewriteBody(headers)) return true;
146
+ const ct = headerGet(headers, "content-type").toLowerCase();
147
+ if (ct) return false;
148
+ const len = Number(headerGet(headers, "content-length") || 0);
149
+ if (len > 2 * 1024 * 1024) return false;
150
+ return true;
134
151
  }
135
152
 
136
153
  function isImmutableAssetPath(path) {
@@ -155,7 +172,8 @@ function isNoStorePath(path) {
155
172
  /\/@vite(?:\/|$)/.test(p) ||
156
173
  /\/@react-refresh/.test(p) ||
157
174
  /\/@fs\//.test(p) ||
158
- /\/@id\//.test(p)
175
+ /\/@id\//.test(p) ||
176
+ /\/__mp\//.test(p)
159
177
  );
160
178
  }
161
179
 
@@ -240,30 +258,274 @@ function notModifiedResult(headers, etag) {
240
258
  return { status: 304, headers: out, body: Buffer.alloc(0) };
241
259
  }
242
260
 
243
- function rewriteLocation(value, publicBase, port) {
244
- if (!publicBase) return value;
245
- const base = String(publicBase).replace(/\/$/, "");
261
+ function isLoopbackHost(host) {
262
+ const name = String(host || "").toLowerCase().replace(/^\[|\]$/g, "");
263
+ return (
264
+ name === "127.0.0.1" ||
265
+ name === "localhost" ||
266
+ name === "::1" ||
267
+ name === "0.0.0.0"
268
+ );
269
+ }
270
+
271
+ function mappedUrlForPort(portUrls, port) {
272
+ if (!portUrls || !port) return "";
273
+ const dest = portUrls[port] || portUrls[String(port)];
274
+ return dest ? String(dest).replace(/\/$/, "") : "";
275
+ }
276
+
277
+ function isProbablyUtf8Text(buf) {
278
+ if (!Buffer.isBuffer(buf) || !buf.length || buf.length > 8 * 1024 * 1024) {
279
+ return false;
280
+ }
281
+ const sample = buf.subarray(0, Math.min(buf.length, 4096));
282
+ if (sample.includes(0)) return false;
283
+ return true;
284
+ }
285
+
286
+ /**
287
+ * Replace app-list origins (`localhost:8080`, LAN IPs, hostnames) with the
288
+ * share URL for that port. Self-contained so the browser shim/SW can embed it.
289
+ *
290
+ * @param {string} text
291
+ * @param {Record<string, string> | null | undefined} portUrls
292
+ */
293
+ export function rewriteMappedLocalUrls(text, portUrls) {
294
+ if (!text || !portUrls) return text;
295
+ const ports = Object.keys(portUrls)
296
+ .map((key) => Number(key))
297
+ .filter((port) => Number.isInteger(port) && port > 0 && port <= 65535)
298
+ .sort((a, b) => b - a);
299
+ if (!ports.length) return text;
300
+ const localHost =
301
+ "(?:localhost|127\\.0\\.0\\.1|\\[::1\\]|::1|0\\.0\\.0\\.0|" +
302
+ "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" +
303
+ "192\\.168\\.\\d{1,3}\\.\\d{1,3}|" +
304
+ "172\\.(?:1[6-9]|2\\d|3[01])\\.\\d{1,3}\\.\\d{1,3}|" +
305
+ "169\\.254\\.\\d{1,3}\\.\\d{1,3}|" +
306
+ "[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\\.(?:local|lan|internal|home))?)";
307
+ const anyHost = "(?:[^\\s'\"\\\\/<>@:]+|\\[[0-9a-fA-F:]+\\])";
308
+ let out = String(text);
309
+ for (let i = 0; i < ports.length; i++) {
310
+ const port = ports[i];
311
+ const dest = String(portUrls[port] || portUrls[String(port)] || "").replace(
312
+ /\/$/,
313
+ ""
314
+ );
315
+ if (!dest) continue;
316
+ const destWs = dest.replace(/^http/i, "ws");
317
+ const destEsc = dest.replace(/\//g, "\\/");
318
+ const destWsEsc = destWs.replace(/\//g, "\\/");
319
+ const tail = "(?!\\d)";
320
+ const swap = function (matched, replacement) {
321
+ if (!matched) return matched;
322
+ if (dest.indexOf(matched) === 0 || destWs.indexOf(matched) === 0) {
323
+ return matched;
324
+ }
325
+ return replacement;
326
+ };
327
+ out = out.replace(new RegExp("https?://" + localHost + ":" + port + tail, "gi"), function (m) {
328
+ return swap(m, dest);
329
+ });
330
+ out = out.replace(new RegExp("wss?://" + localHost + ":" + port + tail, "gi"), function (m) {
331
+ return swap(m, destWs);
332
+ });
333
+ out = out.replace(new RegExp("https?:\\\\/\\\\/" + localHost + ":" + port + tail, "gi"), function (m) {
334
+ return swap(m, destEsc);
335
+ });
336
+ out = out.replace(new RegExp("wss?:\\\\/\\\\/" + localHost + ":" + port + tail, "gi"), function (m) {
337
+ return swap(m, destWsEsc);
338
+ });
339
+ out = out.replace(new RegExp("//" + localHost + ":" + port + tail, "gi"), function (m) {
340
+ return swap(m, dest.replace(/^https?:/i, ""));
341
+ });
342
+ out = out.replace(new RegExp("http://" + anyHost + ":" + port + tail, "gi"), function (m) {
343
+ return swap(m, dest);
344
+ });
345
+ out = out.replace(new RegExp("ws://" + anyHost + ":" + port + tail, "gi"), function (m) {
346
+ return swap(m, destWs);
347
+ });
348
+ out = out.replace(
349
+ new RegExp("(?<![\\w./])" + localHost + ":" + port + tail, "gi"),
350
+ function (m) {
351
+ return swap(m, dest);
352
+ }
353
+ );
354
+ }
355
+ return out;
356
+ }
357
+
358
+ /**
359
+ * @param {Buffer | string | null | undefined} body
360
+ * @param {Record<string, string>} headers
361
+ * @param {Record<string, string> | null | undefined} portUrls
362
+ */
363
+ export function rewriteShareRequestBody(body, headers, portUrls, publicBase) {
364
+ if (!body) return body;
365
+ const buf = Buffer.isBuffer(body) ? body : Buffer.from(body);
366
+ if (!buf.length) return buf;
367
+ if (!shouldRewriteBody(headers) && !isProbablyUtf8Text(buf)) return buf;
368
+ let text = buf.toString("utf8");
369
+ let next = text;
370
+ if (portUrls && Object.keys(portUrls).length) {
371
+ next = rewriteMappedLocalUrls(next, portUrls);
372
+ }
373
+ if (publicBase) next = rewriteShareOriginPaths(next, publicBase);
374
+ if (next === text) return buf;
375
+ return Buffer.from(next, "utf8");
376
+ }
377
+
378
+ export function shareTokenRoot(publicBase) {
246
379
  const prefix = proxyPathPrefix(publicBase);
380
+ if (!prefix) return "";
381
+ const parts = prefix.split("/").filter(Boolean);
382
+ if (parts[0] === "p" && parts[1]) return `/${parts[0]}/${parts[1]}/`;
383
+ return prefix.endsWith("/") ? prefix : `${prefix}/`;
384
+ }
385
+
386
+ export function shareShimScript(pathPrefix, portUrls) {
387
+ return `(${shareProxyShim.toString()})(${JSON.stringify(pathPrefix || "")},${JSON.stringify(portUrls || {})},${rewriteMappedLocalUrls.toString()});`;
388
+ }
389
+
390
+ export function shareServiceWorkerScript(portUrls, tokenRoot) {
391
+ return `(${shareServiceWorkerMain.toString()})(${JSON.stringify(portUrls || {})},${JSON.stringify(tokenRoot || "/")},${rewriteMappedLocalUrls.toString()});`;
392
+ }
393
+
394
+ function rewriteHeaderUrls(headers, publicBase, port, portUrls) {
395
+ if (headers.location) {
396
+ headers.location = rewriteLocation(
397
+ headers.location,
398
+ publicBase,
399
+ port,
400
+ portUrls
401
+ );
402
+ }
403
+ if (headers.link) {
404
+ headers.link = rewriteLinkHeader(headers.link, publicBase);
405
+ }
406
+ if (headers["access-control-allow-origin"]) {
407
+ headers["access-control-allow-origin"] = rewriteAllowOrigin(
408
+ headers["access-control-allow-origin"],
409
+ publicBase
410
+ );
411
+ }
412
+ if (portUrls && Object.keys(portUrls).length) {
413
+ for (const key of Object.keys(headers)) {
414
+ const lower = key.toLowerCase();
415
+ if (lower === "set-cookie" || lower === "content-length" || lower === "content-encoding") {
416
+ continue;
417
+ }
418
+ headers[key] = rewriteMappedLocalUrls(headers[key], portUrls);
419
+ }
420
+ }
421
+ if (publicBase) {
422
+ for (const key of Object.keys(headers)) {
423
+ const lower = key.toLowerCase();
424
+ if (lower === "set-cookie" || lower === "content-length" || lower === "content-encoding") {
425
+ continue;
426
+ }
427
+ headers[key] = rewriteShareOriginPaths(headers[key], publicBase);
428
+ }
429
+ }
430
+ }
431
+
432
+ /**
433
+ * Apps that honor X-Forwarded-Host emit https://admin-host/oauth2 instead of
434
+ * localhost:8080/oauth2. Put those back under /p/{token}/{slug} so the token
435
+ * and app route stay on the URL.
436
+ *
437
+ * @param {string} value
438
+ * @param {string} publicBase
439
+ */
440
+ export function prefixShareOriginUrl(value, publicBase) {
441
+ if (!value || !publicBase) return value;
442
+ try {
443
+ const base = new URL(String(publicBase).replace(/\/$/, ""));
444
+ const prefix = base.pathname.replace(/\/$/, "");
445
+ if (!prefix || prefix.indexOf("/p/") !== 0) return value;
446
+ const u = new URL(String(value), base);
447
+ if (u.protocol !== "http:" && u.protocol !== "https:") return value;
448
+ if (String(u.hostname || "").toLowerCase() !== String(base.hostname || "").toLowerCase()) {
449
+ return value;
450
+ }
451
+ const reqPort = u.port || (u.protocol === "https:" ? "443" : "80");
452
+ const basePort = base.port || (base.protocol === "https:" ? "443" : "80");
453
+ if (reqPort !== basePort) return value;
454
+ const path = u.pathname || "/";
455
+ if (path === prefix || path.indexOf(prefix + "/") === 0) return u.toString();
456
+ if (path.indexOf("/p/") === 0) return u.toString();
457
+ u.pathname = path === "/" ? prefix : prefix + path;
458
+ return u.toString();
459
+ } catch {
460
+ return value;
461
+ }
462
+ }
463
+
464
+ export function rewriteShareOriginPaths(text, publicBase) {
465
+ if (!text || !publicBase) return text;
466
+ let origin = "";
467
+ try {
468
+ origin = new URL(String(publicBase).replace(/\/$/, "")).origin;
469
+ } catch {
470
+ return text;
471
+ }
472
+ if (!origin) return text;
473
+ const originEsc = origin.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
474
+ const originSlashEsc = origin
475
+ .replace(/\//g, "\\/")
476
+ .replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
477
+ let out = String(text);
478
+ out = out.replace(new RegExp(originEsc + "(?:/[^\\s'\"<>\\\\]*)?", "gi"), function (matched) {
479
+ return prefixShareOriginUrl(matched, publicBase);
480
+ });
481
+ out = out.replace(
482
+ new RegExp(originSlashEsc + "(?:\\\\/[^\\s'\"<>]*)?", "gi"),
483
+ function (matched) {
484
+ const unescaped = matched.replace(/\\\//g, "/");
485
+ return prefixShareOriginUrl(unescaped, publicBase).replace(/\//g, "\\/");
486
+ }
487
+ );
488
+ return out;
489
+ }
490
+
491
+ function rewriteLocation(value, publicBase, port, portUrls) {
492
+ if (!publicBase && !(portUrls && Object.keys(portUrls).length)) return value;
247
493
  try {
248
494
  const u = new URL(value, `http://127.0.0.1:${Number(port) || 0}`);
249
- const host = String(u.hostname || "").toLowerCase();
250
- const local =
251
- host === "127.0.0.1" ||
252
- host === "localhost" ||
253
- host === "::1" ||
254
- host === "0.0.0.0";
255
- if (!local) return value;
256
- let path = u.pathname || "/";
257
- if (prefix && (path === prefix || path.startsWith(`${prefix}/`))) {
258
- path = path.slice(prefix.length) || "/";
259
- }
260
- return `${base}${path}${u.search}${u.hash}`;
495
+ if (isLoopbackHost(u.hostname)) {
496
+ const locPort = Number(u.port) || Number(port) || 0;
497
+ const mapped =
498
+ mappedUrlForPort(portUrls, locPort) ||
499
+ String(publicBase || "").replace(/\/$/, "");
500
+ if (!mapped) return value;
501
+ const prefix = proxyPathPrefix(mapped);
502
+ let path = u.pathname || "/";
503
+ if (prefix && (path === prefix || path.startsWith(`${prefix}/`))) {
504
+ path = path.slice(prefix.length) || "/";
505
+ }
506
+ if (path === "/") return `${mapped}${u.search}${u.hash}`;
507
+ return `${mapped}${path}${u.search}${u.hash}`;
508
+ }
509
+ const fromPorts = rewriteMappedLocalUrls(String(value), portUrls);
510
+ if (fromPorts !== String(value)) return fromPorts;
511
+ if (publicBase) return prefixShareOriginUrl(String(value), publicBase);
261
512
  } catch {
262
513
  /* keep */
263
514
  }
264
515
  return value;
265
516
  }
266
517
 
518
+ function rewriteAllowOrigin(value, publicBase) {
519
+ if (!value || value === "*" || !publicBase) return value;
520
+ try {
521
+ const u = new URL(value);
522
+ if (!isLoopbackHost(u.hostname)) return value;
523
+ return new URL(publicBase).origin;
524
+ } catch {
525
+ return value;
526
+ }
527
+ }
528
+
267
529
  function rewriteLinkHeader(value, publicBase) {
268
530
  const prefix = proxyPathPrefix(publicBase);
269
531
  if (!prefix || !value) return value;
@@ -686,11 +948,22 @@ function injectMaintainerProEmbed(html, aiPublicBase) {
686
948
  }
687
949
 
688
950
  /**
689
- * In-page rewrite: navigation stays under the share prefix; fetch/XHR/WebSocket
690
- * only touch same-origin Vite/Next assets. Other hosts are left unchanged.
951
+ * Intercept every browser request and map listed app ports onto share URLs.
691
952
  */
692
- function shareProxyShim(p) {
693
- if (!p) return;
953
+ function shareProxyShim(p, portMap, rewriteMappedLocalUrls) {
954
+ if (!p || window.__MP_SHARE_SHIM__) return;
955
+ window.__MP_SHARE_SHIM__ = 1;
956
+ window.__MP_PORT_MAP__ = portMap || {};
957
+ function rewriteText(text) {
958
+ if (typeof text !== "string" || !text || typeof rewriteMappedLocalUrls !== "function") {
959
+ return text;
960
+ }
961
+ try {
962
+ return rewriteMappedLocalUrls(text, portMap);
963
+ } catch (e) {
964
+ return text;
965
+ }
966
+ }
694
967
  function collapse(path) {
695
968
  var d = p + p;
696
969
  while (path.indexOf(d) === 0) path = p + path.slice(d.length);
@@ -713,13 +986,40 @@ function shareProxyShim(p) {
713
986
  if (path === p || path.indexOf(p + "/") === 0) return collapse(path);
714
987
  var root = p.slice(0, p.lastIndexOf("/"));
715
988
  if (root && (path === root || path.indexOf(root + "/") === 0)) return path;
989
+ if (path.indexOf("/p/") === 0) return path;
716
990
  if (path === "/api/v1" || path.indexOf("/api/v1/") === 0) return path;
717
991
  return collapse(p + path);
718
992
  }
719
993
  return path;
720
994
  }
995
+ function mapLocal(v) {
996
+ if (typeof v !== "string" || !v) return v;
997
+ if (
998
+ v.indexOf("blob:") === 0 ||
999
+ v.indexOf("data:") === 0 ||
1000
+ v.indexOf("javascript:") === 0
1001
+ ) {
1002
+ return v;
1003
+ }
1004
+ var raw = v;
1005
+ if (
1006
+ v.indexOf("://") < 0 &&
1007
+ /^(localhost|127\.0\.0\.1|\[::1\]|0\.0\.0\.0):\d+/i.test(v)
1008
+ ) {
1009
+ raw = "http://" + v;
1010
+ }
1011
+ var next = rewriteText(raw);
1012
+ if (next !== raw) return next;
1013
+ try {
1014
+ var u = new URL(v, location.href);
1015
+ var resolved = rewriteText(u.href);
1016
+ if (resolved !== u.href) return resolved;
1017
+ } catch (e) {}
1018
+ return v;
1019
+ }
721
1020
  function addNav(v) {
722
1021
  if (typeof v !== "string" || !v) return v;
1022
+ v = mapLocal(v);
723
1023
  if (v.charAt(0) === "/" && v.charAt(1) !== "/") return prefixPath(v);
724
1024
  try {
725
1025
  var nav = new URL(v, location.href);
@@ -730,23 +1030,7 @@ function shareProxyShim(p) {
730
1030
  return v;
731
1031
  }
732
1032
  function addNet(v) {
733
- if (typeof v !== "string" || !v) return v;
734
- try {
735
- if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(v) || v.indexOf("//") === 0) {
736
- var net = new URL(v, location.href);
737
- if (net.origin !== location.origin) return v;
738
- if (net.pathname === p || net.pathname.indexOf(p + "/") === 0) return v;
739
- if (!isAsset(net.pathname)) return v;
740
- net.pathname = prefixPath(net.pathname);
741
- return net.toString();
742
- }
743
- } catch (e) {}
744
- if (v.charAt(0) === "/" && v.charAt(1) !== "/") {
745
- if (v === p || v.indexOf(p + "/") === 0) return collapse(v);
746
- if (!isAsset(v)) return v;
747
- return prefixPath(v);
748
- }
749
- return v;
1033
+ return addNav(v);
750
1034
  }
751
1035
  function mapSel(sel) {
752
1036
  if (typeof sel !== "string") return sel;
@@ -776,11 +1060,22 @@ function shareProxyShim(p) {
776
1060
  patchQS(Element.prototype, "querySelectorAll");
777
1061
  var sa = Element.prototype.setAttribute;
778
1062
  Element.prototype.setAttribute = function (n, v) {
779
- if ((n === "src" || n === "href") && typeof v === "string") v = addNav(v);
1063
+ var name = String(n || "").toLowerCase();
1064
+ if (
1065
+ (name === "src" ||
1066
+ name === "href" ||
1067
+ name === "action" ||
1068
+ name === "poster" ||
1069
+ name === "data-src") &&
1070
+ typeof v === "string"
1071
+ ) {
1072
+ v = addNav(v);
1073
+ }
780
1074
  return sa.call(this, n, v);
781
1075
  };
782
1076
  function patchUrlProp(ctor, prop) {
783
1077
  try {
1078
+ if (!ctor || !ctor.prototype) return;
784
1079
  var d = Object.getOwnPropertyDescriptor(ctor.prototype, prop);
785
1080
  if (!d || !d.set) return;
786
1081
  Object.defineProperty(ctor.prototype, prop, {
@@ -795,6 +1090,13 @@ function shareProxyShim(p) {
795
1090
  }
796
1091
  patchUrlProp(HTMLScriptElement, "src");
797
1092
  patchUrlProp(HTMLLinkElement, "href");
1093
+ patchUrlProp(HTMLAnchorElement, "href");
1094
+ patchUrlProp(HTMLImageElement, "src");
1095
+ patchUrlProp(HTMLIFrameElement, "src");
1096
+ patchUrlProp(HTMLFormElement, "action");
1097
+ patchUrlProp(HTMLSourceElement, "src");
1098
+ patchUrlProp(HTMLVideoElement, "src");
1099
+ patchUrlProp(HTMLAudioElement, "src");
798
1100
  var f = window.fetch;
799
1101
  window.fetch = function (input, init) {
800
1102
  if (typeof input === "string") input = addNet(input);
@@ -803,6 +1105,9 @@ function shareProxyShim(p) {
803
1105
  } else if (typeof URL !== "undefined" && input instanceof URL) {
804
1106
  input = new URL(addNet(input.href));
805
1107
  }
1108
+ if (init && typeof init.body === "string") {
1109
+ init = Object.assign({}, init, { body: rewriteText(init.body) });
1110
+ }
806
1111
  return f.call(this, input, init);
807
1112
  };
808
1113
  var xo = XMLHttpRequest.prototype.open;
@@ -810,6 +1115,11 @@ function shareProxyShim(p) {
810
1115
  if (typeof u === "string") arguments[1] = addNet(u);
811
1116
  return xo.apply(this, arguments);
812
1117
  };
1118
+ var xs = XMLHttpRequest.prototype.send;
1119
+ XMLHttpRequest.prototype.send = function (body) {
1120
+ if (typeof body === "string") arguments[0] = rewriteText(body);
1121
+ return xs.apply(this, arguments);
1122
+ };
813
1123
  var ps = history.pushState.bind(history);
814
1124
  history.pushState = function (s, t, u) {
815
1125
  if (typeof u === "string") u = addNav(u);
@@ -823,6 +1133,7 @@ function shareProxyShim(p) {
823
1133
  var WS = window.WebSocket;
824
1134
  function WrappedWS(url, protocols) {
825
1135
  if (typeof url === "string") url = addNet(url);
1136
+ else if (typeof URL !== "undefined" && url instanceof URL) url = addNet(url.href);
826
1137
  return protocols !== undefined ? new WS(url, protocols) : new WS(url);
827
1138
  }
828
1139
  WrappedWS.prototype = WS.prototype;
@@ -831,6 +1142,30 @@ function shareProxyShim(p) {
831
1142
  WrappedWS.CLOSING = WS.CLOSING;
832
1143
  WrappedWS.CLOSED = WS.CLOSED;
833
1144
  window.WebSocket = WrappedWS;
1145
+ if (window.EventSource) {
1146
+ var ES = window.EventSource;
1147
+ function WrappedES(url, config) {
1148
+ if (typeof url === "string") url = addNet(url);
1149
+ return config !== undefined ? new ES(url, config) : new ES(url);
1150
+ }
1151
+ WrappedES.prototype = ES.prototype;
1152
+ WrappedES.CONNECTING = ES.CONNECTING;
1153
+ WrappedES.OPEN = ES.OPEN;
1154
+ WrappedES.CLOSED = ES.CLOSED;
1155
+ window.EventSource = WrappedES;
1156
+ }
1157
+ if (navigator.sendBeacon) {
1158
+ var sb = navigator.sendBeacon.bind(navigator);
1159
+ navigator.sendBeacon = function (url, data) {
1160
+ if (typeof data === "string") data = rewriteText(data);
1161
+ return sb(addNet(String(url)), data);
1162
+ };
1163
+ }
1164
+ var wo = window.open;
1165
+ window.open = function (url) {
1166
+ if (typeof url === "string") arguments[0] = addNav(url);
1167
+ return wo.apply(this, arguments);
1168
+ };
834
1169
  try {
835
1170
  var la = location.assign.bind(location);
836
1171
  location.assign = function (u) {
@@ -856,19 +1191,141 @@ function shareProxyShim(p) {
856
1191
  });
857
1192
  }
858
1193
  } catch (e) {}
1194
+ try {
1195
+ var tokenRoot = p.replace(/\/[^/]+$/, "/");
1196
+ if (navigator.serviceWorker && tokenRoot.indexOf("/p/") === 0) {
1197
+ navigator.serviceWorker.register(p + "/__mp/sw.js", { scope: tokenRoot });
1198
+ }
1199
+ } catch (e) {}
1200
+ }
1201
+
1202
+ function shareServiceWorkerMain(portMap, tokenRoot, rewriteMappedLocalUrls) {
1203
+ self.addEventListener("install", function (event) {
1204
+ event.waitUntil(self.skipWaiting());
1205
+ });
1206
+ self.addEventListener("activate", function (event) {
1207
+ event.waitUntil(self.clients.claim());
1208
+ });
1209
+ function rewriteText(text) {
1210
+ if (typeof text !== "string" || !text) return text;
1211
+ try {
1212
+ return rewriteMappedLocalUrls(text, portMap);
1213
+ } catch (e) {
1214
+ return text;
1215
+ }
1216
+ }
1217
+ function appPrefixFromHref(href) {
1218
+ try {
1219
+ var u = new URL(String(href || ""));
1220
+ var parts = u.pathname.split("/").filter(Boolean);
1221
+ if (parts[0] === "p" && parts[1] && parts[2]) {
1222
+ return "/" + parts[0] + "/" + parts[1] + "/" + parts[2];
1223
+ }
1224
+ } catch (e) {}
1225
+ return "";
1226
+ }
1227
+ function prefixWith(url, prefix) {
1228
+ if (!prefix) return url;
1229
+ try {
1230
+ var u = new URL(url, self.location.href);
1231
+ if (u.origin !== self.location.origin) return url;
1232
+ if (u.pathname.indexOf("/p/") === 0) return url;
1233
+ if (u.pathname === prefix || u.pathname.indexOf(prefix + "/") === 0) return url;
1234
+ u.pathname = u.pathname === "/" ? prefix : prefix + u.pathname;
1235
+ return u.toString();
1236
+ } catch (e) {}
1237
+ return url;
1238
+ }
1239
+ function mapUrl(v, prefix) {
1240
+ if (typeof v !== "string" || !v) return v;
1241
+ if (v.indexOf("/__mp/") !== -1) return v;
1242
+ return prefixWith(rewriteText(v), prefix);
1243
+ }
1244
+ self.addEventListener("fetch", function (event) {
1245
+ var req = event.request;
1246
+ if (req.url.indexOf("/__mp/") !== -1) return;
1247
+ event.respondWith(
1248
+ (async function () {
1249
+ var client = null;
1250
+ try {
1251
+ if (event.clientId) client = await self.clients.get(event.clientId);
1252
+ } catch (e) {}
1253
+ var prefix =
1254
+ appPrefixFromHref(client && client.url) ||
1255
+ appPrefixFromHref(req.referrer) ||
1256
+ appPrefixFromHref(self.registration && self.registration.scope);
1257
+ var url = mapUrl(req.url, prefix);
1258
+ var method = req.method;
1259
+ var headers = new Headers(req.headers);
1260
+ var body;
1261
+ if (method !== "GET" && method !== "HEAD") {
1262
+ try {
1263
+ var ct = headers.get("content-type") || "";
1264
+ if (/json|text|xml|urlencoded|javascript/.test(ct) || !ct) {
1265
+ var text = await req.clone().text();
1266
+ var next = rewriteText(text);
1267
+ if (next !== text) body = next;
1268
+ }
1269
+ } catch (e) {}
1270
+ }
1271
+ var init = {
1272
+ method: method,
1273
+ headers: headers,
1274
+ credentials: req.credentials,
1275
+ redirect: req.redirect,
1276
+ referrer: req.referrer,
1277
+ };
1278
+ if (req.mode && req.mode !== "navigate") init.mode = req.mode;
1279
+ if (body !== undefined) init.body = body;
1280
+ else if (method !== "GET" && method !== "HEAD") {
1281
+ try {
1282
+ init.body = await req.blob();
1283
+ } catch (e) {}
1284
+ }
1285
+ var res = await fetch(new Request(url, init));
1286
+ var outHeaders = new Headers(res.headers);
1287
+ var loc = outHeaders.get("location");
1288
+ if (loc) outHeaders.set("location", mapUrl(loc, prefix));
1289
+ var resType = res.headers.get("content-type") || "";
1290
+ if (
1291
+ !/html|javascript|ecmascript|json|css|xml|svg|text|urlencoded/.test(resType)
1292
+ ) {
1293
+ if (loc && outHeaders.get("location") !== loc) {
1294
+ return new Response(res.body, {
1295
+ status: res.status,
1296
+ statusText: res.statusText,
1297
+ headers: outHeaders,
1298
+ });
1299
+ }
1300
+ return res;
1301
+ }
1302
+ var resText = await res.text();
1303
+ var mapped = rewriteText(resText);
1304
+ outHeaders.delete("content-length");
1305
+ outHeaders.delete("content-encoding");
1306
+ return new Response(mapped, {
1307
+ status: res.status,
1308
+ statusText: res.statusText,
1309
+ headers: outHeaders,
1310
+ });
1311
+ })()
1312
+ );
1313
+ });
859
1314
  }
860
1315
 
861
1316
  function injectNextProxyShim(html, publicBase) {
862
1317
  const prefix = proxyPathPrefix(publicBase);
863
- if (
864
- !prefix ||
865
- html.includes("data-mp-proxy-next") ||
866
- (!isNextDocument(html) && !isViteDocument(html))
867
- ) {
1318
+ if (!prefix || html.includes("data-mp-proxy-next")) {
868
1319
  return html;
869
1320
  }
870
- const script = `<script data-mp-proxy-next>(${shareProxyShim.toString()})(${JSON.stringify(prefix)})</script>`;
871
- return html.replace(/<head([^>]*)>/i, `<head$1>${script}`);
1321
+ const script = `<script data-mp-proxy-next src="${prefix}/__mp/shim.js"><\/script>`;
1322
+ if (/<head[^>]*>/i.test(html)) {
1323
+ return html.replace(/<head([^>]*)>/i, `<head$1>${script}`);
1324
+ }
1325
+ if (/<body[^>]*>/i.test(html)) {
1326
+ return html.replace(/<body([^>]*)>/i, `<body$1>${script}`);
1327
+ }
1328
+ return `${script}${html}`;
872
1329
  }
873
1330
 
874
1331
  /**
@@ -885,6 +1342,7 @@ function injectNextProxyShim(html, publicBase) {
885
1342
  * acceptEncoding?: string,
886
1343
  * ifNoneMatch?: string,
887
1344
  * port?: number,
1345
+ * portUrls?: Record<string, string>,
888
1346
  * }} opts
889
1347
  * @returns {{ status: number, headers: Record<string, string>, body: Buffer }}
890
1348
  */
@@ -896,6 +1354,8 @@ export function processShareHttpResponse(opts) {
896
1354
  const acceptEncoding = String(opts?.acceptEncoding || "");
897
1355
  const ifNoneMatch = String(opts?.ifNoneMatch || "");
898
1356
  const port = Number(opts?.port) || 0;
1357
+ const portUrls =
1358
+ opts?.portUrls && typeof opts.portUrls === "object" ? opts.portUrls : {};
899
1359
  let status =
900
1360
  typeof opts?.status === "number" && opts.status >= 100 ? opts.status : 200;
901
1361
  const headers = lowerHeaders(opts?.headers || {});
@@ -903,12 +1363,7 @@ export function processShareHttpResponse(opts) {
903
1363
  ? opts.body
904
1364
  : Buffer.from(opts?.body || "");
905
1365
 
906
- if (headers.location) {
907
- headers.location = rewriteLocation(headers.location, publicBase, port);
908
- }
909
- if (headers.link) {
910
- headers.link = rewriteLinkHeader(headers.link, publicBase);
911
- }
1366
+ rewriteHeaderUrls(headers, publicBase, port, portUrls);
912
1367
 
913
1368
  const cachedKey = rewriteCacheKey(publicBase, path);
914
1369
  const hit =
@@ -933,10 +1388,27 @@ export function processShareHttpResponse(opts) {
933
1388
 
934
1389
  let text = payload.toString("utf8");
935
1390
  let mutated = false;
936
- if (publicBase && shouldRewriteBody(headers)) {
1391
+ const rewriteTextBody =
1392
+ shouldRewriteBody(headers) ||
1393
+ (!headerGet(headers, "content-type") && isProbablyUtf8Text(payload));
1394
+ if (publicBase && rewriteTextBody) {
937
1395
  text = prefixRootPaths(text, publicBase, headers["content-type"] || "");
938
1396
  mutated = true;
939
1397
  }
1398
+ if (Object.keys(portUrls).length && rewriteTextBody) {
1399
+ const mapped = rewriteMappedLocalUrls(text, portUrls);
1400
+ if (mapped !== text) {
1401
+ text = mapped;
1402
+ mutated = true;
1403
+ }
1404
+ }
1405
+ if (publicBase && rewriteTextBody) {
1406
+ const prefixed = rewriteShareOriginPaths(text, publicBase);
1407
+ if (prefixed !== text) {
1408
+ text = prefixed;
1409
+ mutated = true;
1410
+ }
1411
+ }
940
1412
  if (aiPublicBase) {
941
1413
  const withShareUrls = rewriteLocalSidecarUrls(text, aiPublicBase, publicBase);
942
1414
  if (withShareUrls !== text) {
@@ -951,12 +1423,8 @@ export function processShareHttpResponse(opts) {
951
1423
  mutated = true;
952
1424
  }
953
1425
  }
954
- if (
955
- publicBase &&
956
- isHtmlDocument(headers, text) &&
957
- (isNextDocument(text) || isViteDocument(text))
958
- ) {
959
- const next = injectNextProxyShim(text, publicBase);
1426
+ if (publicBase && isHtmlDocument(headers, text)) {
1427
+ const next = injectNextProxyShim(text, publicBase, portUrls);
960
1428
  if (next !== text) {
961
1429
  text = next;
962
1430
  mutated = true;