vite-plugin-io1 0.1.0 → 0.1.2
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/README.md +11 -7
- package/dist/announce.d.ts +13 -2
- package/dist/announce.d.ts.map +1 -1
- package/dist/announce.js +17 -2
- package/dist/announce.js.map +1 -1
- package/dist/binary.d.ts +2 -2
- package/dist/binary.js +2 -2
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/announce.ts +20 -2
- package/src/binary.ts +2 -2
- package/src/index.ts +29 -13
package/README.md
CHANGED
|
@@ -10,11 +10,15 @@ startup output.
|
|
|
10
10
|
|
|
11
11
|
## Why
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
A tunnel is only worth anything if it points at the dev server you are actually editing, and this
|
|
14
|
+
one does: the public URL is your running `vite dev` - HMR and all - so a teammate (or your phone)
|
|
15
|
+
hits the same live server you have open, and a save reloads their page in place. It arrives over a
|
|
16
|
+
genuine HTTPS cert, so the secure-context APIs that quietly refuse to run on plain HTTP - service
|
|
17
|
+
workers, the camera, WebCrypto - just work.
|
|
18
|
+
|
|
19
|
+
Set `allowedEmails` and the preview turns shared-but-not-public: a visitor verifies one of those
|
|
20
|
+
addresses before the host resolves for them. And because the relay presents the upstream's own Host,
|
|
21
|
+
Vite's host check never trips - there is no `server.allowedHosts` to wrangle.
|
|
18
22
|
|
|
19
23
|
## Install
|
|
20
24
|
|
|
@@ -71,14 +75,14 @@ explicitly for a shared demo host.
|
|
|
71
75
|
|
|
72
76
|
The `bitmot` CLI carries a version (`bitmot version`), and the gateway advertises the latest one on
|
|
73
77
|
every relay handshake; run by hand, the CLI nudges you when you are out of date. That nudge is
|
|
74
|
-
deliberately silent when its output is piped or `CI` is set
|
|
78
|
+
deliberately silent when its output is piped or `CI` is set - that is, whenever this plugin runs it.
|
|
75
79
|
So the plugin keeps the CLI current a different way: auto-download resolves the **currently deployed**
|
|
76
80
|
bytes by content hash, so a plugin-managed CLI is always up to date and the nudge is moot. A CLI you
|
|
77
81
|
installed yourself on your PATH is respected as-is and never replaced.
|
|
78
82
|
|
|
79
83
|
## Caveats
|
|
80
84
|
|
|
81
|
-
- **macOS and Linux**
|
|
85
|
+
- **macOS and Linux** - published binaries cover macOS (arm64/x86_64) and Linux (x86_64/aarch64).
|
|
82
86
|
Elsewhere (e.g. native Windows), install `bitmot` yourself (the plugin will use it) or set
|
|
83
87
|
`bitmotPath`.
|
|
84
88
|
- **Middleware mode** (e.g. Nuxt) exposes no `httpServer` for the plugin to hook; not yet supported.
|
package/dist/announce.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pure argument-building and output-parsing for the bitmot io1 relay. Kept free of I/O so the wire
|
|
3
|
-
* contract with the CLI
|
|
3
|
+
* contract with the CLI - which flags it takes, and how it announces a live host - is unit-tested
|
|
4
4
|
* in isolation and lives in one place.
|
|
5
5
|
*/
|
|
6
|
+
import type { AddressInfo } from 'node:net';
|
|
6
7
|
export interface RelayInvocation {
|
|
7
8
|
/** Hosts to claim, one `--host` each (the CLI appends across repeats). At least one. */
|
|
8
9
|
readonly hosts: readonly string[];
|
|
@@ -30,9 +31,19 @@ export declare function buildRelayArgs(invocation: RelayInvocation): string[];
|
|
|
30
31
|
* The public URL from a relay's per-host announcement line, or null for any other line. The relay
|
|
31
32
|
* prints one `<arrow> <url> live` line per claimed host once its link is up (uncolored when its
|
|
32
33
|
* stderr is piped, as it is under this plugin). Tolerant of the arrow glyph and surrounding spaces so
|
|
33
|
-
* both the native and JVM CLIs
|
|
34
|
+
* both the native and JVM CLIs - and any cached older build - parse the same; the trailing `live`
|
|
34
35
|
* badge is what distinguishes it from the pending-requests and update-nudge lines, which also carry
|
|
35
36
|
* URLs but must not be mistaken for a live host.
|
|
36
37
|
*/
|
|
37
38
|
export declare function parseLiveUrl(line: string): string | null;
|
|
39
|
+
/**
|
|
40
|
+
* The `--to` proxy URL for a dev server bound at [address], a Node AddressInfo read once the socket is
|
|
41
|
+
* listening (so its port is the one the OS actually settled on, whatever Vite asked for). A wildcard
|
|
42
|
+
* bind - '0.0.0.0', '::', or the empty string - is not itself a connectable target, so we dial the
|
|
43
|
+
* loopback of the same family; a concrete address is kept as-is, and an IPv6 authority is bracketed.
|
|
44
|
+
* Using the bound address rather than a hardcoded 127.0.0.1 is what lets an IPv6 bind (Vite falling
|
|
45
|
+
* back to ::1 when 127.0.0.1:PORT is taken) be reached, instead of silently missing it or hitting
|
|
46
|
+
* whatever unrelated server already holds that IPv4 port.
|
|
47
|
+
*/
|
|
48
|
+
export declare function relayTargetUrl(address: AddressInfo): string;
|
|
38
49
|
//# sourceMappingURL=announce.d.ts.map
|
package/dist/announce.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"announce.d.ts","sourceRoot":"","sources":["../src/announce.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,eAAe;IAC9B,wFAAwF;IACxF,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,iGAAiG;IACjG,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1C,qEAAqE;IACrE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,mFAAmF;IACnF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,uFAAuF;IACvF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,kGAAkG;IAClG,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACtC,sEAAsE;IACtE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,eAAe,GAAG,MAAM,EAAE,CAWpE;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGxD"}
|
|
1
|
+
{"version":3,"file":"announce.d.ts","sourceRoot":"","sources":["../src/announce.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE3C,MAAM,WAAW,eAAe;IAC9B,wFAAwF;IACxF,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,iGAAiG;IACjG,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1C,qEAAqE;IACrE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,mFAAmF;IACnF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,uFAAuF;IACvF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,kGAAkG;IAClG,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACtC,sEAAsE;IACtE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,eAAe,GAAG,MAAM,EAAE,CAWpE;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAK3D"}
|
package/dist/announce.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pure argument-building and output-parsing for the bitmot io1 relay. Kept free of I/O so the wire
|
|
3
|
-
* contract with the CLI
|
|
3
|
+
* contract with the CLI - which flags it takes, and how it announces a live host - is unit-tested
|
|
4
4
|
* in isolation and lives in one place.
|
|
5
5
|
*/
|
|
6
6
|
/**
|
|
@@ -31,7 +31,7 @@ export function buildRelayArgs(invocation) {
|
|
|
31
31
|
* The public URL from a relay's per-host announcement line, or null for any other line. The relay
|
|
32
32
|
* prints one `<arrow> <url> live` line per claimed host once its link is up (uncolored when its
|
|
33
33
|
* stderr is piped, as it is under this plugin). Tolerant of the arrow glyph and surrounding spaces so
|
|
34
|
-
* both the native and JVM CLIs
|
|
34
|
+
* both the native and JVM CLIs - and any cached older build - parse the same; the trailing `live`
|
|
35
35
|
* badge is what distinguishes it from the pending-requests and update-nudge lines, which also carry
|
|
36
36
|
* URLs but must not be mistaken for a live host.
|
|
37
37
|
*/
|
|
@@ -39,4 +39,19 @@ export function parseLiveUrl(line) {
|
|
|
39
39
|
const match = /(https?:\/\/\S+)\s+live\s*$/u.exec(line);
|
|
40
40
|
return match ? match[1] : null;
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* The `--to` proxy URL for a dev server bound at [address], a Node AddressInfo read once the socket is
|
|
44
|
+
* listening (so its port is the one the OS actually settled on, whatever Vite asked for). A wildcard
|
|
45
|
+
* bind - '0.0.0.0', '::', or the empty string - is not itself a connectable target, so we dial the
|
|
46
|
+
* loopback of the same family; a concrete address is kept as-is, and an IPv6 authority is bracketed.
|
|
47
|
+
* Using the bound address rather than a hardcoded 127.0.0.1 is what lets an IPv6 bind (Vite falling
|
|
48
|
+
* back to ::1 when 127.0.0.1:PORT is taken) be reached, instead of silently missing it or hitting
|
|
49
|
+
* whatever unrelated server already holds that IPv4 port.
|
|
50
|
+
*/
|
|
51
|
+
export function relayTargetUrl(address) {
|
|
52
|
+
const wildcard = '' === address.address || '0.0.0.0' === address.address || '::' === address.address;
|
|
53
|
+
const host = wildcard ? ('IPv6' === address.family ? '::1' : '127.0.0.1') : address.address;
|
|
54
|
+
const authority = host.includes(':') ? `[${host}]` : host;
|
|
55
|
+
return `http://${authority}:${address.port}`;
|
|
56
|
+
}
|
|
42
57
|
//# sourceMappingURL=announce.js.map
|
package/dist/announce.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"announce.js","sourceRoot":"","sources":["../src/announce.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"announce.js","sourceRoot":"","sources":["../src/announce.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAqBH;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,UAA2B;IACxD,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IAC7B,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IAC9D,MAAM,MAAM,GAAG,UAAU,CAAC,aAAa,IAAI,EAAE,CAAA;IAC7C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IACtE,IAAI,UAAU,CAAC,OAAO;QAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;IAClE,IAAI,UAAU,CAAC,OAAO;QAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;IAClE,IAAI,UAAU,CAAC,WAAW;QAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,WAAW,CAAC,CAAA;IAC/E,IAAI,UAAU,CAAC,SAAS;QAAE,IAAI,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,SAAS,CAAC,CAAA;IAC5D,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,CAAA;IAChC,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,KAAK,GAAG,8BAA8B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACvD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AACjC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,OAAoB;IACjD,MAAM,QAAQ,GAAG,EAAE,KAAK,OAAO,CAAC,OAAO,IAAI,SAAS,KAAK,OAAO,CAAC,OAAO,IAAI,IAAI,KAAK,OAAO,CAAC,OAAO,CAAA;IACpG,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAA;IAC3F,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAA;IACzD,OAAO,UAAU,SAAS,IAAI,OAAO,CAAC,IAAI,EAAE,CAAA;AAC9C,CAAC"}
|
package/dist/binary.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export interface ResolvedBinary {
|
|
|
22
22
|
* The published artifact name for a platform/arch, or null when unsupported. Mirrors the server's
|
|
23
23
|
* download whitelist (io/io1/gateway/download/DownloadRoutesImpl.kt) and the installer's `uname`
|
|
24
24
|
* mapping: macOS and Linux, on x86_64 or 64-bit ARM. Node's arch is translated to the server's
|
|
25
|
-
* spelling
|
|
25
|
+
* spelling - 'x64' -> 'x86_64' on both, but 64-bit ARM is 'arm64' on macOS and 'aarch64' on Linux.
|
|
26
26
|
*/
|
|
27
27
|
export declare function artifactFor(platform: NodeJS.Platform, arch: string): string | null;
|
|
28
28
|
/** `bitmot version` -> "0.2.1", or null if the binary is missing or its output is unexpected. */
|
|
@@ -33,7 +33,7 @@ export declare function readVersion(binary: string): string | null;
|
|
|
33
33
|
* followed response's checksum header names the current version: if a file for that hash is already
|
|
34
34
|
* cached the body is dropped undownloaded, otherwise it is streamed, verified against the advertised
|
|
35
35
|
* checksum, and atomically installed. This is what makes a plugin-managed CLI track production
|
|
36
|
-
* automatically
|
|
36
|
+
* automatically - so the CLI's own "you're out of date" nudge (suppressed anyway when its stderr is
|
|
37
37
|
* piped, as it is here) does not matter for the auto-managed case.
|
|
38
38
|
*/
|
|
39
39
|
export declare function ensureDownloaded(baseUrl: string, artifact: string, cacheDir: string, log?: (message: string) => void): Promise<{
|
package/dist/binary.js
CHANGED
|
@@ -11,7 +11,7 @@ const DEFAULT_BASE_URL = 'https://bitmot.com';
|
|
|
11
11
|
* The published artifact name for a platform/arch, or null when unsupported. Mirrors the server's
|
|
12
12
|
* download whitelist (io/io1/gateway/download/DownloadRoutesImpl.kt) and the installer's `uname`
|
|
13
13
|
* mapping: macOS and Linux, on x86_64 or 64-bit ARM. Node's arch is translated to the server's
|
|
14
|
-
* spelling
|
|
14
|
+
* spelling - 'x64' -> 'x86_64' on both, but 64-bit ARM is 'arm64' on macOS and 'aarch64' on Linux.
|
|
15
15
|
*/
|
|
16
16
|
export function artifactFor(platform, arch) {
|
|
17
17
|
if (platform === 'darwin') {
|
|
@@ -63,7 +63,7 @@ function onPath() {
|
|
|
63
63
|
* followed response's checksum header names the current version: if a file for that hash is already
|
|
64
64
|
* cached the body is dropped undownloaded, otherwise it is streamed, verified against the advertised
|
|
65
65
|
* checksum, and atomically installed. This is what makes a plugin-managed CLI track production
|
|
66
|
-
* automatically
|
|
66
|
+
* automatically - so the CLI's own "you're out of date" nudge (suppressed anyway when its stderr is
|
|
67
67
|
* piped, as it is here) does not matter for the auto-managed case.
|
|
68
68
|
*/
|
|
69
69
|
export async function ensureDownloaded(baseUrl, artifact, cacheDir, log) {
|
package/dist/index.d.ts
CHANGED
|
@@ -27,11 +27,12 @@ export interface Io1PluginOptions {
|
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
29
|
* Vite plugin: while the dev (or preview) server runs, publish it to the internet over a
|
|
30
|
-
* `bitmot io1 relay` child process, proxying to the server
|
|
31
|
-
* tied to the server
|
|
32
|
-
* outlives the session. The CLI is located on
|
|
33
|
-
* the deployed build). Reconnects are the
|
|
34
|
-
* (bad auth, host held by another
|
|
30
|
+
* `bitmot io1 relay` child process, proxying to the address the server actually bound. The relay's
|
|
31
|
+
* lifetime is tied to the server - armed by intercepting listen() and spawned the moment the socket
|
|
32
|
+
* binds, killed when it closes - so a shared URL never outlives the session. The CLI is located on
|
|
33
|
+
* PATH or auto-downloaded (content-addressed, so it tracks the deployed build). Reconnects are the
|
|
34
|
+
* relay's own concern; a non-zero exit is a definitive refusal (bad auth, host held by another
|
|
35
|
+
* account) and is surfaced, not retried.
|
|
35
36
|
*/
|
|
36
37
|
export declare function io1(options?: Io1PluginOptions): Plugin;
|
|
37
38
|
export default io1;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAgC,MAAM,MAAM,CAAA;AAIhE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjE,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACxB,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,kGAAkG;IAClG,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,oFAAoF;IACpF,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAUD
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAgC,MAAM,MAAM,CAAA;AAIhE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjE,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACxB,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,kGAAkG;IAClG,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,oFAAoF;IACpF,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAUD;;;;;;;;GAQG;AACH,wBAAgB,GAAG,CAAC,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAyG1D;AAyBD,eAAe,GAAG,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
-
import { buildRelayArgs, parseLiveUrl } from './announce.js';
|
|
2
|
+
import { buildRelayArgs, parseLiveUrl, relayTargetUrl } from './announce.js';
|
|
3
3
|
import { resolveBitmot } from './binary.js';
|
|
4
4
|
function normalizeHosts(host) {
|
|
5
5
|
const raw = host ?? process.env.IO1_DEV_HOST;
|
|
@@ -9,11 +9,12 @@ function normalizeHosts(host) {
|
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
11
|
* Vite plugin: while the dev (or preview) server runs, publish it to the internet over a
|
|
12
|
-
* `bitmot io1 relay` child process, proxying to the server
|
|
13
|
-
* tied to the server
|
|
14
|
-
* outlives the session. The CLI is located on
|
|
15
|
-
* the deployed build). Reconnects are the
|
|
16
|
-
* (bad auth, host held by another
|
|
12
|
+
* `bitmot io1 relay` child process, proxying to the address the server actually bound. The relay's
|
|
13
|
+
* lifetime is tied to the server - armed by intercepting listen() and spawned the moment the socket
|
|
14
|
+
* binds, killed when it closes - so a shared URL never outlives the session. The CLI is located on
|
|
15
|
+
* PATH or auto-downloaded (content-addressed, so it tracks the deployed build). Reconnects are the
|
|
16
|
+
* relay's own concern; a non-zero exit is a definitive refusal (bad auth, host held by another
|
|
17
|
+
* account) and is surfaced, not retried.
|
|
17
18
|
*/
|
|
18
19
|
export function io1(options = {}) {
|
|
19
20
|
const hosts = normalizeHosts(options.host);
|
|
@@ -39,10 +40,24 @@ export function io1(options = {}) {
|
|
|
39
40
|
child = undefined;
|
|
40
41
|
process.removeListener('exit', onExit); // avoid piling up a listener per dev-server restart
|
|
41
42
|
};
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
// Arm the relay by intercepting listen() rather than only awaiting the 'listening' event: Vite
|
|
44
|
+
// calls listen once it has resolved the final port - the configured one, or (under
|
|
45
|
+
// strictPort:false) the next free port after a collision - so wrapping the very call that binds
|
|
46
|
+
// the socket is what guarantees we read the port the server actually took. The one-time
|
|
47
|
+
// 'listening' hook fires the instant the bind completes; `armed` keeps a second listen() from
|
|
48
|
+
// spawning a second relay. The casts are the price of replacing an overloaded native method.
|
|
49
|
+
const originalListen = httpServer.listen.bind(httpServer);
|
|
50
|
+
let armed = false;
|
|
51
|
+
httpServer.listen = ((...args) => {
|
|
52
|
+
if (!armed) {
|
|
53
|
+
armed = true;
|
|
54
|
+
httpServer.once('listening', () => {
|
|
55
|
+
void start(server).catch((error) => {
|
|
56
|
+
logger.error(`[io1] ${error.message}`);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return originalListen(...args);
|
|
46
61
|
});
|
|
47
62
|
httpServer.once('close', onExit);
|
|
48
63
|
process.once('exit', onExit);
|
|
@@ -51,7 +66,7 @@ export function io1(options = {}) {
|
|
|
51
66
|
const logger = server.config.logger;
|
|
52
67
|
const address = server.httpServer?.address();
|
|
53
68
|
if (!address || typeof address === 'string') {
|
|
54
|
-
logger.error('[io1] could not determine the dev server
|
|
69
|
+
logger.error('[io1] could not determine the dev server address; relay not started');
|
|
55
70
|
return;
|
|
56
71
|
}
|
|
57
72
|
const binary = await resolveBitmot({
|
|
@@ -68,7 +83,7 @@ export function io1(options = {}) {
|
|
|
68
83
|
account: options.account,
|
|
69
84
|
gateway: options.gateway,
|
|
70
85
|
extraArgs: options.extraArgs,
|
|
71
|
-
to:
|
|
86
|
+
to: relayTargetUrl(address),
|
|
72
87
|
});
|
|
73
88
|
if (stopping)
|
|
74
89
|
return; // the server closed while we were resolving the binary
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAA;AAE7D,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/announce.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pure argument-building and output-parsing for the bitmot io1 relay. Kept free of I/O so the wire
|
|
3
|
-
* contract with the CLI
|
|
3
|
+
* contract with the CLI - which flags it takes, and how it announces a live host - is unit-tested
|
|
4
4
|
* in isolation and lives in one place.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import type { AddressInfo } from 'node:net'
|
|
8
|
+
|
|
7
9
|
export interface RelayInvocation {
|
|
8
10
|
/** Hosts to claim, one `--host` each (the CLI appends across repeats). At least one. */
|
|
9
11
|
readonly hosts: readonly string[]
|
|
@@ -44,7 +46,7 @@ export function buildRelayArgs(invocation: RelayInvocation): string[] {
|
|
|
44
46
|
* The public URL from a relay's per-host announcement line, or null for any other line. The relay
|
|
45
47
|
* prints one `<arrow> <url> live` line per claimed host once its link is up (uncolored when its
|
|
46
48
|
* stderr is piped, as it is under this plugin). Tolerant of the arrow glyph and surrounding spaces so
|
|
47
|
-
* both the native and JVM CLIs
|
|
49
|
+
* both the native and JVM CLIs - and any cached older build - parse the same; the trailing `live`
|
|
48
50
|
* badge is what distinguishes it from the pending-requests and update-nudge lines, which also carry
|
|
49
51
|
* URLs but must not be mistaken for a live host.
|
|
50
52
|
*/
|
|
@@ -52,3 +54,19 @@ export function parseLiveUrl(line: string): string | null {
|
|
|
52
54
|
const match = /(https?:\/\/\S+)\s+live\s*$/u.exec(line)
|
|
53
55
|
return match ? match[1]! : null
|
|
54
56
|
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The `--to` proxy URL for a dev server bound at [address], a Node AddressInfo read once the socket is
|
|
60
|
+
* listening (so its port is the one the OS actually settled on, whatever Vite asked for). A wildcard
|
|
61
|
+
* bind - '0.0.0.0', '::', or the empty string - is not itself a connectable target, so we dial the
|
|
62
|
+
* loopback of the same family; a concrete address is kept as-is, and an IPv6 authority is bracketed.
|
|
63
|
+
* Using the bound address rather than a hardcoded 127.0.0.1 is what lets an IPv6 bind (Vite falling
|
|
64
|
+
* back to ::1 when 127.0.0.1:PORT is taken) be reached, instead of silently missing it or hitting
|
|
65
|
+
* whatever unrelated server already holds that IPv4 port.
|
|
66
|
+
*/
|
|
67
|
+
export function relayTargetUrl(address: AddressInfo): string {
|
|
68
|
+
const wildcard = '' === address.address || '0.0.0.0' === address.address || '::' === address.address
|
|
69
|
+
const host = wildcard ? ('IPv6' === address.family ? '::1' : '127.0.0.1') : address.address
|
|
70
|
+
const authority = host.includes(':') ? `[${host}]` : host
|
|
71
|
+
return `http://${authority}:${address.port}`
|
|
72
|
+
}
|
package/src/binary.ts
CHANGED
|
@@ -36,7 +36,7 @@ const DEFAULT_BASE_URL = 'https://bitmot.com'
|
|
|
36
36
|
* The published artifact name for a platform/arch, or null when unsupported. Mirrors the server's
|
|
37
37
|
* download whitelist (io/io1/gateway/download/DownloadRoutesImpl.kt) and the installer's `uname`
|
|
38
38
|
* mapping: macOS and Linux, on x86_64 or 64-bit ARM. Node's arch is translated to the server's
|
|
39
|
-
* spelling
|
|
39
|
+
* spelling - 'x64' -> 'x86_64' on both, but 64-bit ARM is 'arm64' on macOS and 'aarch64' on Linux.
|
|
40
40
|
*/
|
|
41
41
|
export function artifactFor(platform: NodeJS.Platform, arch: string): string | null {
|
|
42
42
|
if (platform === 'darwin') {
|
|
@@ -87,7 +87,7 @@ function onPath(): boolean {
|
|
|
87
87
|
* followed response's checksum header names the current version: if a file for that hash is already
|
|
88
88
|
* cached the body is dropped undownloaded, otherwise it is streamed, verified against the advertised
|
|
89
89
|
* checksum, and atomically installed. This is what makes a plugin-managed CLI track production
|
|
90
|
-
* automatically
|
|
90
|
+
* automatically - so the CLI's own "you're out of date" nudge (suppressed anyway when its stderr is
|
|
91
91
|
* piped, as it is here) does not matter for the auto-managed case.
|
|
92
92
|
*/
|
|
93
93
|
export async function ensureDownloaded(
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn, type ChildProcess } from 'node:child_process'
|
|
2
2
|
import type { Plugin, PreviewServer, ViteDevServer } from 'vite'
|
|
3
|
-
import { buildRelayArgs, parseLiveUrl } from './announce.js'
|
|
3
|
+
import { buildRelayArgs, parseLiveUrl, relayTargetUrl } from './announce.js'
|
|
4
4
|
import { resolveBitmot } from './binary.js'
|
|
5
5
|
|
|
6
6
|
export type { RelayInvocation } from './announce.js'
|
|
@@ -41,11 +41,12 @@ type ServeServer = ViteDevServer | PreviewServer
|
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* Vite plugin: while the dev (or preview) server runs, publish it to the internet over a
|
|
44
|
-
* `bitmot io1 relay` child process, proxying to the server
|
|
45
|
-
* tied to the server
|
|
46
|
-
* outlives the session. The CLI is located on
|
|
47
|
-
* the deployed build). Reconnects are the
|
|
48
|
-
* (bad auth, host held by another
|
|
44
|
+
* `bitmot io1 relay` child process, proxying to the address the server actually bound. The relay's
|
|
45
|
+
* lifetime is tied to the server - armed by intercepting listen() and spawned the moment the socket
|
|
46
|
+
* binds, killed when it closes - so a shared URL never outlives the session. The CLI is located on
|
|
47
|
+
* PATH or auto-downloaded (content-addressed, so it tracks the deployed build). Reconnects are the
|
|
48
|
+
* relay's own concern; a non-zero exit is a definitive refusal (bad auth, host held by another
|
|
49
|
+
* account) and is surfaced, not retried.
|
|
49
50
|
*/
|
|
50
51
|
export function io1(options: Io1PluginOptions = {}): Plugin {
|
|
51
52
|
const hosts = normalizeHosts(options.host)
|
|
@@ -74,11 +75,26 @@ export function io1(options: Io1PluginOptions = {}): Plugin {
|
|
|
74
75
|
process.removeListener('exit', onExit) // avoid piling up a listener per dev-server restart
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
78
|
+
// Arm the relay by intercepting listen() rather than only awaiting the 'listening' event: Vite
|
|
79
|
+
// calls listen once it has resolved the final port - the configured one, or (under
|
|
80
|
+
// strictPort:false) the next free port after a collision - so wrapping the very call that binds
|
|
81
|
+
// the socket is what guarantees we read the port the server actually took. The one-time
|
|
82
|
+
// 'listening' hook fires the instant the bind completes; `armed` keeps a second listen() from
|
|
83
|
+
// spawning a second relay. The casts are the price of replacing an overloaded native method.
|
|
84
|
+
const originalListen = httpServer.listen.bind(httpServer) as unknown as (...args: unknown[]) => unknown
|
|
85
|
+
let armed = false
|
|
86
|
+
httpServer.listen = ((...args: unknown[]): unknown => {
|
|
87
|
+
if (!armed) {
|
|
88
|
+
armed = true
|
|
89
|
+
httpServer.once('listening', () => {
|
|
90
|
+
void start(server).catch((error: unknown) => {
|
|
91
|
+
logger.error(`[io1] ${(error as Error).message}`)
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
return originalListen(...args)
|
|
96
|
+
}) as unknown as typeof httpServer.listen
|
|
97
|
+
|
|
82
98
|
httpServer.once('close', onExit)
|
|
83
99
|
process.once('exit', onExit)
|
|
84
100
|
}
|
|
@@ -87,7 +103,7 @@ export function io1(options: Io1PluginOptions = {}): Plugin {
|
|
|
87
103
|
const logger = server.config.logger
|
|
88
104
|
const address = server.httpServer?.address()
|
|
89
105
|
if (!address || typeof address === 'string') {
|
|
90
|
-
logger.error('[io1] could not determine the dev server
|
|
106
|
+
logger.error('[io1] could not determine the dev server address; relay not started')
|
|
91
107
|
return
|
|
92
108
|
}
|
|
93
109
|
|
|
@@ -105,7 +121,7 @@ export function io1(options: Io1PluginOptions = {}): Plugin {
|
|
|
105
121
|
account: options.account,
|
|
106
122
|
gateway: options.gateway,
|
|
107
123
|
extraArgs: options.extraArgs,
|
|
108
|
-
to:
|
|
124
|
+
to: relayTargetUrl(address),
|
|
109
125
|
})
|
|
110
126
|
|
|
111
127
|
if (stopping) return // the server closed while we were resolving the binary
|