devframe 1.3.2 → 1.3.5
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/{_shared-CnKu5myY.d.mts → _shared-BxeuukaL.d.mts} +2 -2
- package/dist/{_shared-BGb9aDxr.mjs → _shared-CtXCQFTV.mjs} +1 -1
- package/dist/adapters/build.d.mts +1 -1
- package/dist/adapters/cac.d.mts +1 -1
- package/dist/adapters/cac.mjs +2 -2
- package/dist/adapters/dev.d.mts +4 -4
- package/dist/adapters/dev.mjs +2 -2
- package/dist/adapters/embedded.d.mts +1 -1
- package/dist/adapters/initiate.d.mts +4 -4
- package/dist/adapters/initiate.mjs +1 -1
- package/dist/adapters/mcp.d.mts +2 -2
- package/dist/{agentic-CCstJ5yv.d.mts → agentic-DVgUzwhV.d.mts} +1 -1
- package/dist/client/index.d.mts +5 -5
- package/dist/client/index.mjs +1 -1
- package/dist/{context-CsdPs3po.d.mts → context-B-AARy_U.d.mts} +1 -1
- package/dist/{dev-DaHYh5YK.mjs → dev-DF1pEq0n.mjs} +2 -2
- package/dist/{dist-DJydMELP.mjs → dist-CZ-TySHD.mjs} +1 -2
- package/dist/in-page-channel/index.d.mts +3 -2
- package/dist/in-page-channel/index.mjs +1 -1
- package/dist/{context-WxTq6kqb.d.mts → index-BhUqJUHG.d.mts} +1404 -1404
- package/dist/index.d.mts +5 -4
- package/dist/{instance-registry-CmZfF5u3.mjs → instance-registry-DwmnWyCK.mjs} +1 -1
- package/dist/{instance-shell-Dk2SejFT.mjs → instance-shell-C0yMifrP.mjs} +5 -5
- package/dist/{instance-shell-Bujp0BhE.d.mts → instance-shell-DTk514M9.d.mts} +4 -4
- package/dist/{interactive-auth-BURwIAvE.mjs → interactive-auth-CZ3CPfEs.mjs} +1 -1
- package/dist/internal/index.d.mts +7 -7
- package/dist/internal/index.mjs +4 -4
- package/dist/{mcp-content-CQQBt2An.d.mts → mcp-content-0a0mpCL5.d.mts} +1 -1
- package/dist/node/auth.d.mts +84 -3
- package/dist/node/auth.mjs +1 -1
- package/dist/node/hub-internals.d.mts +11 -2
- package/dist/node/hub-internals.mjs +1 -1
- package/dist/node/index.d.mts +4 -2
- package/dist/recipes/interactive-auth.d.mts +2 -2
- package/dist/recipes/interactive-auth.mjs +1 -1
- package/dist/{rolldown-runtime-DYf_mQCB.mjs → rolldown-runtime-BVN1G_yT.mjs} +4 -4
- package/dist/rpc/dump.d.mts +1 -1
- package/dist/rpc/index.d.mts +121 -3
- package/dist/rpc/transports/sse-client.d.mts +34 -2
- package/dist/rpc/transports/sse-server.d.mts +2 -2
- package/dist/rpc/transports/ws-bun.d.mts +2 -2
- package/dist/rpc/transports/ws-client.d.mts +27 -2
- package/dist/rpc/transports/ws-deno.d.mts +2 -2
- package/dist/rpc/transports/ws-server.d.mts +150 -3
- package/dist/{rpc-core-CDUizUQB.mjs → rpc-core-BmDHiDR6.mjs} +1 -1
- package/dist/{rpc-core-CFwyV10r.d.mts → rpc-core-CblgPYJ_.d.mts} +3 -3
- package/dist/{shared-state-COV7NCbd.mjs → shared-state-DiAsLHP8.mjs} +3 -2
- package/dist/{state-B_yjfeqo.mjs → state-TdDWqiG-.mjs} +2 -1
- package/dist/types/index.d.mts +3 -3
- package/dist/{types-844OBepb.d.mts → types-KZOyhez5.d.mts} +1 -0
- package/dist/utils/debounce.d.mts +6 -0
- package/dist/utils/events.d.mts +1 -1
- package/dist/utils/get-port.mjs +1 -1
- package/dist/utils/launch-editor.mjs +1 -1
- package/dist/utils/nostics.d.mts +40 -2
- package/dist/utils/origin.d.mts +55 -2
- package/dist/utils/serve-static.d.mts +1 -1
- package/dist/utils/shared-state.d.mts +1 -1
- package/dist/utils/shared-state.mjs +1 -1
- package/dist/utils/streaming-channel.d.mts +1 -1
- package/package.json +6 -6
- package/dist/index-D0qrBkhO.d.mts +0 -121
- package/dist/index-HMJPlexc.d.mts +0 -84
- package/dist/nostics-Dgwh7ytT.d.mts +0 -40
- package/dist/origin-D5i7K_Zb.d.mts +0 -56
- package/dist/sse-client-B2PrSz-H.d.mts +0 -35
- package/dist/ws-client-lqOeANcn.d.mts +0 -28
- package/dist/ws-server-CYHkeyA-.d.mts +0 -150
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { k as SharedState, o as DevframeNodeContext, s as DevframeNodeRpcSession } from "./context-WxTq6kqb.mjs";
|
|
2
|
-
import { n as InternalAnonymousAuthStorage } from "./context-CsdPs3po.mjs";
|
|
3
|
-
/**
|
|
4
|
-
* Flip `isTrusted` to false on any live WS clients connected with `token`
|
|
5
|
-
* and broadcast the `auth:revoked` event so they can react.
|
|
6
|
-
*
|
|
7
|
-
* Shared between persisted-auth revocation and remote-dock token revocation.
|
|
8
|
-
*/
|
|
9
|
-
declare function revokeActiveConnectionsForToken(context: DevframeNodeContext, token: string): Promise<void>;
|
|
10
|
-
/**
|
|
11
|
-
* Revoke an auth token: remove from storage and notify all connected clients
|
|
12
|
-
* using this token that they are no longer trusted.
|
|
13
|
-
*/
|
|
14
|
-
declare function revokeAuthToken(context: DevframeNodeContext, storage: SharedState<InternalAnonymousAuthStorage>, token: string): Promise<void>;
|
|
15
|
-
/**
|
|
16
|
-
* Format a raw `navigator.userAgent` string into the short display label
|
|
17
|
-
* shown for a trusted device (e.g. "Chrome 120 | macOS 14 desktop").
|
|
18
|
-
*
|
|
19
|
-
* The client used to parse+format this itself, but that pulled
|
|
20
|
-
* `ua-parser-modern` into the browser bundle for a label nothing else on
|
|
21
|
-
* the client needs; the client now sends the raw string and parsing
|
|
22
|
-
* happens here, at the server ingress, keeping the persisted label format
|
|
23
|
-
* identical.
|
|
24
|
-
*/
|
|
25
|
-
declare function describeUA(userAgent: string): string;
|
|
26
|
-
/**
|
|
27
|
-
* The current one-time authentication code. Display this to the user (e.g. in
|
|
28
|
-
* the dev-server terminal) so they can type it into the browser to authenticate.
|
|
29
|
-
*/
|
|
30
|
-
declare function getTempAuthCode(): string;
|
|
31
|
-
/**
|
|
32
|
-
* The current code plus its expiry timestamp, for display (e.g. the auth
|
|
33
|
-
* banner). An already-expired code is rotated first, so the returned code is
|
|
34
|
-
* always redeemable for its remaining lifetime.
|
|
35
|
-
*/
|
|
36
|
-
declare function getTempAuthCodeInfo(): {
|
|
37
|
-
code: string;
|
|
38
|
-
expireAt: number;
|
|
39
|
-
};
|
|
40
|
-
/**
|
|
41
|
-
* Rotate the authentication code, resetting its expiry window and failed-attempt
|
|
42
|
-
* counter. Call this when a new authentication flow begins (e.g. when an
|
|
43
|
-
* untrusted client starts authenticating) so the displayed code is freshly
|
|
44
|
-
* valid for its full TTL.
|
|
45
|
-
*/
|
|
46
|
-
declare function refreshTempAuthCode(): string;
|
|
47
|
-
/**
|
|
48
|
-
* Build a "magic link" authentication URL that embeds a one-time code (OTP) in
|
|
49
|
-
* the URL **fragment**. Opening it authenticates the client without typing;
|
|
50
|
-
* print it on startup (devframe stays headless, so the host prints its own
|
|
51
|
-
* banner). Defaults to the current code; the link is subject to the same TTL.
|
|
52
|
-
*
|
|
53
|
-
* The code rides the fragment (`#devframe_otp=…`), not the query string, so it
|
|
54
|
-
* is never sent to the server, written to an access log, or leaked in a
|
|
55
|
-
* `Referer` header; the browser client reads it locally (see
|
|
56
|
-
* `consumeOtpFromUrl`). Any existing fragment parameters are preserved.
|
|
57
|
-
*/
|
|
58
|
-
declare function buildOtpAuthUrl(baseUrl: string, code?: string): string;
|
|
59
|
-
/**
|
|
60
|
-
* Re-authenticate a connection that presents a previously-issued bearer token.
|
|
61
|
-
* Returns `true` and marks the session trusted when the token is known.
|
|
62
|
-
*
|
|
63
|
-
* Used by the `anonymous:devframe:auth` handler so a client that already
|
|
64
|
-
* authenticated (token persisted in the browser) is trusted on reconnect
|
|
65
|
-
* without entering the code again.
|
|
66
|
-
*/
|
|
67
|
-
declare function verifyAuthToken(token: string, session: DevframeNodeRpcSession, storage: SharedState<InternalAnonymousAuthStorage>): boolean;
|
|
68
|
-
/**
|
|
69
|
-
* Exchange a one-time authentication code for a fresh, node-issued bearer token.
|
|
70
|
-
*
|
|
71
|
-
* On success this mints a high-entropy token, records it in the trusted store,
|
|
72
|
-
* marks the calling session trusted, rotates the code, and returns the token
|
|
73
|
-
* for the client to persist. Returns `null` on any failure.
|
|
74
|
-
*
|
|
75
|
-
* Because the code is short and human-typed, verification is hardened against
|
|
76
|
-
* brute force: it enforces a time-to-live, compares in constant time, and
|
|
77
|
-
* rotates the code after {@link TEMP_AUTH_MAX_ATTEMPTS} failed attempts so an
|
|
78
|
-
* attacker cannot keep guessing against the same code.
|
|
79
|
-
*/
|
|
80
|
-
declare function exchangeTempAuthCode(code: string, session: DevframeNodeRpcSession, info: {
|
|
81
|
-
ua: string;
|
|
82
|
-
origin: string;
|
|
83
|
-
}, storage: SharedState<InternalAnonymousAuthStorage>): string | null;
|
|
84
|
-
export { getTempAuthCodeInfo as a, revokeActiveConnectionsForToken as c, getTempAuthCode as i, revokeAuthToken as l, describeUA as n, refreshTempAuthCode as o, exchangeTempAuthCode as r, verifyAuthToken as s, buildOtpAuthUrl as t };
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { AnyDiagnosticReporter, AnyDiagnosticReporter as AnyDiagnosticReporter$1, ConsoleMethod, ConsoleReporterOptions, Diagnostic, Diagnostic as Diagnostic$1, DiagnosticCallParams, DiagnosticDefinition, DiagnosticDefinition as DiagnosticDefinition$1, DiagnosticHandle, DiagnosticInit, DiagnosticReporter, Diagnostics, Diagnostics as Diagnostics$1, createConsoleReporter, defineProdDiagnostics, formatDiagnostic } from "nostics";
|
|
2
|
-
import { ansiFormatter } from "nostics/formatters/ansi";
|
|
3
|
-
/**
|
|
4
|
-
* The reporter every {@link defineDiagnostics} call below wires in ahead of
|
|
5
|
-
* any caller-supplied ones: prints the diagnostic through devframe's own
|
|
6
|
-
* ANSI colors via `console[method]` (default `'warn'`).
|
|
7
|
-
*/
|
|
8
|
-
declare function devframeReporter(d: Diagnostic, { method }?: {
|
|
9
|
-
method?: 'log' | 'warn' | 'error';
|
|
10
|
-
}): void;
|
|
11
|
-
/**
|
|
12
|
-
* Options accepted by {@link defineDiagnostics}, identical to `nostics`'s
|
|
13
|
-
* own `DefineDiagnosticsOptions`, minus the reporter devframe already
|
|
14
|
-
* prepends.
|
|
15
|
-
*/
|
|
16
|
-
type DevframeDefineDiagnosticsOptions<Codes extends Record<string, DiagnosticDefinition>, Reporters extends readonly AnyDiagnosticReporter[] = []> = Parameters<typeof defineDiagnostics<Codes, Reporters>>[0];
|
|
17
|
-
/**
|
|
18
|
-
* Drop-in replacement for `nostics`'s `defineDiagnostics()` with devframe's
|
|
19
|
-
* ANSI console reporter pre-wired ahead of any `reporters` passed in. Every
|
|
20
|
-
* `diagnostics.ts` in devframe core, `@devframes/hub`, `@devframes/json-render`,
|
|
21
|
-
* and the built-in plugins defines its codes through this instead of
|
|
22
|
-
* `nostics`'s own `defineDiagnostics`; the reporter registration lives
|
|
23
|
-
* here, once, so none of them need to build their own reporter (`colors`,
|
|
24
|
-
* `ansiFormatter`) or take a direct dependency on `nostics` themselves.
|
|
25
|
-
*/
|
|
26
|
-
declare function defineDiagnostics<const Codes extends Record<string, DiagnosticDefinition>, const Reporters extends readonly AnyDiagnosticReporter[] = []>(options: {
|
|
27
|
-
docsBase?: string | ((code: keyof Codes) => string | undefined);
|
|
28
|
-
codes: Codes;
|
|
29
|
-
reporters?: Reporters;
|
|
30
|
-
}): DevframeDiagnostics<Codes, Reporters>;
|
|
31
|
-
/**
|
|
32
|
-
* The `Diagnostics` object returned by devframe's {@link defineDiagnostics}
|
|
33
|
-
* (devframe's ANSI console reporter is always prepended). Integrations that
|
|
34
|
-
* export their own `defineDiagnostics(...)` result as public API annotate it
|
|
35
|
-
* with this type, so the reference resolves through `devframe/utils/nostics`
|
|
36
|
-
* rather than inlining `nostics`'s types or taking a direct `nostics`
|
|
37
|
-
* dependency.
|
|
38
|
-
*/
|
|
39
|
-
type DevframeDiagnostics<Codes extends Record<string, DiagnosticDefinition>, Reporters extends readonly AnyDiagnosticReporter[] = []> = Diagnostics<Codes, readonly [typeof devframeReporter, ...Reporters]>;
|
|
40
|
-
export { formatDiagnostic as _, DevframeDiagnostics as a, DiagnosticDefinition$1 as c, DiagnosticReporter as d, Diagnostics$1 as f, defineProdDiagnostics as g, defineDiagnostics as h, DevframeDefineDiagnosticsOptions as i, DiagnosticHandle as l, createConsoleReporter as m, ConsoleMethod as n, Diagnostic$1 as o, ansiFormatter as p, ConsoleReporterOptions as r, DiagnosticCallParams as s, AnyDiagnosticReporter$1 as t, DiagnosticInit as u };
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Origin and hostname predicates shared by the RPC transports (the WS upgrade,
|
|
3
|
-
* SSE, and MCP origin gates) and the instance shell's authentication-link
|
|
4
|
-
* origin validation. Kept dependency-free and runtime-agnostic so any consumer
|
|
5
|
-
* can pull in a single check without dragging in a transport's `crossws`
|
|
6
|
-
* import.
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* Whether `hostname` names a loopback host: `localhost` (or any `*.localhost`
|
|
10
|
-
* subdomain), the IPv6 loopback `::1`, or an IPv4 literal inside the
|
|
11
|
-
* `127.0.0.0/8` loopback block.
|
|
12
|
-
*
|
|
13
|
-
* The IPv4 case is matched **structurally**: the whole hostname must be a
|
|
14
|
-
* canonical dotted-decimal IPv4 literal whose first octet is `127`. A bare
|
|
15
|
-
* `startsWith('127.')` prefix check would also accept an attacker-controlled
|
|
16
|
-
* DNS name that merely *begins* with `127.` (`127.attacker.example`,
|
|
17
|
-
* `127.0.0.1.attacker.example`), letting a cross-origin browser page defeat
|
|
18
|
-
* the loopback origin gate that guards the RPC/MCP surface (a DNS-rebinding /
|
|
19
|
-
* cross-site WebSocket-hijacking bypass). Requiring a real IPv4 literal keeps
|
|
20
|
-
* genuine loopback addresses (`127.0.0.1`, `127.5.5.5`) allowed while rejecting
|
|
21
|
-
* those DNS names.
|
|
22
|
-
*/
|
|
23
|
-
declare function isLoopbackHostname(hostname: string): boolean;
|
|
24
|
-
/**
|
|
25
|
-
* Whether `address` is a loopback peer address as reported by a socket
|
|
26
|
-
* (`net.Socket.remoteAddress`): the IPv6 loopback `::1`, an IPv4 literal in
|
|
27
|
-
* `127.0.0.0/8`, or an IPv4-mapped IPv6 form of one (`::ffff:127.0.0.1`).
|
|
28
|
-
*
|
|
29
|
-
* Unlike {@link isLoopbackHostname} this takes a raw address, not a hostname:
|
|
30
|
-
* it never accepts a `localhost`-style name (a socket peer is always a literal
|
|
31
|
-
* address) and understands the IPv4-mapped IPv6 form the OS hands back on a
|
|
32
|
-
* dual-stack listener. Used to prove a same-machine caller from the connected
|
|
33
|
-
* peer, which a client cannot forge, rather than from the `Origin` header,
|
|
34
|
-
* which it can.
|
|
35
|
-
*/
|
|
36
|
-
declare function isLoopbackAddress(address: string): boolean;
|
|
37
|
-
/**
|
|
38
|
-
* Default origin policy for a localhost dev tool: allow requests with no
|
|
39
|
-
* `Origin` header (native, non-browser clients), allow any loopback origin
|
|
40
|
-
* (so cross-port localhost dev setups keep working), and allow explicitly
|
|
41
|
-
* configured origins. Everything else, such as a real remote page in the dev's
|
|
42
|
-
* browser, is rejected.
|
|
43
|
-
*/
|
|
44
|
-
declare function isAllowedOrigin(origin: string | undefined, allowedOrigins: readonly string[]): boolean;
|
|
45
|
-
/**
|
|
46
|
-
* Decide whether a request-derived origin candidate may back a devframe's
|
|
47
|
-
* advertised public origin, the destination of the OTP magic link. Stricter
|
|
48
|
-
* than {@link isAllowedOrigin}: it rejects credentials, a path, a query, a
|
|
49
|
-
* fragment, a malformed port, and non-HTTP(S) schemes, and adopts a candidate
|
|
50
|
-
* only when its hostname is loopback or its canonical origin exactly matches
|
|
51
|
-
* an `allowedOrigins` entry (a caller with no static list passes none, so only
|
|
52
|
-
* loopback qualifies). Returns the canonical origin to adopt, or `undefined`
|
|
53
|
-
* to reject. Forwarded headers are never consulted.
|
|
54
|
-
*/
|
|
55
|
-
declare function validateOriginCandidate(candidate: string, allowedOrigins?: readonly string[]): string | undefined;
|
|
56
|
-
export { validateOriginCandidate as i, isLoopbackAddress as n, isLoopbackHostname as r, isAllowedOrigin as t };
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { a as ChannelOptions } from "./index-BKu9BxcT.mjs";
|
|
2
|
-
import { g as RpcFunctionDefinitionAny } from "./types-844OBepb.mjs";
|
|
3
|
-
interface SseRpcChannelOptions {
|
|
4
|
-
/** Resolved `http(s)://` URL of the SSE endpoint. */
|
|
5
|
-
url: string;
|
|
6
|
-
onConnected?: () => void;
|
|
7
|
-
onError?: (e: Error) => void;
|
|
8
|
-
onDisconnected?: () => void;
|
|
9
|
-
authToken?: string;
|
|
10
|
-
/**
|
|
11
|
-
* RPC function definitions (or just the `jsonSerializable` flag per
|
|
12
|
-
* method) used to dispatch the per-call wire serializer, the same contract
|
|
13
|
-
* as the WS channel.
|
|
14
|
-
*/
|
|
15
|
-
definitions?: ReadonlyMap<string, Pick<RpcFunctionDefinitionAny, 'jsonSerializable'>>;
|
|
16
|
-
/** Fetch implementation. Default: `globalThis.fetch`. */
|
|
17
|
-
fetch?: typeof globalThis.fetch;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Build a birpc `ChannelOptions` object backed by an SSE stream (server →
|
|
21
|
-
* client) and HTTP `POST` (client → server): the WebSocket-free counterpart
|
|
22
|
-
* to `createWsRpcChannel`, wire-compatible with `attachSseRpcTransport`.
|
|
23
|
-
*
|
|
24
|
-
* The stream is consumed via `fetch` streaming (not `EventSource`), so it
|
|
25
|
-
* works in browsers and server runtimes alike. The server's first frame
|
|
26
|
-
* (`event: session`) carries the session id; every `POST` echoes it in the
|
|
27
|
-
* `x-birpc-session` header. A response to a client-initiated request comes
|
|
28
|
-
* back in the `POST`'s own body and is re-injected into the channel; a
|
|
29
|
-
* dropped stream terminates the channel; there is no reconnect, matching
|
|
30
|
-
* the WS channel's closed-is-done semantics.
|
|
31
|
-
*/
|
|
32
|
-
declare function createSseRpcChannel(options: SseRpcChannelOptions): ChannelOptions & {
|
|
33
|
-
close: () => void;
|
|
34
|
-
};
|
|
35
|
-
export { createSseRpcChannel as n, SseRpcChannelOptions as t };
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { a as ChannelOptions } from "./index-BKu9BxcT.mjs";
|
|
2
|
-
import { g as RpcFunctionDefinitionAny } from "./types-844OBepb.mjs";
|
|
3
|
-
interface WsRpcChannelOptions {
|
|
4
|
-
url: string;
|
|
5
|
-
onConnected?: (e: Event) => void;
|
|
6
|
-
onError?: (e: Error) => void;
|
|
7
|
-
onDisconnected?: (e: CloseEvent) => void;
|
|
8
|
-
authToken?: string;
|
|
9
|
-
/**
|
|
10
|
-
* RPC function definitions (or just the `jsonSerializable` flag per
|
|
11
|
-
* method) used to dispatch the per-call wire serializer. Pass an
|
|
12
|
-
* empty / partial map on clients that don't have the full registry;
|
|
13
|
-
* encoding falls back to structured-clone (the safer superset) and
|
|
14
|
-
* decoding still routes correctly via the wire prefix.
|
|
15
|
-
*/
|
|
16
|
-
definitions?: ReadonlyMap<string, Pick<RpcFunctionDefinitionAny, 'jsonSerializable'>>;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Build a birpc `ChannelOptions` object backed by a browser `WebSocket`.
|
|
20
|
-
* Pass the result straight to `createRpcClient`'s `channel` option.
|
|
21
|
-
*
|
|
22
|
-
* Also returns `close()`, closing the underlying socket, mirroring the server transport's
|
|
23
|
-
* existing `WsRpcTransport.close()`. `birpc`'s own `ChannelOptions` has no teardown of its own.
|
|
24
|
-
*/
|
|
25
|
-
declare function createWsRpcChannel(options: WsRpcChannelOptions): ChannelOptions & {
|
|
26
|
-
close: () => void;
|
|
27
|
-
};
|
|
28
|
-
export { createWsRpcChannel as n, WsRpcChannelOptions as t };
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { a as ChannelOptions, n as BirpcGroup } from "./index-BKu9BxcT.mjs";
|
|
2
|
-
import { g as RpcFunctionDefinitionAny } from "./types-844OBepb.mjs";
|
|
3
|
-
import { n as DevframeRpcConnection, t as DevframeNodeRpcSessionMeta } from "./session-Y9R6tqg4.mjs";
|
|
4
|
-
import { Hooks } from "crossws";
|
|
5
|
-
import { NodeAdapter } from "crossws/adapters/node";
|
|
6
|
-
import { Buffer } from "node:buffer";
|
|
7
|
-
import { IncomingMessage, Server } from "node:http";
|
|
8
|
-
import { Server as Server$1, ServerOptions } from "node:https";
|
|
9
|
-
import { AddressInfo } from "node:net";
|
|
10
|
-
import { Duplex } from "node:stream";
|
|
11
|
-
interface WsRpcTransportOptions {
|
|
12
|
-
/**
|
|
13
|
-
* Attach to an existing HTTP(S) server, sharing its port. Combine with
|
|
14
|
-
* `path` to bind the WS endpoint to a single route so it coexists with
|
|
15
|
-
* other upgrade handlers on the same server (e.g. a Vite dev server's HMR
|
|
16
|
-
* socket). The shared server's lifecycle is owned by the caller; closing
|
|
17
|
-
* this transport detaches the upgrade listener without closing the server.
|
|
18
|
-
*/
|
|
19
|
-
server?: Server | Server$1;
|
|
20
|
-
/**
|
|
21
|
-
* Port for the standalone WebSocket server. Defaults to `0`, which lets the
|
|
22
|
-
* operating system assign an available port.
|
|
23
|
-
*/
|
|
24
|
-
port?: number;
|
|
25
|
-
/** Host for the standalone WebSocket server. Defaults to `localhost`. */
|
|
26
|
-
host?: string;
|
|
27
|
-
/**
|
|
28
|
-
* Restrict the WS endpoint to a single upgrade route (e.g. `/__ws`). When
|
|
29
|
-
* sharing a `server`, non-matching upgrade requests are left untouched for
|
|
30
|
-
* other listeners to handle, so devframe's socket can sit alongside
|
|
31
|
-
* framework sockets (Vite HMR, etc.).
|
|
32
|
-
*/
|
|
33
|
-
path?: string;
|
|
34
|
-
/**
|
|
35
|
-
* Create the adapter without binding it to anything: no server is created,
|
|
36
|
-
* no port is bound, no `upgrade` listener is installed. The caller drives
|
|
37
|
-
* the socket itself through {@link WsRpcTransport.handleUpgrade} (from its
|
|
38
|
-
* own `upgrade` listener) or {@link WsRpcTransport.attach} (to bind a
|
|
39
|
-
* server later). Takes precedence over `server` / `port` / `https`.
|
|
40
|
-
*/
|
|
41
|
-
unbound?: boolean;
|
|
42
|
-
/**
|
|
43
|
-
* Destroy upgrade requests that don't match `path` instead of leaving them
|
|
44
|
-
* for other listeners. Enable this when devframe owns the shared server
|
|
45
|
-
* outright (nothing else handles its upgrades), so an off-route client is
|
|
46
|
-
* rejected promptly rather than left hanging. Default: `false`
|
|
47
|
-
* (coexist-friendly); servers this transport creates itself always
|
|
48
|
-
* destroy unmatched upgrades.
|
|
49
|
-
*/
|
|
50
|
-
destroyUnmatched?: boolean;
|
|
51
|
-
/** When set, a new https.Server is created and the WS endpoint is attached to it. */
|
|
52
|
-
https?: ServerOptions;
|
|
53
|
-
/**
|
|
54
|
-
* Extra origins to accept on the WS upgrade beyond the loopback default.
|
|
55
|
-
* Add your LAN/tunnel origin here when reaching the tool from another host.
|
|
56
|
-
* Pass `false` to disable origin checking entirely (not recommended).
|
|
57
|
-
* Default: loopback-only.
|
|
58
|
-
*/
|
|
59
|
-
allowedOrigins?: readonly string[] | WsOriginRegistry | false;
|
|
60
|
-
/**
|
|
61
|
-
* RPC function definitions, used by the per-call wire serializer to
|
|
62
|
-
* dispatch between strict-JSON and structured-clone encoding based
|
|
63
|
-
* on each function's `jsonSerializable` flag.
|
|
64
|
-
*
|
|
65
|
-
* When omitted, all messages fall back to structured-clone: safe but
|
|
66
|
-
* loses dev-time validation for `jsonSerializable: true` declarations.
|
|
67
|
-
*/
|
|
68
|
-
definitions?: ReadonlyMap<string, Pick<RpcFunctionDefinitionAny, 'jsonSerializable'>>;
|
|
69
|
-
onConnected?: (connection: DevframeRpcConnection, meta: DevframeNodeRpcSessionMeta) => void;
|
|
70
|
-
onDisconnected?: (connection: DevframeRpcConnection, meta: DevframeNodeRpcSessionMeta) => void;
|
|
71
|
-
/** Override the default per-call serializer. Most callers should leave this unset. */
|
|
72
|
-
serialize?: ChannelOptions['serialize'];
|
|
73
|
-
/** Override the default per-call deserializer. Most callers should leave this unset. */
|
|
74
|
-
deserialize?: ChannelOptions['deserialize'];
|
|
75
|
-
}
|
|
76
|
-
interface CreateWsOriginRegistryOptions {
|
|
77
|
-
/** Origins allowed before any external viewers are registered. */
|
|
78
|
-
allowedOrigins?: readonly string[];
|
|
79
|
-
/** Additional validation to run after the registration token is verified. */
|
|
80
|
-
validateOrigin?: (origin: string) => boolean;
|
|
81
|
-
}
|
|
82
|
-
interface WsOriginRegistry {
|
|
83
|
-
/** Registration token to include in connection metadata. */
|
|
84
|
-
readonly token: string;
|
|
85
|
-
/** Read and register an origin from a connection bootstrap URL. */
|
|
86
|
-
registerFromUrl: (url: string) => string | undefined;
|
|
87
|
-
/** Check whether an origin is currently allowed. */
|
|
88
|
-
isAllowed: (origin: string | undefined) => boolean;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Create a live, token-protected origin allowlist for external browser
|
|
92
|
-
* viewers. Pass it to {@link WsRpcTransportOptions.allowedOrigins}, then use
|
|
93
|
-
* `registerFromUrl()` in the connection metadata handler to authorize a
|
|
94
|
-
* viewer without sharing a mutable array or disabling DNS-rebinding protection.
|
|
95
|
-
*/
|
|
96
|
-
declare function createWsOriginRegistry(options?: CreateWsOriginRegistryOptions): WsOriginRegistry;
|
|
97
|
-
interface WsRpcTransport {
|
|
98
|
-
/**
|
|
99
|
-
* The crossws node adapter driving the socket; exposes the connected
|
|
100
|
-
* `peers` and pub/sub. See https://crossws.h3.dev.
|
|
101
|
-
*/
|
|
102
|
-
ws: NodeAdapter;
|
|
103
|
-
/** Resolves when the transport-owned server is listening. */
|
|
104
|
-
ready: Promise<void>;
|
|
105
|
-
/** Returns the bound address, or `null` when the server is not listening. */
|
|
106
|
-
address: () => AddressInfo | string | null;
|
|
107
|
-
/**
|
|
108
|
-
* Complete a `node:http` `upgrade` event on this transport, applying the
|
|
109
|
-
* same `path` filter and origin gate the transport's own listener uses.
|
|
110
|
-
* Wire it into a host server directly (`server.on('upgrade',
|
|
111
|
-
* transport.handleUpgrade)`) or call it from an existing listener.
|
|
112
|
-
*/
|
|
113
|
-
handleUpgrade: (req: IncomingMessage, socket: Duplex, head: Buffer) => void;
|
|
114
|
-
/**
|
|
115
|
-
* Route a server's `upgrade` events to this transport, returning a detach
|
|
116
|
-
* function. Use it to bind an `unbound` transport once the host server
|
|
117
|
-
* exists; {@link WsRpcTransport.close} detaches every server attached this
|
|
118
|
-
* way (without closing them, since the caller owns their lifecycle).
|
|
119
|
-
*/
|
|
120
|
-
attach: (server: Server | Server$1) => () => void;
|
|
121
|
-
/** Remove the upgrade listener from a shared `server` (a no-op otherwise). */
|
|
122
|
-
detach: () => void;
|
|
123
|
-
/**
|
|
124
|
-
* Tear the transport down deterministically: detach from a shared server,
|
|
125
|
-
* force-terminate every connected peer, and close any server this
|
|
126
|
-
* transport created itself (`port` / `https` modes).
|
|
127
|
-
*/
|
|
128
|
-
close: () => Promise<void>;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* The per-peer lifecycle hooks driving a devframe RPC WebSocket, shaped for
|
|
132
|
-
* any [crossws](https://crossws.h3.dev) adapter. {@link attachWsRpcTransport}
|
|
133
|
-
* feeds them to the Node adapter; runtime-specific attachments (e.g. Bun's
|
|
134
|
-
* fetch-upgrade adapter) reuse the same hooks so every transport speaks the
|
|
135
|
-
* identical wire protocol: one birpc channel per peer, per-method
|
|
136
|
-
* `jsonSerializable` dispatch between strict JSON and structured-clone.
|
|
137
|
-
*/
|
|
138
|
-
declare function createWsRpcPeerHooks<ClientFunctions extends object, ServerFunctions extends object>(rpcGroup: BirpcGroup<ClientFunctions, ServerFunctions, false>, options?: Pick<WsRpcTransportOptions, 'onConnected' | 'onDisconnected' | 'definitions' | 'serialize' | 'deserialize'>): Partial<Hooks>;
|
|
139
|
-
/**
|
|
140
|
-
* Attach a WebSocket transport to an existing RPC group, powered by
|
|
141
|
-
* [crossws](https://crossws.h3.dev). Either attach to an existing HTTP(S)
|
|
142
|
-
* `server` (sharing its port, optionally scoped to a `path`), or let this
|
|
143
|
-
* helper create a standalone server from `port` / `host` / `https`.
|
|
144
|
-
*
|
|
145
|
-
* Returns the crossws node adapter, standalone-server readiness/address
|
|
146
|
-
* accessors, `detach` (remove the upgrade listener from a shared `server`),
|
|
147
|
-
* and `close` (full deterministic teardown).
|
|
148
|
-
*/
|
|
149
|
-
declare function attachWsRpcTransport<ClientFunctions extends object, ServerFunctions extends object>(rpcGroup: BirpcGroup<ClientFunctions, ServerFunctions, false>, options?: WsRpcTransportOptions): WsRpcTransport;
|
|
150
|
-
export { attachWsRpcTransport as a, WsRpcTransportOptions as i, WsOriginRegistry as n, createWsOriginRegistry as o, WsRpcTransport as r, createWsRpcPeerHooks as s, CreateWsOriginRegistryOptions as t };
|