devframe 0.8.0 → 0.8.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/dist/adapters/build.d.mts +1 -1
- package/dist/adapters/build.mjs +2 -2
- package/dist/adapters/cac.d.mts +1 -1
- package/dist/adapters/cac.mjs +1 -1
- package/dist/adapters/cli.d.mts +1 -1
- package/dist/adapters/cli.mjs +1 -1
- package/dist/adapters/dev.d.mts +15 -2
- package/dist/adapters/dev.mjs +1 -1
- package/dist/adapters/embedded.d.mts +1 -1
- package/dist/adapters/mcp.d.mts +11 -5
- package/dist/adapters/mcp.mjs +1 -1
- package/dist/{cac-B-R_tDGJ.mjs → cac-D4_9ok0z.mjs} +1 -1
- package/dist/cli/main.mjs +4 -3
- package/dist/client/index.d.mts +37 -8
- package/dist/client/index.mjs +41 -15
- package/dist/constants.d.mts +13 -6
- package/dist/constants.mjs +13 -6
- package/dist/{context-C9Cgm1hP.mjs → context-CBg8iRbQ.mjs} +3 -2
- package/dist/{context-7BbaIUSI.d.mts → context-DoSozfvx.d.mts} +1 -1
- package/dist/{revoke-BtQDKTp7.mjs → crypto-token-XCqTSMg9.mjs} +1 -35
- package/dist/{dev-D4M7Veo7.mjs → dev-Bc49u3qg.mjs} +7 -5
- package/dist/{devframe-Dsjn_Xtq.d.mts → devframe-mQ4qZAuo.d.mts} +10 -1
- package/dist/{diagnostics-B5-qHeqD.mjs → diagnostics-D7wM2cwM.mjs} +4 -0
- package/dist/{fetch-BZyK4v6W.mjs → fetch-BKaD0Vb3.mjs} +7 -6
- package/dist/helpers/vite.d.mts +15 -14
- package/dist/helpers/vite.mjs +8 -8
- package/dist/{host-h3-Kz7t5Xab.mjs → host-h3-D2hYZvDK.mjs} +2 -2
- package/dist/{http-BghOqfTD.mjs → http-C4T68YV6.mjs} +1 -1
- package/dist/{index-CeBbry0R.d.mts → index-b64Uuhy2.d.mts} +11 -6
- package/dist/index.d.mts +2 -2
- package/dist/{instance-registry-D6fxYu36.mjs → instance-registry-BnnA2Eoh.mjs} +1 -1
- package/dist/node/auth.d.mts +2 -2
- package/dist/node/auth.mjs +2 -2
- package/dist/node/hub-internals.d.mts +2 -2
- package/dist/node/hub-internals.mjs +1 -1
- package/dist/node/index.d.mts +23 -3
- package/dist/node/index.mjs +5 -5
- package/dist/recipes/common-rpc-functions.d.mts +1 -1
- package/dist/recipes/interactive-auth.d.mts +2 -2
- package/dist/recipes/interactive-auth.mjs +11 -3
- package/dist/revoke-DZbJ7Cl0.mjs +35 -0
- package/dist/rpc/transports/ws-server.d.mts +2 -2
- package/dist/rpc/transports/ws-server.mjs +75 -7
- package/dist/{server-CcAPxuoT.mjs → server-CD8XmBXl.mjs} +25 -6
- package/dist/{server-VLQJouOO.d.mts → server-UHWae43Q.d.mts} +21 -3
- package/dist/{state-WX3HT5a3.mjs → state-BeUHDDjk.mjs} +13 -6
- package/dist/{storage-Dzoc3NVC.mjs → storage-CTNVbuFB.mjs} +1 -1
- package/dist/types/index.d.mts +2 -2
- package/dist/utils/events.d.mts +1 -1
- package/dist/utils/shared-state.d.mts +1 -1
- package/dist/utils/streaming-channel.d.mts +1 -1
- package/dist/{ws-server-D_Vjtums.d.mts → ws-server-uKQcClcJ.d.mts} +36 -7
- package/package.json +2 -2
- package/skills/devframe/SKILL.md +3 -2
package/dist/helpers/vite.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { DEVFRAME_CONNECTION_META_FILENAME, DEVFRAME_WS_ROUTE } from "../constants.mjs";
|
|
2
|
-
import { t as diagnostics } from "../diagnostics-
|
|
2
|
+
import { t as diagnostics } from "../diagnostics-D7wM2cwM.mjs";
|
|
3
3
|
import { n as resolveBasePath, t as normalizeBasePath } from "../_shared-bWRzeSa0.mjs";
|
|
4
4
|
import { serveStaticNodeMiddleware } from "../utils/serve-static.mjs";
|
|
5
|
-
import { n as resolveDevServerPort, r as resolveMcpConnectionMeta, t as createDevServer } from "../dev-
|
|
5
|
+
import { n as resolveDevServerPort, r as resolveMcpConnectionMeta, t as createDevServer } from "../dev-Bc49u3qg.mjs";
|
|
6
6
|
import { resolve } from "pathe";
|
|
7
7
|
//#region src/helpers/vite.ts
|
|
8
8
|
/**
|
|
@@ -19,11 +19,11 @@ import { resolve } from "pathe";
|
|
|
19
19
|
* host-served SPA can discover the WS endpoint via
|
|
20
20
|
* {@link connectDevframe}.
|
|
21
21
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
22
|
+
* The side-car RPC server **gates by default** (devframe's interactive OTP
|
|
23
|
+
* unless the definition's `cli.auth` opts out), printing its code/link banner
|
|
24
|
+
* to stdout, so a bridged devframe isn't silently reachable by anything that
|
|
25
|
+
* can open its socket. Pass `options.auth: false` to opt out for a single-user
|
|
26
|
+
* localhost host, or a {@link DevframeAuthHandler} for a custom scheme.
|
|
27
27
|
*
|
|
28
28
|
* Use bridge mode when integrating with frameworks that own the SPA
|
|
29
29
|
* (Nuxt, Astro, SolidStart, plain Vite apps). For the all-in-one
|
|
@@ -58,7 +58,7 @@ function viteDevBridge(d, options = {}) {
|
|
|
58
58
|
port,
|
|
59
59
|
flags: mw.flags,
|
|
60
60
|
openBrowser: false,
|
|
61
|
-
auth: options.auth
|
|
61
|
+
auth: options.auth,
|
|
62
62
|
mcp: options.mcp
|
|
63
63
|
});
|
|
64
64
|
} catch (e) {
|
|
@@ -2,8 +2,8 @@ import { t as devframeReporter } from "./diagnostics-reporter-CsIG85Q5.mjs";
|
|
|
2
2
|
import { t as diagnostics } from "./diagnostics-hwjXp_UV.mjs";
|
|
3
3
|
import { RpcFunctionsCollectorBase } from "./rpc/index.mjs";
|
|
4
4
|
import { defineRpcFunction } from "./index.mjs";
|
|
5
|
-
import { t as diagnostics$1 } from "./diagnostics-
|
|
6
|
-
import { i as createEventEmitter, n as createSharedState, r as nanoid, t as createStorage } from "./storage-
|
|
5
|
+
import { t as diagnostics$1 } from "./diagnostics-D7wM2cwM.mjs";
|
|
6
|
+
import { i as createEventEmitter, n as createSharedState, r as nanoid, t as createStorage } from "./storage-CTNVbuFB.mjs";
|
|
7
7
|
import { defineDiagnostics } from "nostics";
|
|
8
8
|
import { isatty } from "node:tty";
|
|
9
9
|
import { formatWithOptions, inspect } from "node:util";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { W as DevframeNodeRpcSession, b as DevframeNodeContext, ht as SharedState } from "./devframe-
|
|
2
|
-
import { n as InternalAnonymousAuthStorage } from "./context-
|
|
1
|
+
import { W as DevframeNodeRpcSession, b as DevframeNodeContext, ht as SharedState } from "./devframe-mQ4qZAuo.mjs";
|
|
2
|
+
import { n as InternalAnonymousAuthStorage } from "./context-DoSozfvx.mjs";
|
|
3
3
|
//#region src/node/auth/revoke.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* Flip `isTrusted` to false on any live WS clients connected with `token`
|
|
@@ -28,10 +28,15 @@ declare function getTempAuthCode(): string;
|
|
|
28
28
|
*/
|
|
29
29
|
declare function refreshTempAuthCode(): string;
|
|
30
30
|
/**
|
|
31
|
-
* Build a "magic link" authentication URL that embeds a one-time code (OTP)
|
|
32
|
-
*
|
|
33
|
-
* it on startup (devframe stays headless, so the host prints its own
|
|
34
|
-
* Defaults to the current code; the link is subject to the same TTL.
|
|
31
|
+
* Build a "magic link" authentication URL that embeds a one-time code (OTP) in
|
|
32
|
+
* the URL **fragment**. Opening it authenticates the client without typing —
|
|
33
|
+
* print it on startup (devframe stays headless, so the host prints its own
|
|
34
|
+
* banner). Defaults to the current code; the link is subject to the same TTL.
|
|
35
|
+
*
|
|
36
|
+
* The code rides the fragment (`#devframe_otp=…`), not the query string, so it
|
|
37
|
+
* is never sent to the server, written to an access log, or leaked in a
|
|
38
|
+
* `Referer` header — the browser client reads it locally (see
|
|
39
|
+
* `consumeOtpFromUrl`). Any existing fragment parameters are preserved.
|
|
35
40
|
*/
|
|
36
41
|
declare function buildOtpAuthUrl(baseUrl: string, code?: string): string;
|
|
37
42
|
/**
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { $ as DevframeRpcServerFunctions, A as DevframeSettingsStore, At as DevframeAgentHostEvents, B as DevframeDefineDiagnosticsOptions, C as DevframeServicesHost, Ct as AgentResourceContent, D as DevframeScopedStreamingHost, Dt as AgentToolProvider, E as DevframeScopedNodeRpc, Et as AgentToolInput, F as ScopedSharedStates, G as RpcBroadcastOptions, H as DevframeDiagnosticsHost, I as SettingsForNamespace, J as RpcSharedStateHost, K as RpcFunctionsHost, L as DevframeViewHost, M as ScopedClientFunctions, Mt as EventUnsubscribe, N as ScopedRpcFn, Nt as EventsMap, O as DevframeSettings, Ot as AgentToolProviderHandle, P as ScopedServerFunctions, Q as DevframeRpcClientFunctions, R as DevframeHost, S as DevframeServiceOf, St as AgentResource, T as DevframeScopedNodeContext, Tt as AgentTool, U as DevframeDiagnosticsLogger, V as DevframeDiagnosticsDefinition, W as DevframeNodeRpcSession, X as RpcStreamingChannelOptions, Y as RpcStreamingChannel, Z as RpcStreamingHost, _ as ConnectionMeta, a as DevframeDockDefaults, b as DevframeNodeContext, bt as AgentHandle, c as DevframeSetupInfo, d as McpRouteOptions, et as DevframeRpcSharedStates, f as defineDevframe, g as Thenable, h as PartialWithoutId, i as DevframeDeploymentKind, j as ScopedBroadcastOptions, jt as EventEmitter, k as DevframeSettingsRegistry, kt as DevframeAgentHost, l as DevframeSpaOptions, m as EntriesToObject, n as DevframeCliOptions, o as DevframeDuplicationStrategy, q as RpcSharedStateGetOptions, r as DevframeDefinition, s as DevframeRuntime, t as DevframeBrowserContext, u as DevframeWsOptions, v as ConnectionMetaWebsocket, w as DevframeServicesRegistry, wt as AgentResourceInput, x as DevframeServiceId, xt as AgentManifest, y as DevframeCapabilities, z as DevframeStorageScope } from "./devframe-
|
|
1
|
+
import { $ as DevframeRpcServerFunctions, A as DevframeSettingsStore, At as DevframeAgentHostEvents, B as DevframeDefineDiagnosticsOptions, C as DevframeServicesHost, Ct as AgentResourceContent, D as DevframeScopedStreamingHost, Dt as AgentToolProvider, E as DevframeScopedNodeRpc, Et as AgentToolInput, F as ScopedSharedStates, G as RpcBroadcastOptions, H as DevframeDiagnosticsHost, I as SettingsForNamespace, J as RpcSharedStateHost, K as RpcFunctionsHost, L as DevframeViewHost, M as ScopedClientFunctions, Mt as EventUnsubscribe, N as ScopedRpcFn, Nt as EventsMap, O as DevframeSettings, Ot as AgentToolProviderHandle, P as ScopedServerFunctions, Q as DevframeRpcClientFunctions, R as DevframeHost, S as DevframeServiceOf, St as AgentResource, T as DevframeScopedNodeContext, Tt as AgentTool, U as DevframeDiagnosticsLogger, V as DevframeDiagnosticsDefinition, W as DevframeNodeRpcSession, X as RpcStreamingChannelOptions, Y as RpcStreamingChannel, Z as RpcStreamingHost, _ as ConnectionMeta, a as DevframeDockDefaults, b as DevframeNodeContext, bt as AgentHandle, c as DevframeSetupInfo, d as McpRouteOptions, et as DevframeRpcSharedStates, f as defineDevframe, g as Thenable, h as PartialWithoutId, i as DevframeDeploymentKind, j as ScopedBroadcastOptions, jt as EventEmitter, k as DevframeSettingsRegistry, kt as DevframeAgentHost, l as DevframeSpaOptions, m as EntriesToObject, n as DevframeCliOptions, o as DevframeDuplicationStrategy, q as RpcSharedStateGetOptions, r as DevframeDefinition, s as DevframeRuntime, t as DevframeBrowserContext, u as DevframeWsOptions, v as ConnectionMetaWebsocket, w as DevframeServicesRegistry, wt as AgentResourceInput, x as DevframeServiceId, xt as AgentManifest, y as DevframeCapabilities, z as DevframeStorageScope } from "./devframe-mQ4qZAuo.mjs";
|
|
2
2
|
import { C as RpcFunctionType, T as RpcReturnSchema, _ as RpcFunctionDefinition, g as RpcFunctionAgentOptions, i as RpcArgsSchema } from "./types-CnJSgRVa.mjs";
|
|
3
3
|
import "./index-Dbw1p5ch.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { n as DevframeNodeRpcSessionMeta } from "./ws-server-uKQcClcJ.mjs";
|
|
5
5
|
//#region src/define.d.ts
|
|
6
6
|
declare const defineRpcFunction: <NAME extends string, TYPE extends RpcFunctionType, ARGS extends any[], RETURN = void, const AS extends RpcArgsSchema | undefined = undefined, const RS extends RpcReturnSchema | undefined = undefined>(definition: RpcFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS, DevframeNodeContext>) => RpcFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS, DevframeNodeContext>;
|
|
7
7
|
//#endregion
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as diagnostics } from "./diagnostics-
|
|
1
|
+
import { t as diagnostics } from "./diagnostics-D7wM2cwM.mjs";
|
|
2
2
|
import { mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { join } from "pathe";
|
|
4
4
|
import process from "node:process";
|
package/dist/node/auth.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { p as DevframeAuthHandler } from "../devframe-
|
|
2
|
-
import { a as verifyAuthToken, i as refreshTempAuthCode, n as exchangeTempAuthCode, o as revokeActiveConnectionsForToken, r as getTempAuthCode, s as revokeAuthToken, t as buildOtpAuthUrl } from "../index-
|
|
1
|
+
import { p as DevframeAuthHandler } from "../devframe-mQ4qZAuo.mjs";
|
|
2
|
+
import { a as verifyAuthToken, i as refreshTempAuthCode, n as exchangeTempAuthCode, o as revokeActiveConnectionsForToken, r as getTempAuthCode, s as revokeAuthToken, t as buildOtpAuthUrl } from "../index-b64Uuhy2.mjs";
|
|
3
3
|
export { DevframeAuthHandler, buildOtpAuthUrl, exchangeTempAuthCode, getTempAuthCode, refreshTempAuthCode, revokeActiveConnectionsForToken, revokeAuthToken, verifyAuthToken };
|
package/dist/node/auth.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as revokeAuthToken, t as revokeActiveConnectionsForToken } from "../revoke-
|
|
2
|
-
import { a as verifyAuthToken, i as refreshTempAuthCode, n as exchangeTempAuthCode, r as getTempAuthCode, t as buildOtpAuthUrl } from "../state-
|
|
1
|
+
import { n as revokeAuthToken, t as revokeActiveConnectionsForToken } from "../revoke-DZbJ7Cl0.mjs";
|
|
2
|
+
import { a as verifyAuthToken, i as refreshTempAuthCode, n as exchangeTempAuthCode, r as getTempAuthCode, t as buildOtpAuthUrl } from "../state-BeUHDDjk.mjs";
|
|
3
3
|
export { buildOtpAuthUrl, exchangeTempAuthCode, getTempAuthCode, refreshTempAuthCode, revokeActiveConnectionsForToken, revokeAuthToken, verifyAuthToken };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as DevframeDeploymentKind, r as DevframeDefinition } from "../devframe-
|
|
2
|
-
import { a as internalContextMap, i as getInternalContext, n as InternalAnonymousAuthStorage, r as RemoteTokenRecord, t as DevframeInternalContext } from "../context-
|
|
1
|
+
import { i as DevframeDeploymentKind, r as DevframeDefinition } from "../devframe-mQ4qZAuo.mjs";
|
|
2
|
+
import { a as internalContextMap, i as getInternalContext, n as InternalAnonymousAuthStorage, r as RemoteTokenRecord, t as DevframeInternalContext } from "../context-DoSozfvx.mjs";
|
|
3
3
|
//#region src/adapters/_shared.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* Resolve the mount base path for a devframe's SPA. Hosted adapters
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as internalContextMap, t as getInternalContext } from "../context-
|
|
1
|
+
import { n as internalContextMap, t as getInternalContext } from "../context-CBg8iRbQ.mjs";
|
|
2
2
|
import { n as resolveBasePath, t as normalizeBasePath } from "../_shared-bWRzeSa0.mjs";
|
|
3
3
|
export { getInternalContext, internalContextMap, normalizeBasePath, resolveBasePath };
|
package/dist/node/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { At as DevframeAgentHostEvents, C as DevframeServicesHost, Ct as AgentResourceContent, Dt as AgentToolProvider, Et as AgentToolInput, H as DevframeDiagnosticsHost$1, J as RpcSharedStateHost, K as RpcFunctionsHost, L as DevframeViewHost$1, O as DevframeSettings, Ot as AgentToolProviderHandle, R as DevframeHost, S as DevframeServiceOf, St as AgentResource, T as DevframeScopedNodeContext, Tt as AgentTool, U as DevframeDiagnosticsLogger, Z as RpcStreamingHost, b as DevframeNodeContext, bt as AgentHandle, ht as SharedState, jt as EventEmitter, kt as DevframeAgentHost$1, wt as AgentResourceInput, x as DevframeServiceId, xt as AgentManifest } from "../devframe-
|
|
1
|
+
import { At as DevframeAgentHostEvents, C as DevframeServicesHost, Ct as AgentResourceContent, Dt as AgentToolProvider, Et as AgentToolInput, H as DevframeDiagnosticsHost$1, J as RpcSharedStateHost, K as RpcFunctionsHost, L as DevframeViewHost$1, O as DevframeSettings, Ot as AgentToolProviderHandle, R as DevframeHost, S as DevframeServiceOf, St as AgentResource, T as DevframeScopedNodeContext, Tt as AgentTool, U as DevframeDiagnosticsLogger, Z as RpcStreamingHost, b as DevframeNodeContext, bt as AgentHandle, ht as SharedState, jt as EventEmitter, kt as DevframeAgentHost$1, wt as AgentResourceInput, x as DevframeServiceId, xt as AgentManifest } from "../devframe-mQ4qZAuo.mjs";
|
|
2
2
|
import { v as RpcFunctionDefinitionAny } from "../types-CnJSgRVa.mjs";
|
|
3
3
|
import "../index-Dbw1p5ch.mjs";
|
|
4
|
-
import { n as StartedServer, r as startHttpAndWs, t as StartHttpAndWsOptions } from "../server-
|
|
4
|
+
import { n as StartedServer, r as startHttpAndWs, t as StartHttpAndWsOptions } from "../server-UHWae43Q.mjs";
|
|
5
5
|
import { BirpcGroup } from "birpc";
|
|
6
6
|
//#region src/node/agent-args.d.ts
|
|
7
7
|
/**
|
|
@@ -232,6 +232,26 @@ interface DevframeInstanceRegistration {
|
|
|
232
232
|
declare function registerDevframeInstance(record: DevframeInstanceRecord, options?: {
|
|
233
233
|
instancesDir?: string;
|
|
234
234
|
}): DevframeInstanceRegistration;
|
|
235
|
+
/**
|
|
236
|
+
* Read the registry and split records into live and dead by probing each
|
|
237
|
+
* one's `__connection.json`, deleting dead records (prune-on-read). Live
|
|
238
|
+
* records carry the dialable origin the probe confirmed (a `localhost`
|
|
239
|
+
* record may come back as `127.0.0.1` / `[::1]`).
|
|
240
|
+
*
|
|
241
|
+
* A liveness probe only proves *something* answers on the record's port, so
|
|
242
|
+
* records left behind by killed processes shadow the server currently bound
|
|
243
|
+
* there: per `(port, basePath)` only the newest record survives, older
|
|
244
|
+
* ghosts are pruned with the dead.
|
|
245
|
+
*
|
|
246
|
+
* @experimental
|
|
247
|
+
*/
|
|
248
|
+
declare function listLiveDevframeInstances(options?: {
|
|
249
|
+
instancesDir?: string;
|
|
250
|
+
timeoutMs?: number;
|
|
251
|
+
}): Promise<{
|
|
252
|
+
live: DevframeInstanceRecord[];
|
|
253
|
+
pruned: DevframeInstanceRecord[];
|
|
254
|
+
}>;
|
|
235
255
|
//#endregion
|
|
236
256
|
//#region src/node/rpc-shared-state.d.ts
|
|
237
257
|
declare function createRpcSharedStateServerHost(rpc: RpcFunctionsHost): RpcSharedStateHost;
|
|
@@ -278,4 +298,4 @@ declare function toDialableHost(host: string): string;
|
|
|
278
298
|
declare function formatHostForUrl(host: string): string;
|
|
279
299
|
declare function normalizeHttpServerUrl(host: string, port: number | string): string;
|
|
280
300
|
//#endregion
|
|
281
|
-
export { AgentArgsFallback, CreateH3DevframeHostOptions, CreateHostContextOptions, CreateStorageOptions, DevframeAgentHost, DevframeDiagnosticsHost, type DevframeInstanceRecord, type DevframeInstanceRegistration, DevframeServicesHostImpl, DevframeViewHost, type RpcFunctionsHost, StartHttpAndWsOptions, StartedServer, coerceAgentPositionalArgs, createH3DevframeHost, createHostContext, createNodeSettings, createRpcSharedStateServerHost, createRpcStreamingServerHost, createScopedNodeContext, createStorage, formatHostForUrl, isObject, normalizeHttpServerUrl, registerDevframeInstance, startHttpAndWs, toDialableHost };
|
|
301
|
+
export { AgentArgsFallback, CreateH3DevframeHostOptions, CreateHostContextOptions, CreateStorageOptions, DevframeAgentHost, DevframeDiagnosticsHost, type DevframeInstanceRecord, type DevframeInstanceRegistration, DevframeServicesHostImpl, DevframeViewHost, type RpcFunctionsHost, StartHttpAndWsOptions, StartedServer, coerceAgentPositionalArgs, createH3DevframeHost, createHostContext, createNodeSettings, createRpcSharedStateServerHost, createRpcStreamingServerHost, createScopedNodeContext, createStorage, formatHostForUrl, isObject, listLiveDevframeInstances, normalizeHttpServerUrl, registerDevframeInstance, startHttpAndWs, toDialableHost };
|
package/dist/node/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as DevframeViewHost, c as createRpcSharedStateServerHost, d as coerceAgentPositionalArgs, i as createNodeSettings, l as DevframeDiagnosticsHost, n as createHostContext, o as DevframeServicesHostImpl, r as createScopedNodeContext, s as createRpcStreamingServerHost, t as createH3DevframeHost, u as DevframeAgentHost } from "../host-h3-
|
|
2
|
-
import { t as createStorage } from "../storage-
|
|
3
|
-
import { r as registerDevframeInstance } from "../instance-registry-
|
|
4
|
-
import { a as toDialableHost, i as normalizeHttpServerUrl, n as formatHostForUrl, r as isObject, t as startHttpAndWs } from "../server-
|
|
5
|
-
export { DevframeAgentHost, DevframeDiagnosticsHost, DevframeServicesHostImpl, DevframeViewHost, coerceAgentPositionalArgs, createH3DevframeHost, createHostContext, createNodeSettings, createRpcSharedStateServerHost, createRpcStreamingServerHost, createScopedNodeContext, createStorage, formatHostForUrl, isObject, normalizeHttpServerUrl, registerDevframeInstance, startHttpAndWs, toDialableHost };
|
|
1
|
+
import { a as DevframeViewHost, c as createRpcSharedStateServerHost, d as coerceAgentPositionalArgs, i as createNodeSettings, l as DevframeDiagnosticsHost, n as createHostContext, o as DevframeServicesHostImpl, r as createScopedNodeContext, s as createRpcStreamingServerHost, t as createH3DevframeHost, u as DevframeAgentHost } from "../host-h3-D2hYZvDK.mjs";
|
|
2
|
+
import { t as createStorage } from "../storage-CTNVbuFB.mjs";
|
|
3
|
+
import { r as registerDevframeInstance, t as listLiveDevframeInstances } from "../instance-registry-BnnA2Eoh.mjs";
|
|
4
|
+
import { a as toDialableHost, i as normalizeHttpServerUrl, n as formatHostForUrl, r as isObject, t as startHttpAndWs } from "../server-CD8XmBXl.mjs";
|
|
5
|
+
export { DevframeAgentHost, DevframeDiagnosticsHost, DevframeServicesHostImpl, DevframeViewHost, coerceAgentPositionalArgs, createH3DevframeHost, createHostContext, createNodeSettings, createRpcSharedStateServerHost, createRpcStreamingServerHost, createScopedNodeContext, createStorage, formatHostForUrl, isObject, listLiveDevframeInstances, normalizeHttpServerUrl, registerDevframeInstance, startHttpAndWs, toDialableHost };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "../devframe-
|
|
1
|
+
import "../devframe-mQ4qZAuo.mjs";
|
|
2
2
|
import { E as Thenable, S as RpcFunctionSetupResult, c as RpcDump, g as RpcFunctionAgentOptions } from "../types-CnJSgRVa.mjs";
|
|
3
3
|
import "../index-Dbw1p5ch.mjs";
|
|
4
4
|
import { t as SimpleSchema } from "../simple-schema-BDzLeJDk.mjs";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as DevframeNodeContext, p as DevframeAuthHandler } from "../devframe-
|
|
2
|
-
import "../index-
|
|
1
|
+
import { b as DevframeNodeContext, p as DevframeAuthHandler } from "../devframe-mQ4qZAuo.mjs";
|
|
2
|
+
import "../index-b64Uuhy2.mjs";
|
|
3
3
|
//#region src/recipes/interactive-auth.d.ts
|
|
4
4
|
interface CreateInteractiveAuthOptions {
|
|
5
5
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as colors } from "../diagnostics-reporter-CsIG85Q5.mjs";
|
|
2
2
|
import { isAnonymousRpcMethod } from "../constants.mjs";
|
|
3
3
|
import { n as defineRpcFunction } from "../define-BLWPsH6y.mjs";
|
|
4
|
-
import { t as getInternalContext } from "../context-
|
|
5
|
-
import { a as verifyAuthToken, n as exchangeTempAuthCode, r as getTempAuthCode, t as buildOtpAuthUrl } from "../state-
|
|
4
|
+
import { t as getInternalContext } from "../context-CBg8iRbQ.mjs";
|
|
5
|
+
import { a as verifyAuthToken, n as exchangeTempAuthCode, r as getTempAuthCode, t as buildOtpAuthUrl } from "../state-BeUHDDjk.mjs";
|
|
6
6
|
import { t as s } from "../simple-schema-DQPZrAaZ.mjs";
|
|
7
7
|
//#region src/recipes/interactive-auth.ts
|
|
8
8
|
function defaultBanner(info) {
|
|
@@ -107,16 +107,24 @@ function createInteractiveAuth(context, options = {}) {
|
|
|
107
107
|
}
|
|
108
108
|
function onConnect(peer, session) {
|
|
109
109
|
let token;
|
|
110
|
+
let requestOrigin;
|
|
110
111
|
try {
|
|
111
112
|
token = new URL(peer.request?.url ?? "", "http://localhost").searchParams.get("devframe_auth_token") ?? void 0;
|
|
112
113
|
} catch {}
|
|
114
|
+
try {
|
|
115
|
+
requestOrigin = peer.request?.headers?.get?.("origin") ?? void 0;
|
|
116
|
+
} catch {}
|
|
113
117
|
if (!token) return;
|
|
114
118
|
if (isStaticToken(token)) {
|
|
115
119
|
session.meta.clientAuthToken = token;
|
|
116
120
|
session.meta.isTrusted = true;
|
|
117
121
|
return;
|
|
118
122
|
}
|
|
119
|
-
verifyAuthToken(token, session, storage);
|
|
123
|
+
if (verifyAuthToken(token, session, storage)) return;
|
|
124
|
+
if (internal.isRemoteTokenTrusted(token, requestOrigin)) {
|
|
125
|
+
session.meta.clientAuthToken = token;
|
|
126
|
+
session.meta.isTrusted = true;
|
|
127
|
+
}
|
|
120
128
|
}
|
|
121
129
|
function buildOpenUrl(url) {
|
|
122
130
|
return buildOtpAuthUrl(url);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/node/auth/revoke.ts
|
|
2
|
+
/**
|
|
3
|
+
* Flip `isTrusted` to false on any live WS clients connected with `token`
|
|
4
|
+
* and broadcast the `auth:revoked` event so they can react.
|
|
5
|
+
*
|
|
6
|
+
* Shared between persisted-auth revocation and remote-dock token revocation.
|
|
7
|
+
*/
|
|
8
|
+
async function revokeActiveConnectionsForToken(context, token) {
|
|
9
|
+
const rpcHost = context.rpc;
|
|
10
|
+
if (!rpcHost?._rpcGroup) return;
|
|
11
|
+
const affectedSessionIds = /* @__PURE__ */ new Set();
|
|
12
|
+
for (const client of rpcHost._rpcGroup.clients) if (client.$meta.clientAuthToken === token) {
|
|
13
|
+
affectedSessionIds.add(client.$meta.id);
|
|
14
|
+
client.$meta.isTrusted = false;
|
|
15
|
+
client.$meta.clientAuthToken = void 0;
|
|
16
|
+
}
|
|
17
|
+
if (affectedSessionIds.size === 0) return;
|
|
18
|
+
await rpcHost.broadcast({
|
|
19
|
+
method: "devframe:auth:revoked",
|
|
20
|
+
args: [],
|
|
21
|
+
filter: (client) => affectedSessionIds.has(client.$meta.id)
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Revoke an auth token: remove from storage and notify all connected clients
|
|
26
|
+
* using this token that they are no longer trusted.
|
|
27
|
+
*/
|
|
28
|
+
async function revokeAuthToken(context, storage, token) {
|
|
29
|
+
storage.mutate((state) => {
|
|
30
|
+
delete state.trusted[token];
|
|
31
|
+
});
|
|
32
|
+
await revokeActiveConnectionsForToken(context, token);
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { revokeAuthToken as n, revokeActiveConnectionsForToken as t };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as isAllowedOrigin, i as
|
|
2
|
-
export { DevframeNodeRpcSessionMeta, WsRpcTransport, WsRpcTransportOptions, attachWsRpcTransport, isAllowedOrigin, isLoopbackHostname };
|
|
1
|
+
import { a as WsRpcTransportOptions, c as isAllowedOrigin, i as WsRpcTransport, l as isLoopbackHostname, n as DevframeNodeRpcSessionMeta, o as attachWsRpcTransport, r as WsOriginRegistry, s as createWsOriginRegistry, t as CreateWsOriginRegistryOptions } from "../../ws-server-uKQcClcJ.mjs";
|
|
2
|
+
export { CreateWsOriginRegistryOptions, DevframeNodeRpcSessionMeta, WsOriginRegistry, WsRpcTransport, WsRpcTransportOptions, attachWsRpcTransport, createWsOriginRegistry, isAllowedOrigin, isLoopbackHostname };
|
|
@@ -1,12 +1,70 @@
|
|
|
1
|
+
import "../../constants.mjs";
|
|
1
2
|
import { n as strictJsonStringify } from "../../serialization-C8Mnw9hK.mjs";
|
|
2
3
|
import { n as structuredCloneStringify, t as structuredCloneParse } from "../../structured-clone-CbAV5rFI.mjs";
|
|
4
|
+
import { n as randomToken, r as timingSafeEqual } from "../../crypto-token-XCqTSMg9.mjs";
|
|
3
5
|
import { createServer } from "node:http";
|
|
4
6
|
import { createServer as createServer$1 } from "node:https";
|
|
5
7
|
import crossws from "crossws/adapters/node";
|
|
6
8
|
//#region src/rpc/transports/ws-server.ts
|
|
9
|
+
/**
|
|
10
|
+
* Create a live, token-protected origin allowlist for external browser
|
|
11
|
+
* viewers. Pass it to {@link WsRpcTransportOptions.allowedOrigins}, then use
|
|
12
|
+
* `registerFromUrl()` in the connection metadata handler to authorize a
|
|
13
|
+
* viewer without sharing a mutable array or disabling DNS-rebinding protection.
|
|
14
|
+
*/
|
|
15
|
+
function createWsOriginRegistry(options = {}) {
|
|
16
|
+
const token = randomToken();
|
|
17
|
+
const origins = new Set(options.allowedOrigins ?? []);
|
|
18
|
+
function normalizeOrigin(origin) {
|
|
19
|
+
if (!origin) return;
|
|
20
|
+
try {
|
|
21
|
+
const url = new URL(origin);
|
|
22
|
+
const normalized = url.origin === "null" ? `${url.protocol}//${url.host}` : url.origin;
|
|
23
|
+
return origin === normalized ? normalized : void 0;
|
|
24
|
+
} catch {}
|
|
25
|
+
}
|
|
26
|
+
function registerOrigin(origin, candidateToken) {
|
|
27
|
+
const normalized = normalizeOrigin(origin);
|
|
28
|
+
if (!normalized || !candidateToken || !timingSafeEqual(token, candidateToken)) return false;
|
|
29
|
+
if (options.validateOrigin && !options.validateOrigin(normalized)) return false;
|
|
30
|
+
origins.add(normalized);
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
token,
|
|
35
|
+
registerFromUrl(url) {
|
|
36
|
+
let parsed;
|
|
37
|
+
try {
|
|
38
|
+
parsed = new URL(url, "http://localhost");
|
|
39
|
+
} catch {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const origin = parsed.searchParams.get("devframe_viewer_origin") ?? void 0;
|
|
43
|
+
return registerOrigin(origin, parsed.searchParams.get("devframe_viewer_origin_token") ?? void 0) ? origin : void 0;
|
|
44
|
+
},
|
|
45
|
+
isAllowed(origin) {
|
|
46
|
+
return isAllowedOrigin(origin, [...origins]);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
7
50
|
let sessionId = 0;
|
|
8
51
|
const EMPTY_DEFS = /* @__PURE__ */ new Map();
|
|
9
52
|
function NOOP() {}
|
|
53
|
+
function listen(server, port, host) {
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
const onError = (error) => reject(error);
|
|
56
|
+
server.once("error", onError);
|
|
57
|
+
try {
|
|
58
|
+
server.listen(port, host, () => {
|
|
59
|
+
server.off("error", onError);
|
|
60
|
+
resolve();
|
|
61
|
+
});
|
|
62
|
+
} catch (error) {
|
|
63
|
+
server.off("error", onError);
|
|
64
|
+
reject(error);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
10
68
|
/** Compare two URL paths ignoring a trailing slash. */
|
|
11
69
|
function pathMatches(a, b) {
|
|
12
70
|
const strip = (p) => p.length > 1 && p.endsWith("/") ? p.slice(0, -1) : p;
|
|
@@ -32,6 +90,9 @@ function isAllowedOrigin(origin, allowedOrigins) {
|
|
|
32
90
|
return false;
|
|
33
91
|
}
|
|
34
92
|
}
|
|
93
|
+
function isWsOriginRegistry(value) {
|
|
94
|
+
return !!value && !Array.isArray(value);
|
|
95
|
+
}
|
|
35
96
|
/**
|
|
36
97
|
* Route `upgrade` events on a server to the crossws adapter, optionally
|
|
37
98
|
* filtered to a single `path`. Non-matching requests are left untouched so
|
|
@@ -55,7 +116,8 @@ function routeUpgrades(server, ws, path, destroyUnmatched, allowedOrigins) {
|
|
|
55
116
|
return;
|
|
56
117
|
}
|
|
57
118
|
}
|
|
58
|
-
|
|
119
|
+
const originAllowed = isWsOriginRegistry(allowedOrigins) ? allowedOrigins.isAllowed(req.headers.origin) : isAllowedOrigin(req.headers.origin, allowedOrigins || []);
|
|
120
|
+
if (allowedOrigins !== false && !originAllowed) {
|
|
59
121
|
socket.write("HTTP/1.1 403 Forbidden\r\nConnection: close\r\n\r\n");
|
|
60
122
|
socket.destroy();
|
|
61
123
|
return;
|
|
@@ -71,9 +133,9 @@ function routeUpgrades(server, ws, path, destroyUnmatched, allowedOrigins) {
|
|
|
71
133
|
* `server` (sharing its port, optionally scoped to a `path`), or let this
|
|
72
134
|
* helper create a standalone server from `port` / `host` / `https`.
|
|
73
135
|
*
|
|
74
|
-
* Returns the crossws node adapter
|
|
75
|
-
* listener from a shared `server`)
|
|
76
|
-
* teardown).
|
|
136
|
+
* Returns the crossws node adapter, standalone-server readiness/address
|
|
137
|
+
* accessors, `detach` (remove the upgrade listener from a shared `server`),
|
|
138
|
+
* and `close` (full deterministic teardown).
|
|
77
139
|
*/
|
|
78
140
|
function attachWsRpcTransport(rpcGroup, options = {}) {
|
|
79
141
|
const { server, port, host = "localhost", path, destroyUnmatched = false, https, allowedOrigins, onConnected = NOOP, onDisconnected = NOOP, definitions = EMPTY_DEFS, serialize: serializeOverride, deserialize: deserializeOverride } = options;
|
|
@@ -136,32 +198,38 @@ function attachWsRpcTransport(rpcGroup, options = {}) {
|
|
|
136
198
|
}
|
|
137
199
|
} });
|
|
138
200
|
let detach = NOOP;
|
|
201
|
+
let ready = Promise.resolve();
|
|
139
202
|
let ownedServer;
|
|
140
203
|
if (server) detach = routeUpgrades(server, ws, path, destroyUnmatched, allowedOrigins);
|
|
141
204
|
else if (https) {
|
|
142
205
|
ownedServer = createServer$1(https);
|
|
143
206
|
detach = routeUpgrades(ownedServer, ws, path, true, allowedOrigins);
|
|
144
|
-
|
|
207
|
+
ready = listen(ownedServer, port ?? 0, host);
|
|
145
208
|
} else {
|
|
146
209
|
ownedServer = createServer((_req, res) => {
|
|
147
210
|
res.writeHead(426, { "content-type": "text/plain" });
|
|
148
211
|
res.end("Upgrade Required");
|
|
149
212
|
});
|
|
150
213
|
detach = routeUpgrades(ownedServer, ws, path, true, allowedOrigins);
|
|
151
|
-
|
|
214
|
+
ready = listen(ownedServer, port ?? 0, host);
|
|
152
215
|
}
|
|
216
|
+
const activeServer = server ?? ownedServer;
|
|
153
217
|
return {
|
|
154
218
|
ws,
|
|
219
|
+
ready,
|
|
220
|
+
address: () => activeServer?.address() ?? null,
|
|
155
221
|
detach,
|
|
156
222
|
async close() {
|
|
157
223
|
detach();
|
|
158
224
|
ws.closeAll(void 0, void 0, true);
|
|
159
225
|
if (ownedServer) {
|
|
160
226
|
const srv = ownedServer;
|
|
227
|
+
await ready.catch(() => {});
|
|
228
|
+
if (!srv.listening) return;
|
|
161
229
|
await new Promise((r) => srv.close(() => r()));
|
|
162
230
|
}
|
|
163
231
|
}
|
|
164
232
|
};
|
|
165
233
|
}
|
|
166
234
|
//#endregion
|
|
167
|
-
export { attachWsRpcTransport, isAllowedOrigin, isLoopbackHostname };
|
|
235
|
+
export { attachWsRpcTransport, createWsOriginRegistry, isAllowedOrigin, isLoopbackHostname };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRpcServer } from "./rpc/server.mjs";
|
|
2
2
|
import { attachWsRpcTransport } from "./rpc/transports/ws-server.mjs";
|
|
3
|
-
import { t as diagnostics } from "./diagnostics-
|
|
4
|
-
import { t as getInternalContext } from "./context-
|
|
3
|
+
import { t as diagnostics } from "./diagnostics-D7wM2cwM.mjs";
|
|
4
|
+
import { t as getInternalContext } from "./context-CBg8iRbQ.mjs";
|
|
5
5
|
import { createServer } from "node:http";
|
|
6
6
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
7
7
|
import { H3, toNodeHandler } from "h3";
|
|
@@ -87,7 +87,8 @@ async function startHttpAndWs(options) {
|
|
|
87
87
|
authHandler?.onConnect(peer, session);
|
|
88
88
|
options.onPeerConnect?.(peer, session);
|
|
89
89
|
} : void 0,
|
|
90
|
-
onDisconnected: (
|
|
90
|
+
onDisconnected: (peer, meta) => {
|
|
91
|
+
options.onPeerDisconnect?.(peer, meta);
|
|
91
92
|
rpcHost._emitSessionDisconnected(meta);
|
|
92
93
|
}
|
|
93
94
|
});
|
|
@@ -103,9 +104,27 @@ async function startHttpAndWs(options) {
|
|
|
103
104
|
return { isTrusted: true };
|
|
104
105
|
}
|
|
105
106
|
});
|
|
106
|
-
if (ownsHttpServer)
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
if (ownsHttpServer) {
|
|
108
|
+
try {
|
|
109
|
+
await new Promise((resolve, reject) => {
|
|
110
|
+
const onError = (error) => reject(error);
|
|
111
|
+
httpServer.once("error", onError);
|
|
112
|
+
httpServer.listen(port, bindHost, () => {
|
|
113
|
+
httpServer.removeListener("error", onError);
|
|
114
|
+
resolve();
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
} catch (error) {
|
|
118
|
+
await closeWs().catch(() => {});
|
|
119
|
+
throw diagnostics.DF0052({
|
|
120
|
+
host: bindHost,
|
|
121
|
+
port,
|
|
122
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
123
|
+
cause: error
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
if (options.onServerError) httpServer.on("error", options.onServerError);
|
|
127
|
+
}
|
|
109
128
|
const address = httpServer.address();
|
|
110
129
|
const resolvedPort = typeof address === "object" && address ? address.port : port;
|
|
111
130
|
const origin = normalizeHttpServerUrl(bindHost, resolvedPort);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { $ as DevframeRpcServerFunctions, Q as DevframeRpcClientFunctions, W as DevframeNodeRpcSession, _ as ConnectionMeta, b as DevframeNodeContext, p as DevframeAuthHandler } from "./devframe-
|
|
2
|
-
import "./
|
|
1
|
+
import { $ as DevframeRpcServerFunctions, Q as DevframeRpcClientFunctions, W as DevframeNodeRpcSession, _ as ConnectionMeta, b as DevframeNodeContext, p as DevframeAuthHandler } from "./devframe-mQ4qZAuo.mjs";
|
|
2
|
+
import { n as DevframeNodeRpcSessionMeta, r as WsOriginRegistry } from "./ws-server-uKQcClcJ.mjs";
|
|
3
|
+
import "./index-b64Uuhy2.mjs";
|
|
3
4
|
import { Peer } from "crossws";
|
|
4
5
|
import { BirpcGroup, EventOptions } from "birpc";
|
|
5
6
|
import { NodeAdapter } from "crossws/adapters/node";
|
|
@@ -73,6 +74,13 @@ interface StartHttpAndWsOptions {
|
|
|
73
74
|
* observe — but not override — the connect-time trust decision.
|
|
74
75
|
*/
|
|
75
76
|
onPeerConnect?: (peer: Peer, session: DevframeNodeRpcSession) => void;
|
|
77
|
+
/**
|
|
78
|
+
* Called once per closed WS connection, right after the transport's own
|
|
79
|
+
* disconnect bookkeeping runs. Unlike {@link onPeerConnect} this receives
|
|
80
|
+
* the raw session meta, not a wrapped session — by the time a peer
|
|
81
|
+
* disconnects there is no live RPC client left to attach.
|
|
82
|
+
*/
|
|
83
|
+
onPeerDisconnect?: (peer: Peer, meta: DevframeNodeRpcSessionMeta) => void;
|
|
76
84
|
/**
|
|
77
85
|
* Forwarded verbatim to the internal `createRpcServer`'s birpc
|
|
78
86
|
* `rpcOptions`, alongside the resolver `startHttpAndWs` installs for
|
|
@@ -91,7 +99,7 @@ interface StartHttpAndWsOptions {
|
|
|
91
99
|
* from another host. Pass `false` to disable origin checking entirely
|
|
92
100
|
* (not recommended). Default: loopback-only.
|
|
93
101
|
*/
|
|
94
|
-
allowedOrigins?: readonly string[] | false;
|
|
102
|
+
allowedOrigins?: readonly string[] | WsOriginRegistry | false;
|
|
95
103
|
/**
|
|
96
104
|
* Called once the WS server is bound so callers can mount static
|
|
97
105
|
* handlers whose origin depends on the resolved port, or print their
|
|
@@ -102,6 +110,16 @@ interface StartHttpAndWsOptions {
|
|
|
102
110
|
port: number;
|
|
103
111
|
app: H3;
|
|
104
112
|
}) => void | Promise<void>;
|
|
113
|
+
/**
|
|
114
|
+
* Called for any error the HTTP server devframe owns emits after it starts
|
|
115
|
+
* listening — e.g. a transient `EMFILE` while accepting a connection.
|
|
116
|
+
* Without it such an error has no listener and crashes the process.
|
|
117
|
+
*
|
|
118
|
+
* Applies only to a server devframe created itself. When `server` is
|
|
119
|
+
* supplied the caller owns that object and attaches to it directly, so
|
|
120
|
+
* devframe leaves its error handling alone.
|
|
121
|
+
*/
|
|
122
|
+
onServerError?: (error: Error) => void;
|
|
105
123
|
}
|
|
106
124
|
interface StartedServer {
|
|
107
125
|
/** Listening origin, e.g. `http://localhost:9999`. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DEVFRAME_OTP_URL_PARAM } from "./constants.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { n as randomToken, r as timingSafeEqual, t as randomDigits } from "./crypto-token-XCqTSMg9.mjs";
|
|
3
3
|
//#region src/node/auth/state.ts
|
|
4
4
|
/** Number of decimal digits in a human-typed one-time authentication code. */
|
|
5
5
|
const TEMP_AUTH_CODE_LENGTH = 6;
|
|
@@ -37,14 +37,21 @@ function refreshTempAuthCode() {
|
|
|
37
37
|
return tempAuthCode;
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
|
-
* Build a "magic link" authentication URL that embeds a one-time code (OTP)
|
|
41
|
-
*
|
|
42
|
-
* it on startup (devframe stays headless, so the host prints its own
|
|
43
|
-
* Defaults to the current code; the link is subject to the same TTL.
|
|
40
|
+
* Build a "magic link" authentication URL that embeds a one-time code (OTP) in
|
|
41
|
+
* the URL **fragment**. Opening it authenticates the client without typing —
|
|
42
|
+
* print it on startup (devframe stays headless, so the host prints its own
|
|
43
|
+
* banner). Defaults to the current code; the link is subject to the same TTL.
|
|
44
|
+
*
|
|
45
|
+
* The code rides the fragment (`#devframe_otp=…`), not the query string, so it
|
|
46
|
+
* is never sent to the server, written to an access log, or leaked in a
|
|
47
|
+
* `Referer` header — the browser client reads it locally (see
|
|
48
|
+
* `consumeOtpFromUrl`). Any existing fragment parameters are preserved.
|
|
44
49
|
*/
|
|
45
50
|
function buildOtpAuthUrl(baseUrl, code = tempAuthCode) {
|
|
46
51
|
const url = new URL(baseUrl);
|
|
47
|
-
url.
|
|
52
|
+
const fragment = new URLSearchParams(url.hash.replace(/^#/, ""));
|
|
53
|
+
fragment.set(DEVFRAME_OTP_URL_PARAM, code);
|
|
54
|
+
url.hash = fragment.toString();
|
|
48
55
|
return url.href;
|
|
49
56
|
}
|
|
50
57
|
/**
|
package/dist/types/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as DevframeRpcServerFunctions, A as DevframeSettingsStore, At as DevframeAgentHostEvents, B as DevframeDefineDiagnosticsOptions, C as DevframeServicesHost, Ct as AgentResourceContent, D as DevframeScopedStreamingHost, Dt as AgentToolProvider, E as DevframeScopedNodeRpc, Et as AgentToolInput, F as ScopedSharedStates, G as RpcBroadcastOptions, H as DevframeDiagnosticsHost, I as SettingsForNamespace, J as RpcSharedStateHost, K as RpcFunctionsHost, L as DevframeViewHost, M as ScopedClientFunctions, Mt as EventUnsubscribe, N as ScopedRpcFn, Nt as EventsMap, O as DevframeSettings, Ot as AgentToolProviderHandle, P as ScopedServerFunctions, Q as DevframeRpcClientFunctions, R as DevframeHost, S as DevframeServiceOf, St as AgentResource, T as DevframeScopedNodeContext, Tt as AgentTool, U as DevframeDiagnosticsLogger, V as DevframeDiagnosticsDefinition, W as DevframeNodeRpcSession, X as RpcStreamingChannelOptions, Y as RpcStreamingChannel, Z as RpcStreamingHost, _ as ConnectionMeta, a as DevframeDockDefaults, b as DevframeNodeContext, bt as AgentHandle, c as DevframeSetupInfo, d as McpRouteOptions, et as DevframeRpcSharedStates, f as defineDevframe, g as Thenable, h as PartialWithoutId, i as DevframeDeploymentKind, j as ScopedBroadcastOptions, jt as EventEmitter, k as DevframeSettingsRegistry, kt as DevframeAgentHost, l as DevframeSpaOptions, m as EntriesToObject, n as DevframeCliOptions, o as DevframeDuplicationStrategy, q as RpcSharedStateGetOptions, r as DevframeDefinition, s as DevframeRuntime, t as DevframeBrowserContext, u as DevframeWsOptions, v as ConnectionMetaWebsocket, w as DevframeServicesRegistry, wt as AgentResourceInput, x as DevframeServiceId, xt as AgentManifest, y as DevframeCapabilities, z as DevframeStorageScope } from "../devframe-
|
|
1
|
+
import { $ as DevframeRpcServerFunctions, A as DevframeSettingsStore, At as DevframeAgentHostEvents, B as DevframeDefineDiagnosticsOptions, C as DevframeServicesHost, Ct as AgentResourceContent, D as DevframeScopedStreamingHost, Dt as AgentToolProvider, E as DevframeScopedNodeRpc, Et as AgentToolInput, F as ScopedSharedStates, G as RpcBroadcastOptions, H as DevframeDiagnosticsHost, I as SettingsForNamespace, J as RpcSharedStateHost, K as RpcFunctionsHost, L as DevframeViewHost, M as ScopedClientFunctions, Mt as EventUnsubscribe, N as ScopedRpcFn, Nt as EventsMap, O as DevframeSettings, Ot as AgentToolProviderHandle, P as ScopedServerFunctions, Q as DevframeRpcClientFunctions, R as DevframeHost, S as DevframeServiceOf, St as AgentResource, T as DevframeScopedNodeContext, Tt as AgentTool, U as DevframeDiagnosticsLogger, V as DevframeDiagnosticsDefinition, W as DevframeNodeRpcSession, X as RpcStreamingChannelOptions, Y as RpcStreamingChannel, Z as RpcStreamingHost, _ as ConnectionMeta, a as DevframeDockDefaults, b as DevframeNodeContext, bt as AgentHandle, c as DevframeSetupInfo, d as McpRouteOptions, et as DevframeRpcSharedStates, f as defineDevframe, g as Thenable, h as PartialWithoutId, i as DevframeDeploymentKind, j as ScopedBroadcastOptions, jt as EventEmitter, k as DevframeSettingsRegistry, kt as DevframeAgentHost, l as DevframeSpaOptions, m as EntriesToObject, n as DevframeCliOptions, o as DevframeDuplicationStrategy, q as RpcSharedStateGetOptions, r as DevframeDefinition, s as DevframeRuntime, t as DevframeBrowserContext, u as DevframeWsOptions, v as ConnectionMetaWebsocket, w as DevframeServicesRegistry, wt as AgentResourceInput, x as DevframeServiceId, xt as AgentManifest, y as DevframeCapabilities, z as DevframeStorageScope } from "../devframe-mQ4qZAuo.mjs";
|
|
2
2
|
import { g as RpcFunctionAgentOptions } from "../types-CnJSgRVa.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { n as DevframeNodeRpcSessionMeta } from "../ws-server-uKQcClcJ.mjs";
|
|
4
4
|
export { AgentHandle, AgentManifest, AgentResource, AgentResourceContent, AgentResourceInput, AgentTool, AgentToolInput, AgentToolProvider, AgentToolProviderHandle, ConnectionMeta, ConnectionMetaWebsocket, DevframeAgentHost, DevframeAgentHostEvents, DevframeBrowserContext, DevframeCapabilities, DevframeCliOptions, DevframeDefineDiagnosticsOptions, DevframeDefinition, DevframeDeploymentKind, DevframeDiagnosticsDefinition, DevframeDiagnosticsHost, DevframeDiagnosticsLogger, DevframeDockDefaults, DevframeDuplicationStrategy, DevframeHost, DevframeNodeContext, DevframeNodeRpcSession, type DevframeNodeRpcSessionMeta, DevframeRpcClientFunctions, DevframeRpcServerFunctions, DevframeRpcSharedStates, DevframeRuntime, DevframeScopedNodeContext, DevframeScopedNodeRpc, DevframeScopedStreamingHost, DevframeServiceId, DevframeServiceOf, DevframeServicesHost, DevframeServicesRegistry, DevframeSettings, DevframeSettingsRegistry, DevframeSettingsStore, DevframeSetupInfo, DevframeSpaOptions, DevframeStorageScope, DevframeViewHost, DevframeWsOptions, EntriesToObject, EventEmitter, EventUnsubscribe, EventsMap, McpRouteOptions, PartialWithoutId, RpcBroadcastOptions, type RpcFunctionAgentOptions, RpcFunctionsHost, RpcSharedStateGetOptions, RpcSharedStateHost, RpcStreamingChannel, RpcStreamingChannelOptions, RpcStreamingHost, ScopedBroadcastOptions, ScopedClientFunctions, ScopedRpcFn, ScopedServerFunctions, ScopedSharedStates, SettingsForNamespace, Thenable, defineDevframe };
|
package/dist/utils/events.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _t as SharedStateOptions, dt as ImmutableArray, ft as ImmutableMap, gt as SharedStateEvents, ht as SharedState, mt as ImmutableSet, pt as ImmutableObject, ut as Immutable, vt as SharedStatePatch, yt as createSharedState } from "../devframe-
|
|
1
|
+
import { _t as SharedStateOptions, dt as ImmutableArray, ft as ImmutableMap, gt as SharedStateEvents, ht as SharedState, mt as ImmutableSet, pt as ImmutableObject, ut as Immutable, vt as SharedStatePatch, yt as createSharedState } from "../devframe-mQ4qZAuo.mjs";
|
|
2
2
|
export { Immutable, ImmutableArray, ImmutableMap, ImmutableObject, ImmutableSet, SharedState, SharedStateEvents, SharedStateOptions, SharedStatePatch, createSharedState };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { at as StreamReader, ct as createStreamReader, it as StreamErrorPayload, lt as createStreamSink, nt as CreateStreamReaderOptions, ot as StreamSink, rt as CreateStreamSinkOptions, st as StreamSinkEvents, tt as BufferedChunk } from "../devframe-
|
|
1
|
+
import { at as StreamReader, ct as createStreamReader, it as StreamErrorPayload, lt as createStreamSink, nt as CreateStreamReaderOptions, ot as StreamSink, rt as CreateStreamSinkOptions, st as StreamSinkEvents, tt as BufferedChunk } from "../devframe-mQ4qZAuo.mjs";
|
|
2
2
|
export { BufferedChunk, CreateStreamReaderOptions, CreateStreamSinkOptions, StreamErrorPayload, StreamReader, StreamSink, StreamSinkEvents, createStreamReader, createStreamSink };
|