@maintainer-pro/ai-bridge 0.1.21 → 0.1.22

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/share-rewrite.mjs +147 -17
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maintainer-pro/ai-bridge",
3
- "version": "0.1.21",
3
+ "version": "0.1.22",
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",
@@ -274,6 +274,33 @@ function mappedUrlForPort(portUrls, port) {
274
274
  return dest ? String(dest).replace(/\/$/, "") : "";
275
275
  }
276
276
 
277
+ function backendShareBase(portUrls) {
278
+ if (!portUrls || typeof portUrls !== "object") return "";
279
+ for (const dest of Object.values(portUrls)) {
280
+ const url = String(dest || "").replace(/\/$/, "");
281
+ if (!url) continue;
282
+ try {
283
+ const slug = new URL(url).pathname.split("/").filter(Boolean)[2] || "";
284
+ if (slug === "backend" || slug.startsWith("backend-")) return url;
285
+ } catch {
286
+ if (/\/backend(?:-[^/]+)?$/i.test(url)) return url;
287
+ }
288
+ }
289
+ return "";
290
+ }
291
+
292
+ function shareBaseForPath(path, publicBase, portUrls) {
293
+ const pathname = String(path || "").split("?")[0] || "/";
294
+ if (
295
+ isShareAssetPath(pathname) ||
296
+ pathname.startsWith("/_next/") ||
297
+ pathname.startsWith("/@")
298
+ ) {
299
+ return publicBase;
300
+ }
301
+ return backendShareBase(portUrls) || publicBase;
302
+ }
303
+
277
304
  function isProbablyUtf8Text(buf) {
278
305
  if (!Buffer.isBuffer(buf) || !buf.length || buf.length > 8 * 1024 * 1024) {
279
306
  return false;
@@ -410,7 +437,7 @@ function rewriteHeaderUrls(headers, publicBase, port, portUrls) {
410
437
  if (lower === "set-cookie" || lower === "content-length" || lower === "content-encoding") {
411
438
  continue;
412
439
  }
413
- headers[key] = rewriteShareOriginPaths(headers[key], publicBase);
440
+ headers[key] = rewriteShareOriginPaths(headers[key], publicBase, portUrls);
414
441
  }
415
442
  }
416
443
  }
@@ -448,7 +475,7 @@ export function prefixShareOriginUrl(value, publicBase) {
448
475
  }
449
476
  }
450
477
 
