devframe 0.6.0-beta.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/build.d.mts +1 -1
- package/dist/adapters/build.mjs +2 -2
- package/dist/adapters/cli.d.mts +1 -1
- package/dist/adapters/cli.mjs +9 -6
- package/dist/adapters/dev.d.mts +9 -2
- package/dist/adapters/dev.mjs +1 -1
- package/dist/adapters/embedded.d.mts +1 -1
- package/dist/adapters/mcp.d.mts +1 -1
- package/dist/adapters/mcp.mjs +1 -337
- package/dist/build-server-0jWgMrz-.mjs +338 -0
- package/dist/client/index.d.mts +2 -2
- package/dist/client/index.mjs +56 -22
- package/dist/constants.d.mts +31 -1
- package/dist/constants.mjs +33 -1
- package/dist/{context-3x_bgBgZ.mjs → context-CKJheEtf.mjs} +2 -2
- package/dist/{context-BEVByy_Z.d.mts → context-UX9qUDK7.d.mts} +1 -1
- package/dist/{dev-BaX8fLH2.mjs → dev-zC5542OV.mjs} +49 -6
- package/dist/{devframe-D-gr9sBx.d.mts → devframe-BtVHhmwM.d.mts} +76 -4
- package/dist/{dump-DoXkj4ku.mjs → dump-D09PZb7T.mjs} +14 -4
- package/dist/{hash-DFc5WwhO.mjs → hash-PAfnyu2k.mjs} +1 -1
- package/dist/helpers/vite.d.mts +1 -1
- package/dist/helpers/vite.mjs +2 -2
- package/dist/{host-h3-C5SZlk03.mjs → host-h3-Dsf-Tgwx.mjs} +37 -11
- package/dist/http-COX960WK.mjs +114 -0
- package/dist/index-ByaMT1Xp.d.mts +107 -0
- package/dist/{index-CxaPKDXX.d.mts → index-Dy6GFDRf.d.mts} +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/{launch-editor-DPfltGA4.mjs → launch-editor-DIzaS5EG.mjs} +58 -43
- package/dist/node/auth.d.mts +2 -64
- package/dist/node/auth.mjs +2 -100
- package/dist/node/hub-internals.d.mts +2 -2
- package/dist/node/hub-internals.mjs +1 -1
- package/dist/node/index.d.mts +3 -3
- package/dist/node/index.mjs +3 -3
- package/dist/recipes/interactive-auth.d.mts +53 -0
- package/dist/recipes/interactive-auth.mjs +132 -0
- package/dist/recipes/open-helpers.mjs +2 -2
- package/dist/{revoke-ENfxWkFK.mjs → revoke-BtQDKTp7.mjs} +1 -1
- package/dist/rpc/dump.mjs +1 -1
- package/dist/rpc/index.d.mts +2 -2
- package/dist/rpc/index.mjs +4 -1
- package/dist/rpc/transports/ws-client.mjs +21 -8
- package/dist/{server-Dl6TU5LE.mjs → server-CAsvfJNK.mjs} +51 -15
- package/dist/{server-rX781kz-.d.mts → server-Cfr1NrGQ.d.mts} +52 -10
- package/dist/{shared-state-D4PPieA0.mjs → shared-state-QtMas0NG.mjs} +34 -4
- package/dist/state-WX3HT5a3.mjs +101 -0
- package/dist/{storage-l2ezeend.mjs → storage-yrUZaiib.mjs} +55 -6
- package/dist/types/index.d.mts +2 -2
- package/dist/utils/crypto-token.mjs +1 -1
- package/dist/utils/events.d.mts +1 -1
- package/dist/utils/hash.mjs +1 -1
- package/dist/utils/launch-editor.mjs +1 -1
- package/dist/utils/open.mjs +1 -1
- package/dist/utils/serve-static.mjs +2 -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/dist/utils/when.d.mts +1 -1
- package/package.json +10 -9
- package/dist/{open-Dusa2Zzd.mjs → open-Deb5xmIT.mjs} +1 -1
package/dist/rpc/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { C as RpcFunctionType, E as Thenable, S as RpcFunctionSetupResult, T as RpcReturnSchema, _ as RpcFunctionDefinition, a as RpcDefinitionsFilter, b as RpcFunctionDefinitionBase, c as RpcDump, d as RpcDumpDefinition, f as RpcDumpGetter, g as RpcFunctionAgentOptions, h as RpcDumpStore, i as RpcArgsSchema, l as RpcDumpClientOptions, m as RpcDumpRecordError, n as BirpcReturn, o as RpcDefinitionsToFunctions, p as RpcDumpRecord, r as EntriesToObject, s as RpcDefinitionsToFunctionsWithNamespace, t as BirpcFn, u as RpcDumpCollectionOptions, v as RpcFunctionDefinitionAny, w as RpcFunctionsCollector, x as RpcFunctionDefinitionToFunction, y as RpcFunctionDefinitionAnyWithContext } from "../types-DZEx4ffs.mjs";
|
|
2
|
-
import { C as RpcCacheManager, S as RpcFunctionsCollectorBase, _ as strictJsonStringify, a as StaticRpcDumpManifestStaticEntry, b as createDefineWrapperWithContext, c as collectStaticRpcDump, d as getDefinitionsWithDumps, f as reviveDumpError, g as STRUCTURED_CLONE_PREFIX, h as validateDefinitions, i as StaticRpcDumpManifestQueryEntry, l as createClientFromDump, m as validateDefinition, n as StaticRpcDumpFile, o as StaticRpcDumpManifestValue, p as serializeDumpError, r as StaticRpcDumpManifest, s as StaticRpcDumpSerialization, t as StaticRpcDumpCollection, u as dumpFunctions, v as getRpcHandler, w as RpcCacheOptions, x as defineRpcFunction, y as getRpcResolvedSetupResult } from "../index-
|
|
3
|
-
export { BirpcFn, BirpcReturn, EntriesToObject, RpcArgsSchema, RpcCacheManager, RpcCacheOptions, RpcDefinitionsFilter, RpcDefinitionsToFunctions, RpcDefinitionsToFunctionsWithNamespace, RpcDump, RpcDumpClientOptions, RpcDumpCollectionOptions, RpcDumpDefinition, RpcDumpGetter, RpcDumpRecord, RpcDumpRecordError, RpcDumpStore, RpcFunctionAgentOptions, RpcFunctionDefinition, RpcFunctionDefinitionAny, RpcFunctionDefinitionAnyWithContext, RpcFunctionDefinitionBase, RpcFunctionDefinitionToFunction, RpcFunctionSetupResult, RpcFunctionType, RpcFunctionsCollector, RpcFunctionsCollectorBase, RpcReturnSchema, STRUCTURED_CLONE_PREFIX, StaticRpcDumpCollection, StaticRpcDumpFile, StaticRpcDumpManifest, StaticRpcDumpManifestQueryEntry, StaticRpcDumpManifestStaticEntry, StaticRpcDumpManifestValue, StaticRpcDumpSerialization, Thenable, collectStaticRpcDump, createClientFromDump, createDefineWrapperWithContext, defineRpcFunction, dumpFunctions, getDefinitionsWithDumps, getRpcHandler, getRpcResolvedSetupResult, reviveDumpError, serializeDumpError, strictJsonStringify, validateDefinition, validateDefinitions };
|
|
2
|
+
import { C as RpcCacheManager, S as RpcFunctionsCollectorBase, _ as strictJsonStringify, a as StaticRpcDumpManifestStaticEntry, b as createDefineWrapperWithContext, c as collectStaticRpcDump, d as getDefinitionsWithDumps, f as reviveDumpError, g as STRUCTURED_CLONE_PREFIX, h as validateDefinitions, i as StaticRpcDumpManifestQueryEntry, l as createClientFromDump, m as validateDefinition, n as StaticRpcDumpFile, o as StaticRpcDumpManifestValue, p as serializeDumpError, r as StaticRpcDumpManifest, s as StaticRpcDumpSerialization, t as StaticRpcDumpCollection, u as dumpFunctions, v as getRpcHandler, w as RpcCacheOptions, x as defineRpcFunction, y as getRpcResolvedSetupResult } from "../index-Dy6GFDRf.mjs";
|
|
3
|
+
export { type BirpcFn, type BirpcReturn, EntriesToObject, RpcArgsSchema, RpcCacheManager, RpcCacheOptions, RpcDefinitionsFilter, RpcDefinitionsToFunctions, RpcDefinitionsToFunctionsWithNamespace, RpcDump, RpcDumpClientOptions, RpcDumpCollectionOptions, RpcDumpDefinition, RpcDumpGetter, RpcDumpRecord, RpcDumpRecordError, RpcDumpStore, RpcFunctionAgentOptions, RpcFunctionDefinition, RpcFunctionDefinitionAny, RpcFunctionDefinitionAnyWithContext, RpcFunctionDefinitionBase, RpcFunctionDefinitionToFunction, RpcFunctionSetupResult, RpcFunctionType, RpcFunctionsCollector, RpcFunctionsCollectorBase, RpcReturnSchema, STRUCTURED_CLONE_PREFIX, StaticRpcDumpCollection, StaticRpcDumpFile, StaticRpcDumpManifest, StaticRpcDumpManifestQueryEntry, StaticRpcDumpManifestStaticEntry, StaticRpcDumpManifestValue, StaticRpcDumpSerialization, Thenable, collectStaticRpcDump, createClientFromDump, createDefineWrapperWithContext, defineRpcFunction, dumpFunctions, getDefinitionsWithDumps, getRpcHandler, getRpcResolvedSetupResult, reviveDumpError, serializeDumpError, strictJsonStringify, validateDefinition, validateDefinitions };
|
package/dist/rpc/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as dumpFunctions$1, c as serializeDumpError$1, d as hash, i as createClientFromDump$1, l as validateDefinition, n as getRpcHandler, o as getDefinitionsWithDumps$1, r as getRpcResolvedSetupResult, s as reviveDumpError$1, t as collectStaticRpcDump$1, u as validateDefinitions } from "../dump-
|
|
1
|
+
import { a as dumpFunctions$1, c as serializeDumpError$1, d as hash, i as createClientFromDump$1, l as validateDefinition, n as getRpcHandler, o as getDefinitionsWithDumps$1, r as getRpcResolvedSetupResult, s as reviveDumpError$1, t as collectStaticRpcDump$1, u as validateDefinitions } from "../dump-D09PZb7T.mjs";
|
|
2
2
|
import { t as diagnostics } from "../diagnostics-BXwBQmoN.mjs";
|
|
3
3
|
import { n as defineRpcFunction, t as createDefineWrapperWithContext } from "../define-BLWPsH6y.mjs";
|
|
4
4
|
import { n as strictJsonStringify, t as STRUCTURED_CLONE_PREFIX } from "../serialization-DpLXCy13.mjs";
|
|
@@ -24,6 +24,9 @@ var RpcCacheManager = class {
|
|
|
24
24
|
const methodCache = this.cacheMap.get(m);
|
|
25
25
|
if (methodCache) return methodCache.get(this.keySerializer(a));
|
|
26
26
|
}
|
|
27
|
+
has(m, a) {
|
|
28
|
+
return this.cacheMap.get(m)?.has(this.keySerializer(a)) ?? false;
|
|
29
|
+
}
|
|
27
30
|
apply(req, res) {
|
|
28
31
|
const methodCache = this.cacheMap.get(req.m) || /* @__PURE__ */ new Map();
|
|
29
32
|
methodCache.set(this.keySerializer(req.a), res);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DEVFRAME_AUTH_TOKEN_QUERY_PARAM } from "../../constants.mjs";
|
|
1
2
|
import { n as strictJsonStringify } from "../../serialization-DpLXCy13.mjs";
|
|
2
3
|
import { n as structuredCloneStringify, t as structuredCloneParse } from "../../structured-clone-XpHLZ8nr.mjs";
|
|
3
4
|
//#region src/rpc/transports/ws-client.ts
|
|
@@ -9,14 +10,15 @@ const EMPTY_DEFS = /* @__PURE__ */ new Map();
|
|
|
9
10
|
*/
|
|
10
11
|
function createWsRpcChannel(options) {
|
|
11
12
|
let url = options.url;
|
|
12
|
-
if (options.authToken) url = `${url}
|
|
13
|
+
if (options.authToken) url = `${url}?${DEVFRAME_AUTH_TOKEN_QUERY_PARAM}=${encodeURIComponent(options.authToken)}`;
|
|
13
14
|
const ws = new WebSocket(url);
|
|
14
15
|
const { onConnected = NOOP, onError = NOOP, onDisconnected = NOOP, definitions = EMPTY_DEFS } = options;
|
|
15
16
|
ws.addEventListener("open", (e) => {
|
|
16
17
|
onConnected(e);
|
|
17
18
|
});
|
|
18
19
|
ws.addEventListener("error", (e) => {
|
|
19
|
-
|
|
20
|
+
const _e = e instanceof Error ? e : new Error(e.type);
|
|
21
|
+
onError(_e);
|
|
20
22
|
});
|
|
21
23
|
ws.addEventListener("close", (e) => {
|
|
22
24
|
onDisconnected(e);
|
|
@@ -29,14 +31,25 @@ function createWsRpcChannel(options) {
|
|
|
29
31
|
});
|
|
30
32
|
},
|
|
31
33
|
post: (data) => {
|
|
32
|
-
if (ws.readyState === WebSocket.OPEN)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
35
|
+
ws.send(data);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (ws.readyState === WebSocket.CONNECTING) {
|
|
39
|
+
const onOpen = () => {
|
|
40
|
+
cleanup();
|
|
41
|
+
if (ws.readyState === WebSocket.OPEN) ws.send(data);
|
|
42
|
+
};
|
|
43
|
+
const onClose = () => cleanup();
|
|
44
|
+
function cleanup() {
|
|
45
|
+
ws.removeEventListener("open", onOpen);
|
|
46
|
+
ws.removeEventListener("close", onClose);
|
|
37
47
|
}
|
|
38
|
-
ws.addEventListener("open",
|
|
48
|
+
ws.addEventListener("open", onOpen);
|
|
49
|
+
ws.addEventListener("close", onClose);
|
|
50
|
+
return;
|
|
39
51
|
}
|
|
52
|
+
onError(/* @__PURE__ */ new Error("Devframe WebSocket is not open; message dropped"));
|
|
40
53
|
},
|
|
41
54
|
serialize: (msg) => {
|
|
42
55
|
let method;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createRpcServer } from "./rpc/server.mjs";
|
|
2
2
|
import { attachWsRpcTransport } from "./rpc/transports/ws-server.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { a as diagnostics } from "./storage-yrUZaiib.mjs";
|
|
4
|
+
import { t as getInternalContext } from "./context-CKJheEtf.mjs";
|
|
4
5
|
import { createServer } from "node:http";
|
|
5
6
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
6
7
|
import { H3, toNodeHandler } from "h3";
|
|
@@ -18,18 +19,32 @@ async function startHttpAndWs(options) {
|
|
|
18
19
|
const httpServer = options.server ?? createServer(toNodeHandler(app));
|
|
19
20
|
const rpcHost = context.rpc;
|
|
20
21
|
const asyncStorage = new AsyncLocalStorage();
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
const authHandler = typeof options.auth === "object" ? options.auth : void 0;
|
|
23
|
+
const effectiveAuthorize = options.authorize ?? authHandler?.authorize;
|
|
24
|
+
if (authHandler) {
|
|
25
|
+
for (const fn of authHandler.rpcFunctions) if (!rpcHost.definitions.has(fn.name)) rpcHost.register(fn);
|
|
26
|
+
}
|
|
27
|
+
const rpcGroup = createRpcServer(rpcHost.functions, { rpcOptions: {
|
|
28
|
+
onFunctionError: options.rpcOptions?.onFunctionError,
|
|
29
|
+
onGeneralError: options.rpcOptions?.onGeneralError,
|
|
30
|
+
resolver(name, fn) {
|
|
31
|
+
const rpc = this;
|
|
32
|
+
if (!fn) return void 0;
|
|
33
|
+
return async function(...args) {
|
|
34
|
+
const meta = rpc.$meta;
|
|
35
|
+
if (effectiveAuthorize && !effectiveAuthorize(name, {
|
|
36
|
+
meta,
|
|
37
|
+
rpc
|
|
38
|
+
})) throw diagnostics.DF0036({ name });
|
|
39
|
+
return await asyncStorage.run({
|
|
40
|
+
rpc,
|
|
41
|
+
meta
|
|
42
|
+
}, async () => {
|
|
43
|
+
return (await fn).apply(this, args);
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
} });
|
|
33
48
|
const separateWsPort = ownsHttpServer && options.wsPort != null && options.wsPort !== port ? options.wsPort : void 0;
|
|
34
49
|
const { ws, close: closeWs } = attachWsRpcTransport(rpcGroup, {
|
|
35
50
|
...separateWsPort != null ? {
|
|
@@ -39,6 +54,14 @@ async function startHttpAndWs(options) {
|
|
|
39
54
|
path: options.path,
|
|
40
55
|
destroyUnmatched: ownsHttpServer,
|
|
41
56
|
allowedOrigins: options.allowedOrigins,
|
|
57
|
+
onConnected: authHandler || options.onPeerConnect ? (peer, meta) => {
|
|
58
|
+
const session = {
|
|
59
|
+
meta,
|
|
60
|
+
rpc: rpcGroup.clients.find((client) => client.$meta === meta)
|
|
61
|
+
};
|
|
62
|
+
authHandler?.onConnect(peer, session);
|
|
63
|
+
options.onPeerConnect?.(peer, session);
|
|
64
|
+
} : void 0,
|
|
42
65
|
onDisconnected: (_peer, meta) => {
|
|
43
66
|
rpcHost._emitSessionDisconnected(meta);
|
|
44
67
|
}
|
|
@@ -46,8 +69,8 @@ async function startHttpAndWs(options) {
|
|
|
46
69
|
rpcHost._rpcGroup = rpcGroup;
|
|
47
70
|
rpcHost._asyncStorage = asyncStorage;
|
|
48
71
|
rpcHost._authDisabled = options.auth === false;
|
|
49
|
-
if (options.auth === false && !rpcHost.definitions.has("devframe:
|
|
50
|
-
name: "devframe:
|
|
72
|
+
if (options.auth === false && !rpcHost.definitions.has("anonymous:devframe:auth")) rpcHost.register({
|
|
73
|
+
name: "anonymous:devframe:auth",
|
|
51
74
|
type: "action",
|
|
52
75
|
handler: () => {
|
|
53
76
|
const session = rpcHost.getCurrentRpcSession();
|
|
@@ -69,12 +92,25 @@ async function startHttpAndWs(options) {
|
|
|
69
92
|
port: resolvedPort,
|
|
70
93
|
app
|
|
71
94
|
});
|
|
95
|
+
function connectionMeta() {
|
|
96
|
+
const jsonSerializableMethods = [];
|
|
97
|
+
for (const def of rpcHost.definitions.values()) if (def.jsonSerializable === true) jsonSerializableMethods.push(def.name);
|
|
98
|
+
return {
|
|
99
|
+
backend: "websocket",
|
|
100
|
+
websocket: separateWsPort != null ? {
|
|
101
|
+
port: separateWsPort,
|
|
102
|
+
path: options.path
|
|
103
|
+
} : { path: options.path },
|
|
104
|
+
jsonSerializableMethods
|
|
105
|
+
};
|
|
106
|
+
}
|
|
72
107
|
return {
|
|
73
108
|
origin,
|
|
74
109
|
port: resolvedPort,
|
|
75
110
|
app,
|
|
76
111
|
ws,
|
|
77
112
|
rpcGroup,
|
|
113
|
+
connectionMeta,
|
|
78
114
|
async close() {
|
|
79
115
|
await closeWs();
|
|
80
116
|
if (ownsHttpServer) await new Promise((r) => httpServer.close(() => r()));
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { at as DevframeRpcServerFunctions, f as ConnectionMeta, g as DevframeNodeRpcSession, h as DevframeNodeContext, it as DevframeRpcClientFunctions } from "./devframe-BtVHhmwM.mjs";
|
|
2
|
+
import { c as DevframeAuthHandler } from "./index-ByaMT1Xp.mjs";
|
|
3
|
+
import { BirpcGroup, EventOptions } from "birpc";
|
|
4
|
+
import { Peer } from "crossws";
|
|
3
5
|
import { NodeAdapter } from "crossws/adapters/node";
|
|
4
6
|
import { Server } from "node:http";
|
|
5
7
|
import { H3 } from "h3";
|
|
@@ -41,16 +43,48 @@ interface StartHttpAndWsOptions {
|
|
|
41
43
|
*/
|
|
42
44
|
server?: Server;
|
|
43
45
|
/**
|
|
44
|
-
*
|
|
45
|
-
* Intended for single-user localhost tools where an auth round-trip
|
|
46
|
-
* would only get in the way. The Vite-flavoured auth layer in
|
|
47
|
-
* `@vitejs/devtools` already honors the equivalent
|
|
48
|
-
* `devtools.clientAuth` setting; devframe records the intent here so
|
|
49
|
-
* future auth plumbing can consult it without another API change.
|
|
46
|
+
* Authentication for the server:
|
|
50
47
|
*
|
|
51
|
-
*
|
|
48
|
+
* - `true` (default) — no gate; every registered method is callable
|
|
49
|
+
* regardless of trust (today's behavior, unchanged).
|
|
50
|
+
* - `false` — the RPC server is started without a trust handshake.
|
|
51
|
+
* Intended for single-user localhost tools where an auth round-trip
|
|
52
|
+
* would only get in the way. A noop `anonymous:devframe:auth` handler
|
|
53
|
+
* is registered so the browser client's unconditional handshake call
|
|
54
|
+
* succeeds and auto-trusts.
|
|
55
|
+
* - A {@link DevframeAuthHandler} (e.g. from
|
|
56
|
+
* `devframe/recipes/interactive-auth`'s `createInteractiveAuth`) —
|
|
57
|
+
* registers its `rpcFunctions`, wires its `authorize` as the resolver
|
|
58
|
+
* gate, and wires its `onConnect` on every new peer. This is the
|
|
59
|
+
* fully-authenticated server: an untrusted caller can only reach
|
|
60
|
+
* `anonymous:`-prefixed methods (see `isAnonymousRpcMethod`).
|
|
52
61
|
*/
|
|
53
|
-
auth?: boolean;
|
|
62
|
+
auth?: boolean | DevframeAuthHandler;
|
|
63
|
+
/**
|
|
64
|
+
* Lower-level escape hatch: gate individual RPC calls by method name and
|
|
65
|
+
* session without a full {@link DevframeAuthHandler}. Ignored when `auth`
|
|
66
|
+
* is a handler object (its own `authorize` is used); combine with `auth:
|
|
67
|
+
* true` to layer a custom policy on top of an otherwise ungated server.
|
|
68
|
+
*/
|
|
69
|
+
authorize?: (methodName: string, session: DevframeNodeRpcSession) => boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Called once per new WS connection, right after its session is created
|
|
72
|
+
* (before any RPC call is dispatched). Runs after the auth handler's own
|
|
73
|
+
* `onConnect` (when `auth` is a {@link DevframeAuthHandler}), so it can
|
|
74
|
+
* observe — but not override — the connect-time trust decision.
|
|
75
|
+
*/
|
|
76
|
+
onPeerConnect?: (peer: Peer, session: DevframeNodeRpcSession) => void;
|
|
77
|
+
/**
|
|
78
|
+
* Forwarded verbatim to the internal `createRpcServer`'s birpc
|
|
79
|
+
* `rpcOptions`, alongside the resolver `startHttpAndWs` installs for
|
|
80
|
+
* auth/session wiring. Use this so a host that owns its own structured
|
|
81
|
+
* diagnostics (e.g. a coded error reporter) keeps seeing RPC failures
|
|
82
|
+
* instead of them being silently absorbed by delegating to
|
|
83
|
+
* `startHttpAndWs`. Returning `true` from either callback suppresses
|
|
84
|
+
* birpc's own error response to the caller — see birpc's
|
|
85
|
+
* `EventOptions` for the full contract.
|
|
86
|
+
*/
|
|
87
|
+
rpcOptions?: Pick<EventOptions<DevframeRpcClientFunctions, DevframeRpcServerFunctions, false>, 'onFunctionError' | 'onGeneralError'>;
|
|
54
88
|
/**
|
|
55
89
|
* Extra origins to accept on the WS upgrade beyond the loopback default
|
|
56
90
|
* (`localhost`/`127.0.0.1`/`::1` and any `Origin`-less request from a
|
|
@@ -78,6 +112,14 @@ interface StartedServer {
|
|
|
78
112
|
/** The crossws node adapter driving the RPC socket (connected peers, pub/sub). */
|
|
79
113
|
ws: NodeAdapter;
|
|
80
114
|
rpcGroup: BirpcGroup<DevframeRpcClientFunctions, DevframeRpcServerFunctions, false>;
|
|
115
|
+
/**
|
|
116
|
+
* The {@link ConnectionMeta} descriptor for this server — the same shape
|
|
117
|
+
* a `__connection.json` route should serve so a devframe client's
|
|
118
|
+
* `resolveWsUrl` can dial back in. Reflects the `path` / `wsPort` this
|
|
119
|
+
* server was started with and the `jsonSerializable` methods currently
|
|
120
|
+
* registered on `context.rpc`.
|
|
121
|
+
*/
|
|
122
|
+
connectionMeta: () => ConnectionMeta;
|
|
81
123
|
close: () => Promise<void>;
|
|
82
124
|
}
|
|
83
125
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createEventEmitter } from "./utils/events.mjs";
|
|
2
2
|
import { nanoid } from "./utils/nanoid.mjs";
|
|
3
|
-
//#region ../../node_modules/.pnpm/immer@11.1.
|
|
3
|
+
//#region ../../node_modules/.pnpm/immer@11.1.11/node_modules/immer/dist/immer.mjs
|
|
4
4
|
var NOTHING = Symbol.for("immer-nothing");
|
|
5
5
|
var DRAFTABLE = Symbol.for("immer-draftable");
|
|
6
6
|
var DRAFT_STATE = Symbol.for("immer-state");
|
|
@@ -350,6 +350,21 @@ function createProxyProxy(base, parent) {
|
|
|
350
350
|
var objectTraps = {
|
|
351
351
|
get(state, prop) {
|
|
352
352
|
if (prop === DRAFT_STATE) return state;
|
|
353
|
+
if (prop === "constructor" || prop === "__proto__") {
|
|
354
|
+
const value2 = latest(state)[prop];
|
|
355
|
+
return new Proxy(value2 || {}, {
|
|
356
|
+
get: (target, key) => {
|
|
357
|
+
if (key === "__proto__" || key === "prototype") return Object.freeze(/* @__PURE__ */ Object.create(null));
|
|
358
|
+
return Reflect.get(target, key);
|
|
359
|
+
},
|
|
360
|
+
set: () => {
|
|
361
|
+
return true;
|
|
362
|
+
},
|
|
363
|
+
apply: (target, thisArg, args) => {
|
|
364
|
+
return Reflect.apply(target, thisArg, args);
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
}
|
|
353
368
|
let arrayPlugin = state.scope_.arrayMethodsPlugin_;
|
|
354
369
|
const isArrayWithStringProp = state.type_ === 1 && typeof prop === "string";
|
|
355
370
|
if (isArrayWithStringProp) {
|
|
@@ -369,12 +384,14 @@ var objectTraps = {
|
|
|
369
384
|
return value;
|
|
370
385
|
},
|
|
371
386
|
has(state, prop) {
|
|
387
|
+
if (prop === "constructor" || prop === "__proto__" || prop === "prototype") return false;
|
|
372
388
|
return prop in latest(state);
|
|
373
389
|
},
|
|
374
390
|
ownKeys(state) {
|
|
375
391
|
return Reflect.ownKeys(latest(state));
|
|
376
392
|
},
|
|
377
393
|
set(state, prop, value) {
|
|
394
|
+
if (prop === "constructor" || prop === "__proto__" || prop === "prototype") return true;
|
|
378
395
|
const desc = getDescriptorFromProto(latest(state), prop);
|
|
379
396
|
if (desc?.set) {
|
|
380
397
|
desc.set.call(state.draft_, value);
|
|
@@ -392,7 +409,7 @@ var objectTraps = {
|
|
|
392
409
|
prepareCopy(state);
|
|
393
410
|
markChanged(state);
|
|
394
411
|
}
|
|
395
|
-
if (state.copy_[prop] === value && (value !== void 0 || prop
|
|
412
|
+
if (state.copy_[prop] === value && (value !== void 0 || has(state.copy_, prop, state.type_)) || Number.isNaN(value) && Number.isNaN(state.copy_[prop])) return true;
|
|
396
413
|
state.copy_[prop] = value;
|
|
397
414
|
state.assigned_.set(prop, true);
|
|
398
415
|
handleCrossReference(state, prop, value);
|
|
@@ -894,6 +911,19 @@ var produceWithPatches = /* @__PURE__ */ immer.produceWithPatches.bind(immer);
|
|
|
894
911
|
var applyPatches = /* @__PURE__ */ immer.applyPatches.bind(immer);
|
|
895
912
|
//#endregion
|
|
896
913
|
//#region src/utils/shared-state.ts
|
|
914
|
+
/**
|
|
915
|
+
* Upper bound on retained syncIds. Loop echoes arrive near-immediately, so a
|
|
916
|
+
* generous window preserves de-dup while capping memory on long-lived,
|
|
917
|
+
* frequently-mutated states (e.g. a 1s terminal poll).
|
|
918
|
+
*/
|
|
919
|
+
const MAX_SYNC_IDS = 1e3;
|
|
920
|
+
function rememberSyncId(syncIds, syncId) {
|
|
921
|
+
syncIds.add(syncId);
|
|
922
|
+
if (syncIds.size > MAX_SYNC_IDS) {
|
|
923
|
+
const oldest = syncIds.values().next().value;
|
|
924
|
+
if (oldest !== void 0) syncIds.delete(oldest);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
897
927
|
function createSharedState(options) {
|
|
898
928
|
const { enablePatches: enablePatches$1 = false } = options;
|
|
899
929
|
const events = createEventEmitter();
|
|
@@ -906,12 +936,12 @@ function createSharedState(options) {
|
|
|
906
936
|
if (syncIds.has(syncId)) return;
|
|
907
937
|
enablePatches();
|
|
908
938
|
state = applyPatches(state, patches);
|
|
909
|
-
syncIds
|
|
939
|
+
rememberSyncId(syncIds, syncId);
|
|
910
940
|
events.emit("updated", state, void 0, syncId);
|
|
911
941
|
},
|
|
912
942
|
mutate: (fn, syncId = nanoid()) => {
|
|
913
943
|
if (syncIds.has(syncId)) return;
|
|
914
|
-
syncIds
|
|
944
|
+
rememberSyncId(syncIds, syncId);
|
|
915
945
|
if (enablePatches$1) {
|
|
916
946
|
const [newState, patches] = produceWithPatches(state, fn);
|
|
917
947
|
state = newState;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { DEVFRAME_OTP_URL_PARAM } from "./constants.mjs";
|
|
2
|
+
import { a as timingSafeEqual, i as randomToken, r as randomDigits } from "./revoke-BtQDKTp7.mjs";
|
|
3
|
+
//#region src/node/auth/state.ts
|
|
4
|
+
/** Number of decimal digits in a human-typed one-time authentication code. */
|
|
5
|
+
const TEMP_AUTH_CODE_LENGTH = 6;
|
|
6
|
+
/**
|
|
7
|
+
* How long an authentication code stays valid after it is (re)generated. A
|
|
8
|
+
* 6-digit code only has ~20 bits of entropy, so a short lifetime plus the
|
|
9
|
+
* attempt cap below are what keep it brute-force resistant.
|
|
10
|
+
*/
|
|
11
|
+
const TEMP_AUTH_CODE_TTL = 5 * 6e4;
|
|
12
|
+
/** Failed attempts allowed against a single code before it is rotated. */
|
|
13
|
+
const TEMP_AUTH_MAX_ATTEMPTS = 5;
|
|
14
|
+
let tempAuthCode = generateTempCode();
|
|
15
|
+
let tempAuthCodeExpiresAt = Date.now() + TEMP_AUTH_CODE_TTL;
|
|
16
|
+
let tempAuthFailedAttempts = 0;
|
|
17
|
+
function generateTempCode() {
|
|
18
|
+
return randomDigits(TEMP_AUTH_CODE_LENGTH);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The current one-time authentication code. Display this to the user (e.g. in
|
|
22
|
+
* the dev-server terminal) so they can type it into the browser to authenticate.
|
|
23
|
+
*/
|
|
24
|
+
function getTempAuthCode() {
|
|
25
|
+
return tempAuthCode;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Rotate the authentication code, resetting its expiry window and failed-attempt
|
|
29
|
+
* counter. Call this when a new authentication flow begins (e.g. when an
|
|
30
|
+
* untrusted client starts authenticating) so the displayed code is freshly
|
|
31
|
+
* valid for its full TTL.
|
|
32
|
+
*/
|
|
33
|
+
function refreshTempAuthCode() {
|
|
34
|
+
tempAuthCode = generateTempCode();
|
|
35
|
+
tempAuthCodeExpiresAt = Date.now() + TEMP_AUTH_CODE_TTL;
|
|
36
|
+
tempAuthFailedAttempts = 0;
|
|
37
|
+
return tempAuthCode;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Build a "magic link" authentication URL that embeds a one-time code (OTP) as
|
|
41
|
+
* a query parameter. Opening it authenticates the client without typing — print
|
|
42
|
+
* it on startup (devframe stays headless, so the host prints its own banner).
|
|
43
|
+
* Defaults to the current code; the link is subject to the same TTL.
|
|
44
|
+
*/
|
|
45
|
+
function buildOtpAuthUrl(baseUrl, code = tempAuthCode) {
|
|
46
|
+
const url = new URL(baseUrl);
|
|
47
|
+
url.searchParams.set(DEVFRAME_OTP_URL_PARAM, code);
|
|
48
|
+
return url.href;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Re-authenticate a connection that presents a previously-issued bearer token.
|
|
52
|
+
* Returns `true` and marks the session trusted when the token is known.
|
|
53
|
+
*
|
|
54
|
+
* Used by the `anonymous:devframe:auth` handler so a client that already
|
|
55
|
+
* authenticated (token persisted in the browser) is trusted on reconnect
|
|
56
|
+
* without entering the code again.
|
|
57
|
+
*/
|
|
58
|
+
function verifyAuthToken(token, session, storage) {
|
|
59
|
+
if (!token || !storage.value().trusted[token]) return false;
|
|
60
|
+
session.meta.clientAuthToken = token;
|
|
61
|
+
session.meta.isTrusted = true;
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Exchange a one-time authentication code for a fresh, node-issued bearer token.
|
|
66
|
+
*
|
|
67
|
+
* On success this mints a high-entropy token, records it in the trusted store,
|
|
68
|
+
* marks the calling session trusted, rotates the code, and returns the token
|
|
69
|
+
* for the client to persist. Returns `null` on any failure.
|
|
70
|
+
*
|
|
71
|
+
* Because the code is short and human-typed, verification is hardened against
|
|
72
|
+
* brute force: it enforces a time-to-live, compares in constant time, and
|
|
73
|
+
* rotates the code after {@link TEMP_AUTH_MAX_ATTEMPTS} failed attempts so an
|
|
74
|
+
* attacker cannot keep guessing against the same code.
|
|
75
|
+
*/
|
|
76
|
+
function exchangeTempAuthCode(code, session, info, storage) {
|
|
77
|
+
if (Date.now() > tempAuthCodeExpiresAt) {
|
|
78
|
+
refreshTempAuthCode();
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
if (!timingSafeEqual(code, tempAuthCode)) {
|
|
82
|
+
tempAuthFailedAttempts += 1;
|
|
83
|
+
if (tempAuthFailedAttempts >= TEMP_AUTH_MAX_ATTEMPTS) refreshTempAuthCode();
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
const authToken = randomToken();
|
|
87
|
+
storage.mutate((state) => {
|
|
88
|
+
state.trusted[authToken] = {
|
|
89
|
+
authToken,
|
|
90
|
+
ua: info.ua,
|
|
91
|
+
origin: info.origin,
|
|
92
|
+
timestamp: Date.now()
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
session.meta.clientAuthToken = authToken;
|
|
96
|
+
session.meta.isTrusted = true;
|
|
97
|
+
refreshTempAuthCode();
|
|
98
|
+
return authToken;
|
|
99
|
+
}
|
|
100
|
+
//#endregion
|
|
101
|
+
export { verifyAuthToken as a, refreshTempAuthCode as i, exchangeTempAuthCode as n, getTempAuthCode as r, buildOtpAuthUrl as t };
|
|
@@ -2,6 +2,7 @@ import { t as devframeReporter } from "./diagnostics-reporter-CsIG85Q5.mjs";
|
|
|
2
2
|
import { defineDiagnostics } from "nostics";
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import { dirname } from "pathe";
|
|
5
|
+
import process$1 from "node:process";
|
|
5
6
|
import { destr } from "destr";
|
|
6
7
|
//#region src/node/diagnostics.ts
|
|
7
8
|
const diagnostics = defineDiagnostics({
|
|
@@ -46,6 +47,14 @@ const diagnostics = defineDiagnostics({
|
|
|
46
47
|
DF0034: {
|
|
47
48
|
why: (p) => `Scoped RPC registration for namespace "${p.namespace}" received an already-namespaced function name "${p.name}".`,
|
|
48
49
|
fix: "A scoped context auto-namespaces ids. Pass a bare name without a \":\" separator (e.g. `register({ name: \"get-cwd\" })`), or use the unscoped `ctx.base.rpc.register` for a fully-qualified name."
|
|
50
|
+
},
|
|
51
|
+
DF0035: {
|
|
52
|
+
why: (p) => `Failed to persist storage file: ${p.filepath}`,
|
|
53
|
+
fix: "Check that the storage directory is writable and has free space."
|
|
54
|
+
},
|
|
55
|
+
DF0036: {
|
|
56
|
+
why: (p) => `RPC call to "${p.name}" was rejected: the caller is not authorized.`,
|
|
57
|
+
fix: "Complete the auth handshake (or connect with a static/pre-shared token) before calling a trusted method. Untrusted callers may only call `anonymous:`-prefixed methods — see `isAnonymousRpcMethod`."
|
|
49
58
|
}
|
|
50
59
|
}
|
|
51
60
|
});
|
|
@@ -89,7 +98,7 @@ function createEventEmitter() {
|
|
|
89
98
|
};
|
|
90
99
|
}
|
|
91
100
|
//#endregion
|
|
92
|
-
//#region ../../node_modules/.pnpm/immer@11.1.
|
|
101
|
+
//#region ../../node_modules/.pnpm/immer@11.1.11/node_modules/immer/dist/immer.mjs
|
|
93
102
|
var NOTHING = Symbol.for("immer-nothing");
|
|
94
103
|
var DRAFTABLE = Symbol.for("immer-draftable");
|
|
95
104
|
var DRAFT_STATE = Symbol.for("immer-state");
|
|
@@ -439,6 +448,21 @@ function createProxyProxy(base, parent) {
|
|
|
439
448
|
var objectTraps = {
|
|
440
449
|
get(state, prop) {
|
|
441
450
|
if (prop === DRAFT_STATE) return state;
|
|
451
|
+
if (prop === "constructor" || prop === "__proto__") {
|
|
452
|
+
const value2 = latest(state)[prop];
|
|
453
|
+
return new Proxy(value2 || {}, {
|
|
454
|
+
get: (target, key) => {
|
|
455
|
+
if (key === "__proto__" || key === "prototype") return Object.freeze(/* @__PURE__ */ Object.create(null));
|
|
456
|
+
return Reflect.get(target, key);
|
|
457
|
+
},
|
|
458
|
+
set: () => {
|
|
459
|
+
return true;
|
|
460
|
+
},
|
|
461
|
+
apply: (target, thisArg, args) => {
|
|
462
|
+
return Reflect.apply(target, thisArg, args);
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
}
|
|
442
466
|
let arrayPlugin = state.scope_.arrayMethodsPlugin_;
|
|
443
467
|
const isArrayWithStringProp = state.type_ === 1 && typeof prop === "string";
|
|
444
468
|
if (isArrayWithStringProp) {
|
|
@@ -458,12 +482,14 @@ var objectTraps = {
|
|
|
458
482
|
return value;
|
|
459
483
|
},
|
|
460
484
|
has(state, prop) {
|
|
485
|
+
if (prop === "constructor" || prop === "__proto__" || prop === "prototype") return false;
|
|
461
486
|
return prop in latest(state);
|
|
462
487
|
},
|
|
463
488
|
ownKeys(state) {
|
|
464
489
|
return Reflect.ownKeys(latest(state));
|
|
465
490
|
},
|
|
466
491
|
set(state, prop, value) {
|
|
492
|
+
if (prop === "constructor" || prop === "__proto__" || prop === "prototype") return true;
|
|
467
493
|
const desc = getDescriptorFromProto(latest(state), prop);
|
|
468
494
|
if (desc?.set) {
|
|
469
495
|
desc.set.call(state.draft_, value);
|
|
@@ -481,7 +507,7 @@ var objectTraps = {
|
|
|
481
507
|
prepareCopy(state);
|
|
482
508
|
markChanged(state);
|
|
483
509
|
}
|
|
484
|
-
if (state.copy_[prop] === value && (value !== void 0 || prop
|
|
510
|
+
if (state.copy_[prop] === value && (value !== void 0 || has(state.copy_, prop, state.type_)) || Number.isNaN(value) && Number.isNaN(state.copy_[prop])) return true;
|
|
485
511
|
state.copy_[prop] = value;
|
|
486
512
|
state.assigned_.set(prop, true);
|
|
487
513
|
handleCrossReference(state, prop, value);
|
|
@@ -992,6 +1018,19 @@ function nanoid(size = 21) {
|
|
|
992
1018
|
}
|
|
993
1019
|
//#endregion
|
|
994
1020
|
//#region src/utils/shared-state.ts
|
|
1021
|
+
/**
|
|
1022
|
+
* Upper bound on retained syncIds. Loop echoes arrive near-immediately, so a
|
|
1023
|
+
* generous window preserves de-dup while capping memory on long-lived,
|
|
1024
|
+
* frequently-mutated states (e.g. a 1s terminal poll).
|
|
1025
|
+
*/
|
|
1026
|
+
const MAX_SYNC_IDS = 1e3;
|
|
1027
|
+
function rememberSyncId(syncIds, syncId) {
|
|
1028
|
+
syncIds.add(syncId);
|
|
1029
|
+
if (syncIds.size > MAX_SYNC_IDS) {
|
|
1030
|
+
const oldest = syncIds.values().next().value;
|
|
1031
|
+
if (oldest !== void 0) syncIds.delete(oldest);
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
995
1034
|
function createSharedState(options) {
|
|
996
1035
|
const { enablePatches: enablePatches$1 = false } = options;
|
|
997
1036
|
const events = createEventEmitter();
|
|
@@ -1004,12 +1043,12 @@ function createSharedState(options) {
|
|
|
1004
1043
|
if (syncIds.has(syncId)) return;
|
|
1005
1044
|
enablePatches();
|
|
1006
1045
|
state = applyPatches(state, patches);
|
|
1007
|
-
syncIds
|
|
1046
|
+
rememberSyncId(syncIds, syncId);
|
|
1008
1047
|
events.emit("updated", state, void 0, syncId);
|
|
1009
1048
|
},
|
|
1010
1049
|
mutate: (fn, syncId = nanoid()) => {
|
|
1011
1050
|
if (syncIds.has(syncId)) return;
|
|
1012
|
-
syncIds
|
|
1051
|
+
rememberSyncId(syncIds, syncId);
|
|
1013
1052
|
if (enablePatches$1) {
|
|
1014
1053
|
const [newState, patches] = produceWithPatches(state, fn);
|
|
1015
1054
|
state = newState;
|
|
@@ -1132,8 +1171,18 @@ function createStorage(options) {
|
|
|
1132
1171
|
enablePatches: false
|
|
1133
1172
|
});
|
|
1134
1173
|
state.on("updated", debounce((newState) => {
|
|
1135
|
-
|
|
1136
|
-
|
|
1174
|
+
try {
|
|
1175
|
+
const dir = dirname(options.filepath);
|
|
1176
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
1177
|
+
const tmp = `${options.filepath}.${process$1.pid}.tmp`;
|
|
1178
|
+
fs.writeFileSync(tmp, `${JSON.stringify(newState, null, 2)}\n`);
|
|
1179
|
+
fs.renameSync(tmp, options.filepath);
|
|
1180
|
+
} catch (error) {
|
|
1181
|
+
diagnostics.DF0035({
|
|
1182
|
+
filepath: options.filepath,
|
|
1183
|
+
cause: error
|
|
1184
|
+
}, { method: "error" });
|
|
1185
|
+
}
|
|
1137
1186
|
}, debounceTime));
|
|
1138
1187
|
return state;
|
|
1139
1188
|
}
|
package/dist/types/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as ScopedClientFunctions, C as RpcStreamingHost, Ct as EventsMap, G as Thenable, J as DevframeScopedStreamingHost, K as DevframeScopedNodeContext, Q as ScopedBroadcastOptions, S as RpcStreamingChannelOptions, St as EventUnsubscribe, U as EntriesToObject, W as PartialWithoutId, X as DevframeSettingsRegistry, Y as DevframeSettings, Z as DevframeSettingsStore, _ as RpcBroadcastOptions, _t as AgentTool, a as DevframeDuplicationStrategy, at as DevframeRpcServerFunctions, b as RpcSharedStateHost, bt as DevframeAgentHostEvents, c as DevframeSpaOptions, ct as DevframeDefineDiagnosticsOptions, d as defineDevframe, dt as DevframeDiagnosticsLogger, et as ScopedServerFunctions, f as ConnectionMeta, ft as AgentHandle, g as DevframeNodeRpcSession, gt as AgentResourceInput, h as DevframeNodeContext, ht as AgentResourceContent, i as DevframeDeploymentKind, it as DevframeRpcClientFunctions, l as DevframeWsOptions, lt as DevframeDiagnosticsDefinition, m as DevframeCapabilities, mt as AgentResource, n as DevframeCliOptions, nt as SettingsForNamespace, o as DevframeRuntime, ot as DevframeRpcSharedStates, p as ConnectionMetaWebsocket, pt as AgentManifest, q as DevframeScopedNodeRpc, r as DevframeDefinition, rt as DevframeViewHost, s as DevframeSetupInfo, st as DevframeHost, t as DevframeBrowserContext, tt as ScopedSharedStates, u as McpRouteOptions, ut as DevframeDiagnosticsHost, v as RpcFunctionsHost, vt as AgentToolInput, x as RpcStreamingChannel, xt as EventEmitter, y as RpcSharedStateGetOptions, yt as DevframeAgentHost } from "../devframe-BtVHhmwM.mjs";
|
|
2
2
|
import { g as RpcFunctionAgentOptions } from "../types-DZEx4ffs.mjs";
|
|
3
3
|
import { t as DevframeNodeRpcSessionMeta } from "../ws-server-Bc2wBHl-.mjs";
|
|
4
|
-
export { AgentHandle, AgentManifest, AgentResource, AgentResourceContent, AgentResourceInput, AgentTool, AgentToolInput, ConnectionMeta, ConnectionMetaWebsocket, DevframeAgentHost, DevframeAgentHostEvents, DevframeBrowserContext, DevframeCapabilities, DevframeCliOptions, DevframeDefineDiagnosticsOptions, DevframeDefinition, DevframeDeploymentKind, DevframeDiagnosticsDefinition, DevframeDiagnosticsHost, DevframeDiagnosticsLogger, DevframeDuplicationStrategy, DevframeHost, DevframeNodeContext, DevframeNodeRpcSession, DevframeNodeRpcSessionMeta, DevframeRpcClientFunctions, DevframeRpcServerFunctions, DevframeRpcSharedStates, DevframeRuntime, DevframeScopedNodeContext, DevframeScopedNodeRpc, DevframeScopedStreamingHost, DevframeSettings, DevframeSettingsRegistry, DevframeSettingsStore, DevframeSetupInfo, DevframeSpaOptions, DevframeViewHost, DevframeWsOptions, EntriesToObject, EventEmitter, EventUnsubscribe, EventsMap, PartialWithoutId, RpcBroadcastOptions, RpcFunctionAgentOptions, RpcFunctionsHost, RpcSharedStateGetOptions, RpcSharedStateHost, RpcStreamingChannel, RpcStreamingChannelOptions, RpcStreamingHost, ScopedBroadcastOptions, ScopedClientFunctions, ScopedServerFunctions, ScopedSharedStates, SettingsForNamespace, Thenable, defineDevframe };
|
|
4
|
+
export { AgentHandle, AgentManifest, AgentResource, AgentResourceContent, AgentResourceInput, AgentTool, AgentToolInput, ConnectionMeta, ConnectionMetaWebsocket, DevframeAgentHost, DevframeAgentHostEvents, DevframeBrowserContext, DevframeCapabilities, DevframeCliOptions, DevframeDefineDiagnosticsOptions, DevframeDefinition, DevframeDeploymentKind, DevframeDiagnosticsDefinition, DevframeDiagnosticsHost, DevframeDiagnosticsLogger, DevframeDuplicationStrategy, DevframeHost, DevframeNodeContext, DevframeNodeRpcSession, type DevframeNodeRpcSessionMeta, DevframeRpcClientFunctions, DevframeRpcServerFunctions, DevframeRpcSharedStates, DevframeRuntime, DevframeScopedNodeContext, DevframeScopedNodeRpc, DevframeScopedStreamingHost, DevframeSettings, DevframeSettingsRegistry, DevframeSettingsStore, DevframeSetupInfo, DevframeSpaOptions, DevframeViewHost, DevframeWsOptions, EntriesToObject, EventEmitter, EventUnsubscribe, EventsMap, McpRouteOptions, PartialWithoutId, RpcBroadcastOptions, type RpcFunctionAgentOptions, RpcFunctionsHost, RpcSharedStateGetOptions, RpcSharedStateHost, RpcStreamingChannel, RpcStreamingChannelOptions, RpcStreamingHost, ScopedBroadcastOptions, ScopedClientFunctions, ScopedServerFunctions, ScopedSharedStates, SettingsForNamespace, Thenable, defineDevframe };
|
|
@@ -19,7 +19,7 @@ function randomToken(byteLength = 16) {
|
|
|
19
19
|
*/
|
|
20
20
|
function randomDigits(length) {
|
|
21
21
|
const limit = 250;
|
|
22
|
-
const buf = new Uint8Array(1);
|
|
22
|
+
const buf = /* @__PURE__ */ new Uint8Array(1);
|
|
23
23
|
let out = "";
|
|
24
24
|
while (out.length < length) {
|
|
25
25
|
globalThis.crypto.getRandomValues(buf);
|
package/dist/utils/events.d.mts
CHANGED
package/dist/utils/hash.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as hash } from "../hash-
|
|
1
|
+
import { t as hash } from "../hash-PAfnyu2k.mjs";
|
|
2
2
|
export { hash };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as launchEditor } from "../launch-editor-
|
|
1
|
+
import { t as launchEditor } from "../launch-editor-DIzaS5EG.mjs";
|
|
2
2
|
export { launchEditor };
|
package/dist/utils/open.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as open } from "../open-
|
|
1
|
+
import { t as open } from "../open-Deb5xmIT.mjs";
|
|
2
2
|
export { open };
|
|
@@ -143,7 +143,8 @@ function serveStaticNodeMiddleware(dir, options) {
|
|
|
143
143
|
res.end();
|
|
144
144
|
return;
|
|
145
145
|
}
|
|
146
|
-
const
|
|
146
|
+
const url = req.url ?? "/";
|
|
147
|
+
const file = await resolveTarget(absDir, url, opts.indexNames, opts.single);
|
|
147
148
|
if (!file) {
|
|
148
149
|
if (next) {
|
|
149
150
|
next();
|