@maintainer-pro/ai-bridge 0.1.13 → 0.1.15
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/package.json +3 -3
- package/src/daemon.mjs +13 -2
- package/src/share-rewrite.mjs +298 -38
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maintainer-pro/ai-bridge",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.15",
|
|
4
4
|
"description": "Local bridge daemon that pairs a machine to Maintainer Pro and configures multiple client sandboxes.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"maintainer-pro",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"node": ">=22"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@maintainer-pro/ai-cli": "^0.1.
|
|
32
|
-
"@maintainer-pro/ai-server": "^0.1.
|
|
31
|
+
"@maintainer-pro/ai-cli": "^0.1.8",
|
|
32
|
+
"@maintainer-pro/ai-server": "^0.1.7"
|
|
33
33
|
}
|
|
34
34
|
}
|
package/src/daemon.mjs
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
lookupShareResponse,
|
|
24
24
|
prepareShareHttpRequest,
|
|
25
25
|
processShareHttpResponse,
|
|
26
|
-
|
|
26
|
+
shouldProcessShareResponse,
|
|
27
27
|
} from "./share-rewrite.mjs";
|
|
28
28
|
|
|
29
29
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -2565,7 +2565,7 @@ function handleProxyHttpFromAdmin(msg) {
|
|
|
2565
2565
|
}
|
|
2566
2566
|
const status = res.statusCode || 502;
|
|
2567
2567
|
applyShareCacheHeaders(outHeaders, path);
|
|
2568
|
-
if (
|
|
2568
|
+
if (shouldProcessShareResponse(outHeaders)) {
|
|
2569
2569
|
/** @type {Buffer[]} */
|
|
2570
2570
|
const chunks = [];
|
|
2571
2571
|
res.on("data", (chunk) => {
|
|
@@ -5200,6 +5200,12 @@ async function main() {
|
|
|
5200
5200
|
|
|
5201
5201
|
if (args.pair || !cfg.token || !cfg.adminUrl) {
|
|
5202
5202
|
cfg = await pairFlow(args);
|
|
5203
|
+
} else if (typeof args.adminUrl === "string" && args.adminUrl.trim()) {
|
|
5204
|
+
const next = args.adminUrl.replace(/\/$/, "");
|
|
5205
|
+
if (cfg.adminUrl && cfg.adminUrl !== next) {
|
|
5206
|
+
log(`admin URL ${cfg.adminUrl} → ${next}`);
|
|
5207
|
+
}
|
|
5208
|
+
cfg.adminUrl = next;
|
|
5203
5209
|
}
|
|
5204
5210
|
|
|
5205
5211
|
cfg.noAiServer = Boolean(args.noAiServer);
|
|
@@ -5557,6 +5563,11 @@ async function main() {
|
|
|
5557
5563
|
clearHeartbeatTimer();
|
|
5558
5564
|
clearPingTimer();
|
|
5559
5565
|
if (socket === ws) socket = null;
|
|
5566
|
+
if (Number(code) === 1008) {
|
|
5567
|
+
warn(
|
|
5568
|
+
"Admin rejected this computer’s token. This admin is not the one in ~/.maintainer-pro/bridge.json. Generate a new pair code (Admin → Bridges → Add computer) and run the pair command."
|
|
5569
|
+
);
|
|
5570
|
+
}
|
|
5560
5571
|
scheduleReconnect(code, reason);
|
|
5561
5572
|
};
|
|
5562
5573
|
|
package/src/share-rewrite.mjs
CHANGED
|
@@ -128,6 +128,11 @@ export function shouldRewriteBody(headers) {
|
|
|
128
128
|
);
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
/** Redirects have no Content-Type, but Location still has to stay under the share prefix. */
|
|
132
|
+
export function shouldProcessShareResponse(headers) {
|
|
133
|
+
return Boolean(headerGet(headers, "location")) || shouldRewriteBody(headers);
|
|
134
|
+
}
|
|
135
|
+
|
|
131
136
|
function isImmutableAssetPath(path) {
|
|
132
137
|
const p = String(path || "").split("?")[0] || "";
|
|
133
138
|
return (
|
|
@@ -237,17 +242,36 @@ function notModifiedResult(headers, etag) {
|
|
|
237
242
|
|
|
238
243
|
function rewriteLocation(value, publicBase, port) {
|
|
239
244
|
if (!publicBase) return value;
|
|
245
|
+
const base = String(publicBase).replace(/\/$/, "");
|
|
246
|
+
const prefix = proxyPathPrefix(publicBase);
|
|
240
247
|
try {
|
|
241
248
|
const u = new URL(value, `http://127.0.0.1:${Number(port) || 0}`);
|
|
242
|
-
|
|
243
|
-
|
|
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) || "/";
|
|
244
259
|
}
|
|
260
|
+
return `${base}${path}${u.search}${u.hash}`;
|
|
245
261
|
} catch {
|
|
246
262
|
/* keep */
|
|
247
263
|
}
|
|
248
264
|
return value;
|
|
249
265
|
}
|
|
250
266
|
|
|
267
|
+
function rewriteLinkHeader(value, publicBase) {
|
|
268
|
+
const prefix = proxyPathPrefix(publicBase);
|
|
269
|
+
if (!prefix || !value) return value;
|
|
270
|
+
return String(value).replace(/<(\/(?!\/)[^>\s]*)>/g, (full, path) =>
|
|
271
|
+
alreadyPrefixed(path, prefix) ? full : `<${prefix}${path}>`
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
|
|
251
275
|
function gzipIfRequested(payload, headers, acceptEncoding) {
|
|
252
276
|
if (payload.length < 1024) return payload;
|
|
253
277
|
if (!/\bgzip\b/i.test(acceptEncoding || "")) return payload;
|
|
@@ -348,26 +372,65 @@ function viteDevBases(body) {
|
|
|
348
372
|
return bases;
|
|
349
373
|
}
|
|
350
374
|
|
|
351
|
-
function
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
"
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
"/
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
375
|
+
function inferViteBase(body) {
|
|
376
|
+
const fromConst = viteDevBases(body)[0];
|
|
377
|
+
if (fromConst) return fromConst;
|
|
378
|
+
const text = String(body || "");
|
|
379
|
+
const match = text.match(
|
|
380
|
+
/["'`](\/[^"'`]*?)\/(?:@vite(?:\/client)?|@react-refresh)(?:["'`?]|$)/
|
|
381
|
+
);
|
|
382
|
+
if (match?.[1] && match[1] !== "/") {
|
|
383
|
+
return match[1].endsWith("/") ? match[1] : `${match[1]}/`;
|
|
384
|
+
}
|
|
385
|
+
return "/";
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/** Vite/Next module URLs that must stay on the share origin. App routes like /hub/settings are not assets. */
|
|
389
|
+
function isShareAssetPath(path) {
|
|
390
|
+
const p = String(path || "").split("?")[0];
|
|
391
|
+
if (!p.startsWith("/")) return false;
|
|
392
|
+
if (
|
|
393
|
+
/\/(?:_next\/|__nextjs_|@vite(?:\/|$)|@react-refresh(?:\/|$)|@fs\/|@id\/|node_modules\/)/.test(
|
|
394
|
+
p
|
|
395
|
+
)
|
|
396
|
+
) {
|
|
397
|
+
return true;
|
|
398
|
+
}
|
|
399
|
+
if (/\/src\/[^/].+\.[A-Za-z0-9]+$/.test(p)) return true;
|
|
400
|
+
return /\.(?:m?[jt]sx?|cjs|mjs|css|scss|sass|less|map|wasm|vue|svelte)$/i.test(
|
|
401
|
+
p
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
function prefixQuotedAssetPaths(body, pathPrefix) {
|
|
406
|
+
if (!pathPrefix) return body;
|
|
407
|
+
return String(body).replace(/(["'`])(\/(?!\/)[^"'`]*)/g, (full, q, path) => {
|
|
408
|
+
if (alreadyPrefixed(path, pathPrefix)) return full;
|
|
409
|
+
if (!isShareAssetPath(path)) return full;
|
|
410
|
+
return `${q}${pathPrefix}${path}`;
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function rewriteViteBaseLiterals(body, pathPrefix) {
|
|
415
|
+
let out = rewriteViteHmrClient(body, pathPrefix);
|
|
416
|
+
const bases = [...viteDevBases(body), inferViteBase(body)].filter(
|
|
417
|
+
(base, i, all) => base && base !== "/" && all.indexOf(base) === i
|
|
418
|
+
);
|
|
419
|
+
for (const viteBase of bases) {
|
|
420
|
+
const prefixed = joinProxyAndViteBase(pathPrefix, viteBase);
|
|
421
|
+
const withSlash = viteBase.endsWith("/") ? viteBase : `${viteBase}/`;
|
|
422
|
+
const escaped = withSlash.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
423
|
+
out = out.replace(
|
|
424
|
+
new RegExp(`(\\bconst base(?:\\$\\d+)?\\s*=\\s*)(["'])${escaped}\\2`, "g"),
|
|
425
|
+
`$1$2${prefixed}$2`
|
|
426
|
+
);
|
|
427
|
+
out = out.split(`BASE_URL:"${withSlash}"`).join(`BASE_URL:"${prefixed}"`);
|
|
428
|
+
out = out.split(`BASE_URL:'${withSlash}'`).join(`BASE_URL:'${prefixed}'`);
|
|
429
|
+
out = out
|
|
430
|
+
.split(`"BASE_URL":"${withSlash}"`)
|
|
431
|
+
.join(`"BASE_URL":"${prefixed}"`);
|
|
368
432
|
}
|
|
369
|
-
|
|
370
|
-
return [...roots];
|
|
433
|
+
return out;
|
|
371
434
|
}
|
|
372
435
|
|
|
373
436
|
function joinProxyAndViteBase(pathPrefix, viteBase) {
|
|
@@ -411,9 +474,38 @@ function alreadyPrefixed(path, pathPrefix) {
|
|
|
411
474
|
return path === pathPrefix || path.startsWith(`${pathPrefix}/`);
|
|
412
475
|
}
|
|
413
476
|
|
|
477
|
+
function rewriteNextFlightCanonical(body, pathPrefix) {
|
|
478
|
+
if (!pathPrefix || !body) return body;
|
|
479
|
+
const encoded = JSON.stringify(pathPrefix);
|
|
480
|
+
const escaped = pathPrefix.replaceAll("\\", "\\\\").replaceAll('"', '\\"');
|
|
481
|
+
let out = body;
|
|
482
|
+
if (out.includes(`"c":["",""]`)) {
|
|
483
|
+
out = out.split(`"c":["",""]`).join(`"c":[${encoded}]`);
|
|
484
|
+
}
|
|
485
|
+
if (out.includes('\\"c\\":[\\"\\",\\"\\"]')) {
|
|
486
|
+
out = out
|
|
487
|
+
.split('\\"c\\":[\\"\\",\\"\\"]')
|
|
488
|
+
.join(`\\"c\\":[\\"${escaped}\\"]`);
|
|
489
|
+
}
|
|
490
|
+
out = out.replace(/("b":"[^"]+","p":)""/g, `$1${encoded}`);
|
|
491
|
+
out = out.replace(
|
|
492
|
+
/(\\?"b\\":\\?"[^"]+\\?",\\?"p\\":)\\?"\\?"/g,
|
|
493
|
+
`$1\\"${escaped}\\"`
|
|
494
|
+
);
|
|
495
|
+
if (out.includes(`"assetPrefix":""`)) {
|
|
496
|
+
out = out.split(`"assetPrefix":""`).join(`"assetPrefix":${encoded}`);
|
|
497
|
+
}
|
|
498
|
+
if (out.includes('\\"assetPrefix\\":\\"\\"')) {
|
|
499
|
+
out = out
|
|
500
|
+
.split('\\"assetPrefix\\":\\"\\"')
|
|
501
|
+
.join(`\\"assetPrefix\\":\\"${escaped}\\"`);
|
|
502
|
+
}
|
|
503
|
+
return out;
|
|
504
|
+
}
|
|
505
|
+
|
|
414
506
|
function rewriteNextTurbopackBasePath(body, pathPrefix) {
|
|
415
507
|
if (!pathPrefix) return body;
|
|
416
|
-
let out = body;
|
|
508
|
+
let out = rewriteNextFlightCanonical(body, pathPrefix);
|
|
417
509
|
if (out.includes("TURBOPACK compile-time value")) {
|
|
418
510
|
const next = JSON.stringify(pathPrefix);
|
|
419
511
|
out = out
|
|
@@ -454,10 +546,9 @@ function prefixRootPaths(body, publicBase, contentType = "") {
|
|
|
454
546
|
mime === "application/xhtml+xml" ||
|
|
455
547
|
(!mime && /<!doctype html|<html[\s>]/i.test(body)));
|
|
456
548
|
const css = mime === "text/css" || (!isCode && !html && /css/.test(mime));
|
|
457
|
-
const viteAndNext = ["/_next/", "/__nextjs_", ...viteAssetRoots(body)];
|
|
458
549
|
if (!html && !css) {
|
|
459
|
-
let code =
|
|
460
|
-
code =
|
|
550
|
+
let code = rewriteViteBaseLiterals(body, pathPrefix);
|
|
551
|
+
code = prefixQuotedAssetPaths(code, pathPrefix);
|
|
461
552
|
code = code.replace(
|
|
462
553
|
/(?<![A-Za-z0-9])\/__nextjs_/g,
|
|
463
554
|
`${pathPrefix}/__nextjs_`
|
|
@@ -472,10 +563,9 @@ function prefixRootPaths(body, publicBase, contentType = "") {
|
|
|
472
563
|
!/<base\s/i.test(out) &&
|
|
473
564
|
!isNextDocument(out)
|
|
474
565
|
) {
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
);
|
|
566
|
+
const viteBase = isViteDocument(out) ? inferViteBase(out) : "/";
|
|
567
|
+
const href = joinProxyAndViteBase(pathPrefix, viteBase);
|
|
568
|
+
out = out.replace(/<head([^>]*)>/i, `<head$1><base href="${href}">`);
|
|
479
569
|
}
|
|
480
570
|
if (html) {
|
|
481
571
|
out = out.replace(
|
|
@@ -486,6 +576,7 @@ function prefixRootPaths(body, publicBase, contentType = "") {
|
|
|
486
576
|
out = out.replace(/\s+crossorigin(?:\s*=\s*(["']).*?\1)?/gi, "");
|
|
487
577
|
}
|
|
488
578
|
if (isNextDocument(out)) {
|
|
579
|
+
out = rewriteNextFlightCanonical(out, pathPrefix);
|
|
489
580
|
out = prefixQuotedRoots(out, pathPrefix, ["/_next/", "/__nextjs_"]);
|
|
490
581
|
out = out.replace(
|
|
491
582
|
/(url\(\s*['"]?)(\/(?!\/)[^)"']*)/gi,
|
|
@@ -503,13 +594,7 @@ function prefixRootPaths(body, publicBase, contentType = "") {
|
|
|
503
594
|
(full, start, path) =>
|
|
504
595
|
alreadyPrefixed(path, pathPrefix) ? full : `${start}${pathPrefix}${path}`
|
|
505
596
|
);
|
|
506
|
-
|
|
507
|
-
const escaped = root.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
508
|
-
out = out.replace(
|
|
509
|
-
new RegExp(`(?<![A-Za-z0-9])${escaped}`, "g"),
|
|
510
|
-
`${pathPrefix}${root}`
|
|
511
|
-
);
|
|
512
|
-
}
|
|
597
|
+
out = prefixQuotedAssetPaths(out, pathPrefix);
|
|
513
598
|
}
|
|
514
599
|
return out;
|
|
515
600
|
}
|
|
@@ -600,6 +685,179 @@ function injectMaintainerProEmbed(html, aiPublicBase) {
|
|
|
600
685
|
return html + loader;
|
|
601
686
|
}
|
|
602
687
|
|
|
688
|
+
/**
|
|
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.
|
|
691
|
+
*/
|
|
692
|
+
function shareProxyShim(p) {
|
|
693
|
+
if (!p) return;
|
|
694
|
+
function collapse(path) {
|
|
695
|
+
var d = p + p;
|
|
696
|
+
while (path.indexOf(d) === 0) path = p + path.slice(d.length);
|
|
697
|
+
return path;
|
|
698
|
+
}
|
|
699
|
+
function isAsset(path) {
|
|
700
|
+
return (
|
|
701
|
+
/\/(?:_next\/|__nextjs_|@vite(?:\/|$)|@react-refresh(?:\/|$)|@fs\/|@id\/|node_modules\/)/.test(
|
|
702
|
+
path
|
|
703
|
+
) ||
|
|
704
|
+
/\/src\/[^/].+\.[A-Za-z0-9]+(?:\?|$)/.test(path) ||
|
|
705
|
+
/\.(?:m?[jt]sx?|cjs|mjs|css|scss|sass|less|map|wasm|vue|svelte)(?:\?|$)/i.test(
|
|
706
|
+
path
|
|
707
|
+
)
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
function prefixPath(path) {
|
|
711
|
+
if (typeof path !== "string" || !path) return path;
|
|
712
|
+
if (path.charAt(0) === "/" && path.charAt(1) !== "/") {
|
|
713
|
+
if (path === p || path.indexOf(p + "/") === 0) return collapse(path);
|
|
714
|
+
var root = p.slice(0, p.lastIndexOf("/"));
|
|
715
|
+
if (root && (path === root || path.indexOf(root + "/") === 0)) return path;
|
|
716
|
+
if (path === "/api/v1" || path.indexOf("/api/v1/") === 0) return path;
|
|
717
|
+
return collapse(p + path);
|
|
718
|
+
}
|
|
719
|
+
return path;
|
|
720
|
+
}
|
|
721
|
+
function addNav(v) {
|
|
722
|
+
if (typeof v !== "string" || !v) return v;
|
|
723
|
+
if (v.charAt(0) === "/" && v.charAt(1) !== "/") return prefixPath(v);
|
|
724
|
+
try {
|
|
725
|
+
var nav = new URL(v, location.href);
|
|
726
|
+
if (nav.origin !== location.origin) return v;
|
|
727
|
+
nav.pathname = prefixPath(nav.pathname);
|
|
728
|
+
return nav.toString();
|
|
729
|
+
} catch (e) {}
|
|
730
|
+
return v;
|
|
731
|
+
}
|
|
732
|
+
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;
|
|
750
|
+
}
|
|
751
|
+
function mapSel(sel) {
|
|
752
|
+
if (typeof sel !== "string") return sel;
|
|
753
|
+
var pairs = [
|
|
754
|
+
['src="/_next/', 'src="' + p + "/_next/"],
|
|
755
|
+
['href="/_next/', 'href="' + p + "/_next/"],
|
|
756
|
+
];
|
|
757
|
+
for (var i = 0; i < pairs.length; i++) {
|
|
758
|
+
if (sel.indexOf(pairs[i][0]) !== -1) return sel.split(pairs[i][0]).join(pairs[i][1]);
|
|
759
|
+
}
|
|
760
|
+
return sel;
|
|
761
|
+
}
|
|
762
|
+
function patchQS(proto, name) {
|
|
763
|
+
var orig = proto[name];
|
|
764
|
+
proto[name] = function (sel) {
|
|
765
|
+
var r = orig.call(this, sel);
|
|
766
|
+
if (name === "querySelector") {
|
|
767
|
+
if (r) return r;
|
|
768
|
+
} else if (r.length) return r;
|
|
769
|
+
var s2 = mapSel(sel);
|
|
770
|
+
return s2 === sel ? r : orig.call(this, s2);
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
patchQS(Document.prototype, "querySelector");
|
|
774
|
+
patchQS(Document.prototype, "querySelectorAll");
|
|
775
|
+
patchQS(Element.prototype, "querySelector");
|
|
776
|
+
patchQS(Element.prototype, "querySelectorAll");
|
|
777
|
+
var sa = Element.prototype.setAttribute;
|
|
778
|
+
Element.prototype.setAttribute = function (n, v) {
|
|
779
|
+
if ((n === "src" || n === "href") && typeof v === "string") v = addNav(v);
|
|
780
|
+
return sa.call(this, n, v);
|
|
781
|
+
};
|
|
782
|
+
function patchUrlProp(ctor, prop) {
|
|
783
|
+
try {
|
|
784
|
+
var d = Object.getOwnPropertyDescriptor(ctor.prototype, prop);
|
|
785
|
+
if (!d || !d.set) return;
|
|
786
|
+
Object.defineProperty(ctor.prototype, prop, {
|
|
787
|
+
configurable: true,
|
|
788
|
+
enumerable: true,
|
|
789
|
+
get: d.get,
|
|
790
|
+
set: function (v) {
|
|
791
|
+
d.set.call(this, addNav(v));
|
|
792
|
+
},
|
|
793
|
+
});
|
|
794
|
+
} catch (e) {}
|
|
795
|
+
}
|
|
796
|
+
patchUrlProp(HTMLScriptElement, "src");
|
|
797
|
+
patchUrlProp(HTMLLinkElement, "href");
|
|
798
|
+
var f = window.fetch;
|
|
799
|
+
window.fetch = function (input, init) {
|
|
800
|
+
if (typeof input === "string") input = addNet(input);
|
|
801
|
+
else if (typeof Request !== "undefined" && input instanceof Request) {
|
|
802
|
+
input = new Request(addNet(input.url), input);
|
|
803
|
+
} else if (typeof URL !== "undefined" && input instanceof URL) {
|
|
804
|
+
input = new URL(addNet(input.href));
|
|
805
|
+
}
|
|
806
|
+
return f.call(this, input, init);
|
|
807
|
+
};
|
|
808
|
+
var xo = XMLHttpRequest.prototype.open;
|
|
809
|
+
XMLHttpRequest.prototype.open = function (m, u) {
|
|
810
|
+
if (typeof u === "string") arguments[1] = addNet(u);
|
|
811
|
+
return xo.apply(this, arguments);
|
|
812
|
+
};
|
|
813
|
+
var ps = history.pushState.bind(history);
|
|
814
|
+
history.pushState = function (s, t, u) {
|
|
815
|
+
if (typeof u === "string") u = addNav(u);
|
|
816
|
+
return ps(s, t, u);
|
|
817
|
+
};
|
|
818
|
+
var rs = history.replaceState.bind(history);
|
|
819
|
+
history.replaceState = function (s, t, u) {
|
|
820
|
+
if (typeof u === "string") u = addNav(u);
|
|
821
|
+
return rs(s, t, u);
|
|
822
|
+
};
|
|
823
|
+
var WS = window.WebSocket;
|
|
824
|
+
function WrappedWS(url, protocols) {
|
|
825
|
+
if (typeof url === "string") url = addNet(url);
|
|
826
|
+
return protocols !== undefined ? new WS(url, protocols) : new WS(url);
|
|
827
|
+
}
|
|
828
|
+
WrappedWS.prototype = WS.prototype;
|
|
829
|
+
WrappedWS.CONNECTING = WS.CONNECTING;
|
|
830
|
+
WrappedWS.OPEN = WS.OPEN;
|
|
831
|
+
WrappedWS.CLOSING = WS.CLOSING;
|
|
832
|
+
WrappedWS.CLOSED = WS.CLOSED;
|
|
833
|
+
window.WebSocket = WrappedWS;
|
|
834
|
+
try {
|
|
835
|
+
var la = location.assign.bind(location);
|
|
836
|
+
location.assign = function (u) {
|
|
837
|
+
return la(addNav(String(u)));
|
|
838
|
+
};
|
|
839
|
+
var lr = location.replace.bind(location);
|
|
840
|
+
location.replace = function (u) {
|
|
841
|
+
return lr(addNav(String(u)));
|
|
842
|
+
};
|
|
843
|
+
} catch (e) {}
|
|
844
|
+
try {
|
|
845
|
+
var hd = Object.getOwnPropertyDescriptor(Location.prototype, "href");
|
|
846
|
+
if (hd && hd.set) {
|
|
847
|
+
Object.defineProperty(location, "href", {
|
|
848
|
+
configurable: true,
|
|
849
|
+
enumerable: true,
|
|
850
|
+
get: function () {
|
|
851
|
+
return hd.get.call(location);
|
|
852
|
+
},
|
|
853
|
+
set: function (v) {
|
|
854
|
+
hd.set.call(location, addNav(String(v)));
|
|
855
|
+
},
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
} catch (e) {}
|
|
859
|
+
}
|
|
860
|
+
|
|
603
861
|
function injectNextProxyShim(html, publicBase) {
|
|
604
862
|
const prefix = proxyPathPrefix(publicBase);
|
|
605
863
|
if (
|
|
@@ -609,8 +867,7 @@ function injectNextProxyShim(html, publicBase) {
|
|
|
609
867
|
) {
|
|
610
868
|
return html;
|
|
611
869
|
}
|
|
612
|
-
const
|
|
613
|
-
const script = `<script data-mp-proxy-next>(function(p){if(!p)return;function add(v){if(typeof v!=="string"||!v)return v;if(v.charAt(0)==="/"&&v.charAt(1)!=="/"){if(v===p||v.indexOf(p+"/")===0)return v;var root=p.slice(0,p.lastIndexOf("/"));if(root&&(v===root||v.indexOf(root+"/")===0)return v;if(v==="/api/v1"||v.indexOf("/api/v1/")===0)return v;return p+v}try{var u=new URL(v,location.href);var host=String(u.hostname||"").toLowerCase();if(host.charAt(0)==="["&&host.charAt(host.length-1)==="]")host=host.slice(1,-1);var local=host==="localhost"||host==="127.0.0.1"||host==="::1"||host==="0.0.0.0";if(!local){if(u.pathname===p){u.pathname="/";return u.toString()}if(u.pathname.indexOf(p+"/")===0){u.pathname=u.pathname.slice(p.length)||"/";return u.toString()}return v}var samePort=String(u.port||"")===String(location.port||"");if(samePort){u.pathname=add(u.pathname);return u.toString()}if(u.pathname===p||u.pathname.indexOf(p+"/")===0){u.protocol=location.protocol;u.host=location.host;return u.toString()}}catch(e){}return v}function mapSel(sel){if(typeof sel!=="string")return sel;var pairs=[["src=\\"/_next/","src=\\""+p+"/_next/"],["href=\\"/_next/","href=\\""+p+"/_next/"]];for(var i=0;i<pairs.length;i++){if(sel.indexOf(pairs[i][0])!==-1)return sel.split(pairs[i][0]).join(pairs[i][1])}return sel}function patchQS(proto,name){var orig=proto[name];proto[name]=function(sel){var r=orig.call(this,sel);if(name==="querySelector"){if(r)return r}else if(r.length)return r;var s2=mapSel(sel);return s2===sel?r:orig.call(this,s2)}}patchQS(Document.prototype,"querySelector");patchQS(Document.prototype,"querySelectorAll");patchQS(Element.prototype,"querySelector");patchQS(Element.prototype,"querySelectorAll");var sa=Element.prototype.setAttribute;Element.prototype.setAttribute=function(n,v){if((n==="src"||n==="href")&&typeof v==="string")v=add(v);return sa.call(this,n,v)};function patchUrlProp(ctor,prop){try{var d=Object.getOwnPropertyDescriptor(ctor.prototype,prop);if(!d||!d.set)return;Object.defineProperty(ctor.prototype,prop,{configurable:true,enumerable:true,get:d.get,set:function(v){d.set.call(this,add(v))}})}catch(e){}}patchUrlProp(HTMLScriptElement,"src");patchUrlProp(HTMLLinkElement,"href");var f=window.fetch;window.fetch=function(input,init){if(typeof input==="string")input=add(input);else if(typeof Request!=="undefined"&&input instanceof Request)input=new Request(add(input.url),input);else if(typeof URL!=="undefined"&&input instanceof URL)input=new URL(add(input.href));return f.call(this,input,init)};var xo=XMLHttpRequest.prototype.open;XMLHttpRequest.prototype.open=function(m,u){if(typeof u==="string")arguments[1]=add(u);return xo.apply(this,arguments)};var ps=history.pushState.bind(history);history.pushState=function(s,t,u){if(typeof u==="string")u=add(u);return ps(s,t,u)};var rs=history.replaceState.bind(history);history.replaceState=function(s,t,u){if(typeof u==="string")u=add(u);return rs(s,t,u)};var WS=window.WebSocket;function WrappedWS(url,protocols){if(typeof url==="string")url=add(url);return protocols!==undefined?new WS(url,protocols):new WS(url)}WrappedWS.prototype=WS.prototype;WrappedWS.CONNECTING=WS.CONNECTING;WrappedWS.OPEN=WS.OPEN;WrappedWS.CLOSING=WS.CLOSING;WrappedWS.CLOSED=WS.CLOSED;window.WebSocket=WrappedWS})(${p})</script>`;
|
|
870
|
+
const script = `<script data-mp-proxy-next>(${shareProxyShim.toString()})(${JSON.stringify(prefix)})</script>`;
|
|
614
871
|
return html.replace(/<head([^>]*)>/i, `<head$1>${script}`);
|
|
615
872
|
}
|
|
616
873
|
|
|
@@ -649,6 +906,9 @@ export function processShareHttpResponse(opts) {
|
|
|
649
906
|
if (headers.location) {
|
|
650
907
|
headers.location = rewriteLocation(headers.location, publicBase, port);
|
|
651
908
|
}
|
|
909
|
+
if (headers.link) {
|
|
910
|
+
headers.link = rewriteLinkHeader(headers.link, publicBase);
|
|
911
|
+
}
|
|
652
912
|
|
|
653
913
|
const cachedKey = rewriteCacheKey(publicBase, path);
|
|
654
914
|
const hit =
|