451
- export function rewriteShareOriginPaths(text, publicBase) {
478
+ export function rewriteShareOriginPaths(text, publicBase, portUrls) {
452
479
  if (!text || !publicBase) return text;
453
480
  let origin = "";
454
481
  try {
@@ -461,15 +488,24 @@ export function rewriteShareOriginPaths(text, publicBase) {
461
488
  const originSlashEsc = origin
462
489
  .replace(/\//g, "\\/")
463
490
  .replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
491
+ const baseFor = function (matched) {
492
+ let path = "/";
493
+ try {
494
+ path = new URL(matched).pathname || "/";
495
+ } catch {
496
+ /* keep */
497
+ }
498
+ return shareBaseForPath(path, publicBase, portUrls);
499
+ };
464
500
  let out = String(text);
465
501
  out = out.replace(new RegExp(originEsc + "/(?!p/)[^\\s'\"<>\\\\]+", "gi"), function (matched) {
466
- return prefixShareOriginUrl(matched, publicBase);
502
+ return prefixShareOriginUrl(matched, baseFor(matched));
467
503
  });
468
504
  out = out.replace(
469
505
  new RegExp(originSlashEsc + "\\\\/(?!p/)[^\\s'\"<>]+", "gi"),
470
506
  function (matched) {
471
507
  const unescaped = matched.replace(/\\\//g, "/");
472
- return prefixShareOriginUrl(unescaped, publicBase).replace(/\//g, "\\/");
508
+ return prefixShareOriginUrl(unescaped, baseFor(unescaped)).replace(/\//g, "\\/");
473
509
  }
474
510
  );
475
511
  return out;
@@ -495,7 +531,18 @@ function rewriteLocation(value, publicBase, port, portUrls) {
495
531
  }
496
532
  const fromPorts = rewriteMappedLocalUrls(String(value), portUrls);
497
533
  if (fromPorts !== String(value)) return fromPorts;
498
- if (publicBase) return prefixShareOriginUrl(String(value), publicBase);
534
+ if (publicBase) {
535
+ let path = "/";
536
+ try {
537
+ path = new URL(String(value)).pathname || "/";
538
+ } catch {
539
+ /* keep */
540
+ }
541
+ return prefixShareOriginUrl(
542
+ String(value),
543
+ shareBaseForPath(path, publicBase, portUrls)
544
+ );
545
+ }
499
546
  } catch {
500
547
  /* keep */
501
548
  }
@@ -1017,6 +1064,21 @@ function shareProxyShim(p, portMap, rewriteMappedLocalUrls) {
1017
1064
  } catch (e) {}
1018
1065
  return v;
1019
1066
  }
1067
+ function backendBase() {
1068
+ var map = portMap || {};
1069
+ var keys = Object.keys(map);
1070
+ for (var i = 0; i < keys.length; i++) {
1071
+ var url = String(map[keys[i]] || "").replace(/\/$/, "");
1072
+ if (!url) continue;
1073
+ try {
1074
+ var slug = new URL(url).pathname.split("/").filter(Boolean)[2] || "";
1075
+ if (slug === "backend" || slug.indexOf("backend-") === 0) return url;
1076
+ } catch (e) {
1077
+ if (/\/backend(?:-[^/]+)?$/i.test(url)) return url;
1078
+ }
1079
+ }
1080
+ return "";
1081
+ }
1020
1082
  function addNav(v) {
1021
1083
  if (typeof v !== "string" || !v) return v;
1022
1084
  var mapped = mapLocal(v);
@@ -1036,11 +1098,42 @@ function shareProxyShim(p, portMap, rewriteMappedLocalUrls) {
1036
1098
  if (typeof v !== "string" || !v) return v;
1037
1099
  var mapped = mapLocal(v);
1038
1100
  if (mapped !== v) return mapped;
1039
- if (/^(https?:|wss?:)\/\//i.test(v)) {
1040
- try {
1041
- var u = new URL(v);
1042
- if (!loopback(u.hostname)) return v;
1043
- } catch (e) {}
1101
+ var backend = backendBase();
1102
+ var path = "";
1103
+ var search = "";
1104
+ var hash = "";
1105
+ var abs = null;
1106
+ try {
1107
+ if (/^(https?:|wss?:)\/\//i.test(v)) {
1108
+ abs = new URL(v);
1109
+ var host = String(abs.hostname || "")
1110
+ .replace(/^\[|\]$/g, "")
1111
+ .toLowerCase();
1112
+ if (!loopback(host) && host !== String(location.hostname || "").toLowerCase()) {
1113
+ return v;
1114
+ }
1115
+ path = abs.pathname || "/";
1116
+ search = abs.search || "";
1117
+ hash = abs.hash || "";
1118
+ } else if (v.charAt(0) === "/" && v.charAt(1) !== "/") {
1119
+ var rel = new URL(v, location.href);
1120
+ path = rel.pathname || "/";
1121
+ search = rel.search || "";
1122
+ hash = rel.hash || "";
1123
+ } else {
1124
+ return addNav(v);
1125
+ }
1126
+ } catch (e) {
1127
+ return addNav(v);
1128
+ }
1129
+ if (path === "/api/v1" || path.indexOf("/api/v1/") === 0) return v;
1130
+ if (path.indexOf("/p/") === 0) return v;
1131
+ if (path === "/" || path === "") return addNav(v);
1132
+ if (isAsset(path)) return addNav(v);
1133
+ if (backend) {
1134
+ var dest = backend + path + search + hash;
1135
+ if (abs && /^ws/i.test(abs.protocol)) dest = dest.replace(/^http/i, "ws");
1136
+ return dest;
1044
1137
  }
1045
1138
  return addNav(v);
1046
1139
  }
@@ -1244,17 +1337,54 @@ function shareServiceWorkerMain(portMap, tokenRoot, rewriteMappedLocalUrls) {
1244
1337
  h === "localhost" || h === "127.0.0.1" || h === "::1" || h === "0.0.0.0"
1245
1338
  );
1246
1339
  }
1340
+ function backendBase() {
1341
+ var map = portMap || {};
1342
+ var keys = Object.keys(map);
1343
+ for (var i = 0; i < keys.length; i++) {
1344
+ var url = String(map[keys[i]] || "").replace(/\/$/, "");
1345
+ if (!url) continue;
1346
+ try {
1347
+ var slug = new URL(url).pathname.split("/").filter(Boolean)[2] || "";
1348
+ if (slug === "backend" || slug.indexOf("backend-") === 0) return url;
1349
+ } catch (e) {
1350
+ if (/\/backend(?:-[^/]+)?$/i.test(url)) return url;
1351
+ }
1352
+ }
1353
+ return "";
1354
+ }
1247
1355
  function prefixWith(url, prefix) {
1248
1356
  if (!prefix) return url;
1249
1357
  try {
1250
- if (/^(https?:|wss?:)\/\//i.test(url)) {
1251
- var abs = new URL(url);
1252
- if (!loopback(abs.hostname)) return url;
1358
+ var backend = backendBase();
1359
+ var parsed = new URL(url, self.location.href);
1360
+ var host = String(parsed.hostname || "")
1361
+ .replace(/^\[|\]$/g, "")
1362
+ .toLowerCase();
1363
+ var pageHost = String(self.location.hostname || "")
1364
+ .replace(/^\[|\]$/g, "")
1365
+ .toLowerCase();
1366
+ if (/^(https?:|wss?:)\/\//i.test(url) && !loopback(host) && host !== pageHost) {
1367
+ return url;
1253
1368
  }
1254
- var u = new URL(url, self.location.href);
1369
+ var path = parsed.pathname || "/";
1370
+ if (path === "/api/v1" || path.indexOf("/api/v1/") === 0) return url;
1371
+ if (path.indexOf("/p/") === 0) return url;
1372
+ if (
1373
+ backend &&
1374
+ path !== "/" &&
1375
+ path !== "" &&
1376
+ !/\/(?:_next\/|__nextjs_|@vite(?:\/|$)|@react-refresh(?:\/|$)|@fs\/|@id\/|node_modules\/)/.test(
1377
+ path
1378
+ ) &&
1379
+ !/\.(?:m?[jt]sx?|cjs|mjs|css|scss|sass|less|map|wasm|vue|svelte)$/i.test(path)
1380
+ ) {
1381
+ var dest = backend + path + (parsed.search || "") + (parsed.hash || "");
1382
+ if (/^ws/i.test(parsed.protocol)) dest = dest.replace(/^http/i, "ws");
1383
+ return dest;
1384
+ }
1385
+ var u = parsed;
1255
1386
  if (u.origin !== self.location.origin) return url;
1256
1387
  if (u.pathname === "/" || u.pathname === "") return url;
1257
- if (u.pathname.indexOf("/p/") === 0) return url;
1258
1388
  if (u.pathname === prefix || u.pathname.indexOf(prefix + "/") === 0) return url;
1259
1389
  u.pathname = u.pathname === "/" ? prefix : prefix + u.pathname;
1260
1390
  return u.toString();
@@ -1427,8 +1557,8 @@ export function processShareHttpResponse(opts) {
1427
1557
  mutated = true;
1428
1558
  }
1429
1559
  }
1430
- if (publicBase && rewriteTextBody && !isScriptOrJsonBody(headers, path)) {
1431
- const prefixed = rewriteShareOriginPaths(text, publicBase);
1560
+ if (publicBase && rewriteTextBody) {
1561
+ const prefixed = rewriteShareOriginPaths(text, publicBase, portUrls);
1432
1562
  if (prefixed !== text) {
1433
1563
  text = prefixed;
1434
1564
  mutated = true;