@shipers-dev/multi 0.12.1 → 0.13.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/dist/index.js +63 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16272,7 +16272,7 @@ import { join as join4, dirname as dirname3 } from "path";
|
|
|
16272
16272
|
// package.json
|
|
16273
16273
|
var package_default = {
|
|
16274
16274
|
name: "@shipers-dev/multi",
|
|
16275
|
-
version: "0.
|
|
16275
|
+
version: "0.13.0",
|
|
16276
16276
|
type: "module",
|
|
16277
16277
|
bin: {
|
|
16278
16278
|
"multi-agent": "./dist/index.js"
|
|
@@ -16715,7 +16715,7 @@ async function cmdConnect(apiUrl, config2) {
|
|
|
16715
16715
|
try {
|
|
16716
16716
|
writeFileSync4(PORT_PATH, String(port));
|
|
16717
16717
|
} catch {}
|
|
16718
|
-
let tunnel = await startTunnel(port);
|
|
16718
|
+
let tunnel = await startTunnel(port, log);
|
|
16719
16719
|
if (!tunnel) {
|
|
16720
16720
|
log("\u274C cloudflared did not emit a tunnel URL \u2014 is `cloudflared` installed? (`brew install cloudflared`)");
|
|
16721
16721
|
try {
|
|
@@ -16785,7 +16785,7 @@ async function cmdConnect(apiUrl, config2) {
|
|
|
16785
16785
|
old?.child.kill();
|
|
16786
16786
|
} catch {}
|
|
16787
16787
|
for (let attempt = 1;alive; attempt++) {
|
|
16788
|
-
const next = await startTunnel(port);
|
|
16788
|
+
const next = await startTunnel(port, log);
|
|
16789
16789
|
if (next) {
|
|
16790
16790
|
tunnel = next;
|
|
16791
16791
|
log(`\u2601\uFE0F Tunnel up: ${tunnel.url}`);
|
|
@@ -16854,21 +16854,77 @@ async function cmdConnect(apiUrl, config2) {
|
|
|
16854
16854
|
}
|
|
16855
16855
|
}
|
|
16856
16856
|
}
|
|
16857
|
-
async function startTunnel(port) {
|
|
16857
|
+
async function startTunnel(port, log2 = () => {}) {
|
|
16858
|
+
const named = process.env.MULTI_TUNNEL_NAME?.trim();
|
|
16859
|
+
const hostname3 = process.env.MULTI_TUNNEL_HOSTNAME?.trim();
|
|
16860
|
+
if (named) {
|
|
16861
|
+
if (!hostname3) {
|
|
16862
|
+
log2("\u274C MULTI_TUNNEL_NAME set but MULTI_TUNNEL_HOSTNAME missing \u2014 set the public hostname routed to this tunnel");
|
|
16863
|
+
return null;
|
|
16864
|
+
}
|
|
16865
|
+
const args = ["tunnel", "--no-autoupdate", "--url", `http://127.0.0.1:${port}`, "run", named];
|
|
16866
|
+
const child2 = Bun.spawn(["cloudflared", ...args], { stdout: "pipe", stderr: "pipe", stdin: "ignore" });
|
|
16867
|
+
const ok = await waitNamedTunnelReady(child2.stderr);
|
|
16868
|
+
if (!ok.ready) {
|
|
16869
|
+
try {
|
|
16870
|
+
child2.kill();
|
|
16871
|
+
} catch {}
|
|
16872
|
+
if (ok.tail) {
|
|
16873
|
+
const lines = ok.tail.split(`
|
|
16874
|
+
`).filter(Boolean).slice(-6);
|
|
16875
|
+
for (const l of lines)
|
|
16876
|
+
log2(` cloudflared: ${l}`);
|
|
16877
|
+
}
|
|
16878
|
+
return null;
|
|
16879
|
+
}
|
|
16880
|
+
const url3 = hostname3.startsWith("http") ? hostname3.replace(/\/+$/, "") : `https://${hostname3}`;
|
|
16881
|
+
return { child: child2, url: url3 };
|
|
16882
|
+
}
|
|
16858
16883
|
const child = Bun.spawn(["cloudflared", "tunnel", "--no-autoupdate", "--url", `http://127.0.0.1:${port}`], {
|
|
16859
16884
|
stdout: "pipe",
|
|
16860
16885
|
stderr: "pipe",
|
|
16861
16886
|
stdin: "ignore"
|
|
16862
16887
|
});
|
|
16863
|
-
const url2 = await parseTunnelUrl(child.stderr);
|
|
16888
|
+
const { url: url2, tail } = await parseTunnelUrl(child.stderr);
|
|
16864
16889
|
if (!url2) {
|
|
16865
16890
|
try {
|
|
16866
16891
|
child.kill();
|
|
16867
16892
|
} catch {}
|
|
16893
|
+
if (tail) {
|
|
16894
|
+
const lines = tail.split(`
|
|
16895
|
+
`).filter(Boolean).slice(-6);
|
|
16896
|
+
for (const l of lines)
|
|
16897
|
+
log2(` cloudflared: ${l}`);
|
|
16898
|
+
}
|
|
16868
16899
|
return null;
|
|
16869
16900
|
}
|
|
16870
16901
|
return { child, url: url2 };
|
|
16871
16902
|
}
|
|
16903
|
+
async function waitNamedTunnelReady(stream2) {
|
|
16904
|
+
const reader = stream2.getReader();
|
|
16905
|
+
const dec = new TextDecoder;
|
|
16906
|
+
const deadline = Date.now() + 30000;
|
|
16907
|
+
let buf = "";
|
|
16908
|
+
while (Date.now() < deadline) {
|
|
16909
|
+
const { value, done } = await reader.read();
|
|
16910
|
+
if (done)
|
|
16911
|
+
break;
|
|
16912
|
+
buf += dec.decode(value, { stream: true });
|
|
16913
|
+
if (/Registered tunnel connection|Connection [a-z0-9-]+ registered/i.test(buf)) {
|
|
16914
|
+
(async () => {
|
|
16915
|
+
try {
|
|
16916
|
+
while (true) {
|
|
16917
|
+
const { done: done2 } = await reader.read();
|
|
16918
|
+
if (done2)
|
|
16919
|
+
break;
|
|
16920
|
+
}
|
|
16921
|
+
} catch {}
|
|
16922
|
+
})();
|
|
16923
|
+
return { ready: true, tail: buf };
|
|
16924
|
+
}
|
|
16925
|
+
}
|
|
16926
|
+
return { ready: false, tail: buf };
|
|
16927
|
+
}
|
|
16872
16928
|
async function probeTunnel(url2) {
|
|
16873
16929
|
try {
|
|
16874
16930
|
const ctrl = new AbortController;
|
|
@@ -16934,10 +16990,10 @@ async function parseTunnelUrl(stream2) {
|
|
|
16934
16990
|
}
|
|
16935
16991
|
} catch {}
|
|
16936
16992
|
})();
|
|
16937
|
-
return m[1];
|
|
16993
|
+
return { url: m[1], tail: buf };
|
|
16938
16994
|
}
|
|
16939
16995
|
}
|
|
16940
|
-
return null;
|
|
16996
|
+
return { url: null, tail: buf };
|
|
16941
16997
|
}
|
|
16942
16998
|
async function markStopped(apiUrl, issueId, reason) {
|
|
16943
16999
|
try {
|