devframe 0.8.2 → 0.9.0-beta.1
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-CttmCMBi.mjs +70 -0
- package/dist/_shared-DmpWW-HH.d.mts +43 -0
- package/dist/adapters/build.d.mts +1 -1
- package/dist/adapters/build.mjs +6 -5
- package/dist/adapters/cac.d.mts +1 -1
- package/dist/adapters/cac.mjs +157 -1
- package/dist/adapters/dev.d.mts +20 -42
- package/dist/adapters/dev.mjs +2 -1
- package/dist/adapters/embedded.d.mts +1 -1
- package/dist/adapters/initiate.d.mts +223 -0
- package/dist/adapters/initiate.mjs +2 -0
- package/dist/adapters/mcp.d.mts +26 -2
- package/dist/adapters/mcp.mjs +2 -2
- package/dist/cli/main.mjs +2 -2
- package/dist/client/index.d.mts +70 -6
- package/dist/client/index.mjs +743 -408
- package/dist/constants.d.mts +19 -6
- package/dist/constants.mjs +19 -6
- package/dist/{context-CBg8iRbQ.mjs → context-C33rR7n0.mjs} +1 -1
- package/dist/{context-DoSozfvx.d.mts → context-CSCwoABx.d.mts} +1 -1
- package/dist/{host-h3-D2hYZvDK.mjs → context-Du11TLcO.mjs} +5 -255
- package/dist/dev-BEveeA5H.mjs +233 -0
- package/dist/{devframe-mQ4qZAuo.d.mts → devframe-Bdd9YXTy.d.mts} +88 -25
- package/dist/{diagnostics-D7wM2cwM.mjs → diagnostics-DLYH5oD3.mjs} +16 -0
- package/dist/dist-D8jAMwxU.mjs +227 -0
- package/dist/helpers/vite.d.mts +43 -39
- package/dist/helpers/vite.mjs +26 -38
- package/dist/host-agent-CpbAoqBx.mjs +230 -0
- package/dist/host-h3-CzCZwtuV.mjs +26 -0
- package/dist/{fetch-BKaD0Vb3.mjs → http-DLr_cJZ7.mjs} +42 -4
- package/dist/{index-b64Uuhy2.d.mts → index-CZRd2K1C.d.mts} +2 -2
- package/dist/{index-Dbw1p5ch.d.mts → index-DSCq4M4q.d.mts} +2 -31
- package/dist/index.d.mts +9 -4
- package/dist/index.mjs +8 -1
- package/dist/{instance-registry-BnnA2Eoh.mjs → instance-registry-BQqGoDO9.mjs} +9 -2
- package/dist/instance-shell-DBTXTSjN.d.mts +264 -0
- package/dist/instance-shell-KRdee1QF.mjs +485 -0
- package/dist/internal/index.d.mts +150 -0
- package/dist/internal/index.mjs +7 -0
- package/dist/node/auth.d.mts +2 -2
- package/dist/node/hub-internals.d.mts +2 -14
- package/dist/node/hub-internals.mjs +2 -2
- package/dist/node/index.d.mts +3 -267
- package/dist/node/index.mjs +3 -5
- package/dist/recipes/common-rpc-functions.d.mts +3 -3
- package/dist/recipes/interactive-auth.d.mts +3 -3
- package/dist/recipes/interactive-auth.mjs +6 -6
- package/dist/rolldown-runtime-JspESFgx.mjs +35 -0
- package/dist/rpc/dump.d.mts +77 -1
- package/dist/rpc/dump.mjs +1 -1
- package/dist/rpc/index.d.mts +2 -2
- package/dist/rpc/index.mjs +3 -17
- package/dist/rpc/transports/sse-client.d.mts +2 -0
- package/dist/rpc/transports/sse-client.mjs +142 -0
- package/dist/rpc/transports/sse-server.d.mts +61 -0
- package/dist/rpc/transports/sse-server.mjs +209 -0
- package/dist/rpc/transports/ws-bun.d.mts +35 -0
- package/dist/rpc/transports/ws-bun.mjs +31 -0
- package/dist/rpc/transports/ws-client.d.mts +1 -1
- package/dist/rpc/transports/ws-client.mjs +10 -18
- package/dist/rpc/transports/ws-server.d.mts +2 -2
- package/dist/rpc/transports/ws-server.mjs +2 -235
- package/dist/rpc-core-CGctXToO.d.mts +48 -0
- package/dist/rpc-core-CqcJkAu9.mjs +81 -0
- package/dist/{serialization-C8Mnw9hK.mjs → serialization-BHY8M5NQ.mjs} +1 -1
- package/dist/{shared-state-6kHolYZy.mjs → shared-state-fRRbRUtD.mjs} +1 -1
- package/dist/sse-client-BsIK3hMD.d.mts +37 -0
- package/dist/{dump-CgZShDRB.mjs → static-CvjkO8QE.mjs} +2 -265
- package/dist/{storage-CTNVbuFB.mjs → storage-BcmVEJRc.mjs} +2 -2
- package/dist/types/index.d.mts +3 -3
- package/dist/types/index.mjs +1 -6
- package/dist/utils/events.d.mts +1 -1
- package/dist/utils/launch-editor.mjs +1 -25
- package/dist/utils/open.mjs +1 -1
- package/dist/utils/serve-static.mjs +1 -1
- package/dist/utils/shared-state.d.mts +1 -1
- package/dist/utils/shared-state.mjs +1 -1
- package/dist/utils/simple-schema.d.mts +101 -1
- package/dist/utils/streaming-channel.d.mts +1 -1
- package/dist/validation-BiuDXTKW.mjs +266 -0
- package/dist/wire-codec-9VhIKnyp.mjs +58 -0
- package/dist/{ws-client-B6Tnr0ic.d.mts → ws-client-CdNuATYa.d.mts} +6 -1
- package/dist/ws-server-Bk1hOG3X.mjs +267 -0
- package/dist/{ws-server-uKQcClcJ.d.mts → ws-server-Ces08fjP.d.mts} +89 -8
- package/package.json +10 -9
- package/skills/devframe/SKILL.md +84 -85
- package/dist/_shared-bWRzeSa0.mjs +0 -19
- package/dist/adapters/cli.d.mts +0 -11
- package/dist/adapters/cli.mjs +0 -6
- package/dist/cac-D4_9ok0z.mjs +0 -157
- package/dist/dev-Bc49u3qg.mjs +0 -439
- package/dist/http-C4T68YV6.mjs +0 -38
- package/dist/index-vAX6bYuc.d.mts +0 -78
- package/dist/recipes/open-helpers.d.mts +0 -6
- package/dist/recipes/open-helpers.mjs +0 -6
- package/dist/server-CD8XmBXl.mjs +0 -167
- package/dist/server-UHWae43Q.d.mts +0 -149
- package/dist/simple-schema-BDzLeJDk.d.mts +0 -102
- package/dist/utils/promise.d.mts +0 -8
- package/dist/utils/promise.mjs +0 -15
- package/dist/utils/scope.d.mts +0 -11
- package/dist/utils/scope.mjs +0 -15
- package/dist/{open-Deb5xmIT.mjs → open-Dz4V4irZ.mjs} +1 -1
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
import "./constants.mjs";
|
|
2
|
+
import { t as diagnostics } from "./diagnostics-DLYH5oD3.mjs";
|
|
3
|
+
import { t as getInternalContext } from "./context-C33rR7n0.mjs";
|
|
4
|
+
import { createInteractiveAuth } from "./recipes/interactive-auth.mjs";
|
|
5
|
+
import { createServer } from "node:http";
|
|
6
|
+
import process from "node:process";
|
|
7
|
+
import { isIP } from "node:net";
|
|
8
|
+
import { joinURL, withLeadingSlash, withoutLeadingSlash, withoutTrailingSlash } from "ufo";
|
|
9
|
+
import { H3, defineHandler, toNodeHandler } from "h3";
|
|
10
|
+
//#region src/node/utils.ts
|
|
11
|
+
const NON_DIALABLE_HOSTS = /* @__PURE__ */ new Set([
|
|
12
|
+
"0.0.0.0",
|
|
13
|
+
"127.0.0.1",
|
|
14
|
+
"::",
|
|
15
|
+
"0000:0000:0000:0000:0000:0000:0000:0000",
|
|
16
|
+
""
|
|
17
|
+
]);
|
|
18
|
+
/** Map a bind host to a host a client can actually connect to. */
|
|
19
|
+
function toDialableHost(host) {
|
|
20
|
+
return NON_DIALABLE_HOSTS.has(host) ? "localhost" : host;
|
|
21
|
+
}
|
|
22
|
+
/** Format a bind host for use in a URL authority (dialable, IPv6-bracketed). */
|
|
23
|
+
function formatHostForUrl(host) {
|
|
24
|
+
const dialable = toDialableHost(host);
|
|
25
|
+
return isIP(dialable) === 6 ? `[${dialable}]` : dialable;
|
|
26
|
+
}
|
|
27
|
+
function normalizeHttpServerUrl(host, port) {
|
|
28
|
+
return `http://${formatHostForUrl(host)}:${port}`;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/node/instance-shell.ts
|
|
32
|
+
/**
|
|
33
|
+
* Compose an h3 + WebSocket RPC server for a devframe context — the low-level
|
|
34
|
+
* "listen on a port (or share one) + attach the WS transport" binding the
|
|
35
|
+
* side-car and shared-server tiers below are built on. Owns and listens on a
|
|
36
|
+
* fresh `node:http` server unless `server` is supplied, in which case it only
|
|
37
|
+
* attaches the upgrade listener and leaves that server's lifecycle to its
|
|
38
|
+
* owner.
|
|
39
|
+
*/
|
|
40
|
+
async function bindHttpAndWs(options) {
|
|
41
|
+
const { context, port, core } = options;
|
|
42
|
+
const bindHost = options.host;
|
|
43
|
+
const app = new H3();
|
|
44
|
+
const ownsHttpServer = !options.server;
|
|
45
|
+
const httpServer = options.server ?? createServer(toNodeHandler(app));
|
|
46
|
+
const rpcHost = context.rpc;
|
|
47
|
+
const websocket = options.websocket !== false;
|
|
48
|
+
let ws;
|
|
49
|
+
let closeWs = async () => {};
|
|
50
|
+
if (websocket) {
|
|
51
|
+
const { attachWsRpcTransport } = await import("./rpc/transports/ws-server.mjs");
|
|
52
|
+
const transport = attachWsRpcTransport(core.rpcGroup, {
|
|
53
|
+
server: httpServer,
|
|
54
|
+
path: options.path,
|
|
55
|
+
destroyUnmatched: options.destroyUnmatched ?? ownsHttpServer,
|
|
56
|
+
allowedOrigins: options.allowedOrigins,
|
|
57
|
+
onConnected: core.onConnected,
|
|
58
|
+
onDisconnected: core.onDisconnected
|
|
59
|
+
});
|
|
60
|
+
ws = transport.ws;
|
|
61
|
+
closeWs = transport.close;
|
|
62
|
+
}
|
|
63
|
+
if (ownsHttpServer) try {
|
|
64
|
+
await new Promise((resolve, reject) => {
|
|
65
|
+
const onError = (error) => reject(error);
|
|
66
|
+
httpServer.once("error", onError);
|
|
67
|
+
httpServer.listen(port, bindHost, () => {
|
|
68
|
+
httpServer.removeListener("error", onError);
|
|
69
|
+
resolve();
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
} catch (error) {
|
|
73
|
+
await closeWs().catch(() => {});
|
|
74
|
+
throw diagnostics.DF0052({
|
|
75
|
+
host: bindHost,
|
|
76
|
+
port,
|
|
77
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
78
|
+
cause: error
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
const address = httpServer.address();
|
|
82
|
+
const resolvedPort = typeof address === "object" && address ? address.port : port;
|
|
83
|
+
const origin = normalizeHttpServerUrl(bindHost, resolvedPort);
|
|
84
|
+
const internal = getInternalContext(context);
|
|
85
|
+
const wsUrl = `ws://${formatHostForUrl(bindHost)}:${resolvedPort}${options.path ?? ""}`;
|
|
86
|
+
if (websocket) internal.wsEndpoint = { url: wsUrl };
|
|
87
|
+
function connectionMeta() {
|
|
88
|
+
const jsonSerializableMethods = [];
|
|
89
|
+
for (const def of rpcHost.definitions.values()) if (def.jsonSerializable === true) jsonSerializableMethods.push(def.name);
|
|
90
|
+
return {
|
|
91
|
+
backend: "websocket",
|
|
92
|
+
websocket: { path: options.path },
|
|
93
|
+
jsonSerializableMethods
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
origin,
|
|
98
|
+
port: resolvedPort,
|
|
99
|
+
app,
|
|
100
|
+
ws,
|
|
101
|
+
rpcGroup: core.rpcGroup,
|
|
102
|
+
connectionMeta,
|
|
103
|
+
async close() {
|
|
104
|
+
await closeWs();
|
|
105
|
+
if (ownsHttpServer) await new Promise((r) => httpServer.close(() => r()));
|
|
106
|
+
if (websocket && getInternalContext(context).wsEndpoint?.url === wsUrl) getInternalContext(context).wsEndpoint = void 0;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Translate the public `register?: boolean | Partial<DevframeInstanceRecord>`
|
|
112
|
+
* option into a shell {@link InstanceRegisterConfig}, or `undefined` when
|
|
113
|
+
* registration is opted out. The object form supplies record overrides on top
|
|
114
|
+
* of the caller-provided identity defaults.
|
|
115
|
+
*/
|
|
116
|
+
function resolveInstanceRegister(option, defaults) {
|
|
117
|
+
if (!option) return void 0;
|
|
118
|
+
return {
|
|
119
|
+
id: defaults.id,
|
|
120
|
+
...defaults.name !== void 0 ? { name: defaults.name } : {},
|
|
121
|
+
...defaults.rootDir !== void 0 ? { rootDir: defaults.rootDir } : {},
|
|
122
|
+
...typeof option === "object" ? { overrides: option } : {}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/** Compare two URL paths ignoring a trailing slash. */
|
|
126
|
+
function samePath(a, b) {
|
|
127
|
+
return withoutTrailingSlash(a) === withoutTrailingSlash(b);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Copy a web `Response` from a fetch-style transport handler onto the h3
|
|
131
|
+
* event's response and return its body — mirroring the MCP route's bridge.
|
|
132
|
+
* Returning the body (a `ReadableStream`, or `''` for an empty one — h3
|
|
133
|
+
* middleware only falls through on `undefined`) terminates the chain with
|
|
134
|
+
* the status/headers set here instead of continuing to the SPA catch-all.
|
|
135
|
+
*/
|
|
136
|
+
function respondWith(event, response) {
|
|
137
|
+
event.res.status = response.status;
|
|
138
|
+
event.res.statusText = response.statusText;
|
|
139
|
+
response.headers.forEach((value, key) => {
|
|
140
|
+
event.res.headers.set(key, value);
|
|
141
|
+
});
|
|
142
|
+
return response.body ?? "";
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The shared machinery behind `initDevframe` and `initHub`: one mount base,
|
|
146
|
+
* one h3 app, one lazily-derived public origin (and the auth banner that waits
|
|
147
|
+
* for it), one WebSocket binding, and the fetch / connect-middleware pair that
|
|
148
|
+
* serves them. Each factory supplies only what makes it itself — its context,
|
|
149
|
+
* its routes, its diagnostics — through `init` / `mount`.
|
|
150
|
+
*
|
|
151
|
+
* Nothing here listens on a port unless a side-car was explicitly requested:
|
|
152
|
+
* the default tier leaves the socket `unbound`, so a host chains it onto its
|
|
153
|
+
* own server through {@link InstanceShell.attach} /
|
|
154
|
+
* {@link InstanceShell.handleUpgrade}.
|
|
155
|
+
*
|
|
156
|
+
* @internal
|
|
157
|
+
*/
|
|
158
|
+
function createInstanceShell(options) {
|
|
159
|
+
const base = options.base;
|
|
160
|
+
const baseNoSlash = withoutTrailingSlash(base);
|
|
161
|
+
const app = options.app ?? new H3();
|
|
162
|
+
const wsDisabled = options.ws === false;
|
|
163
|
+
const ws = options.ws === false ? {} : options.ws ?? {};
|
|
164
|
+
const route = withoutLeadingSlash(ws.route ?? "__ws");
|
|
165
|
+
/** Where an upgrade lands on the host's own origin. */
|
|
166
|
+
const routePath = joinURL(base, route);
|
|
167
|
+
/** What `__connection.json` advertises for a same-origin socket. */
|
|
168
|
+
const advertisedPath = options.absoluteWsPath ? routePath : route;
|
|
169
|
+
const sidecarRequested = ws.port != null || ws.sidecar === true;
|
|
170
|
+
const tier = wsDisabled ? "disabled" : sidecarRequested ? "sidecar" : options.server ? "server" : ws.url ? "external" : "unbound";
|
|
171
|
+
const sseEnabled = options.sse !== false && tier !== "external";
|
|
172
|
+
const sseRoute = withoutLeadingSlash((typeof options.sse === "object" ? options.sse.route : void 0) ?? "__sse");
|
|
173
|
+
const sseRoutePath = joinURL(base, sseRoute);
|
|
174
|
+
const advertisedSsePath = options.absoluteWsPath ? sseRoutePath : sseRoute;
|
|
175
|
+
let derivedOrigin;
|
|
176
|
+
function currentOrigin() {
|
|
177
|
+
return (typeof options.origin === "function" ? options.origin() : options.origin) || derivedOrigin;
|
|
178
|
+
}
|
|
179
|
+
let authHandler;
|
|
180
|
+
let bannerPrinted = false;
|
|
181
|
+
function maybePrintBanner() {
|
|
182
|
+
if (bannerPrinted || !authHandler || !currentOrigin()) return;
|
|
183
|
+
bannerPrinted = true;
|
|
184
|
+
authHandler.printBanner();
|
|
185
|
+
}
|
|
186
|
+
let meta;
|
|
187
|
+
let registration;
|
|
188
|
+
let registerPromise;
|
|
189
|
+
/**
|
|
190
|
+
* Publish the instance in the global registry the moment both its origin
|
|
191
|
+
* and connection meta are known — at init end for a pinned origin, or on
|
|
192
|
+
* the first request for a derived one. Registration never throws (the
|
|
193
|
+
* registry writer degrades to a coded warning), so failures never surface.
|
|
194
|
+
*/
|
|
195
|
+
function maybeRegister() {
|
|
196
|
+
const cfg = options.register;
|
|
197
|
+
const origin = currentOrigin();
|
|
198
|
+
if (!cfg || registerPromise || !origin || !meta) return;
|
|
199
|
+
const resolvedMeta = meta;
|
|
200
|
+
registerPromise = import("./instance-registry-BQqGoDO9.mjs").then((n) => n.t).then(({ registerDevframeInstance }) => {
|
|
201
|
+
let port = 0;
|
|
202
|
+
try {
|
|
203
|
+
const url = new URL(origin);
|
|
204
|
+
port = Number(url.port) || (url.protocol === "https:" ? 443 : 80);
|
|
205
|
+
} catch {}
|
|
206
|
+
registration = registerDevframeInstance({
|
|
207
|
+
pid: process.pid,
|
|
208
|
+
port,
|
|
209
|
+
origin,
|
|
210
|
+
basePath: base,
|
|
211
|
+
id: cfg.id,
|
|
212
|
+
...cfg.name !== void 0 ? { name: cfg.name } : {},
|
|
213
|
+
rootDir: cfg.rootDir ?? process.cwd(),
|
|
214
|
+
mcp: resolvedMeta.mcp ? { path: joinURL(base, resolvedMeta.mcp.path) } : null,
|
|
215
|
+
startedAt: Date.now(),
|
|
216
|
+
...cfg.overrides
|
|
217
|
+
});
|
|
218
|
+
}).catch(() => {});
|
|
219
|
+
}
|
|
220
|
+
function noteOrigin(origin) {
|
|
221
|
+
derivedOrigin ??= origin;
|
|
222
|
+
maybePrintBanner();
|
|
223
|
+
maybeRegister();
|
|
224
|
+
}
|
|
225
|
+
let started;
|
|
226
|
+
let transport;
|
|
227
|
+
let dispose;
|
|
228
|
+
let ctx;
|
|
229
|
+
const api = {
|
|
230
|
+
base,
|
|
231
|
+
app,
|
|
232
|
+
origin: currentOrigin,
|
|
233
|
+
connectionMeta: () => meta
|
|
234
|
+
};
|
|
235
|
+
/**
|
|
236
|
+
* Auth resolution: gate by default, `false` opts out, a handler object
|
|
237
|
+
* installs a custom scheme. The `external` tier has no local transport to
|
|
238
|
+
* gate — the server behind `ws.url` owns auth — so it resolves to nothing.
|
|
239
|
+
*/
|
|
240
|
+
function resolveAuth() {
|
|
241
|
+
if (options.auth === false) return false;
|
|
242
|
+
if (typeof options.auth === "object") {
|
|
243
|
+
authHandler = options.auth;
|
|
244
|
+
return options.auth;
|
|
245
|
+
}
|
|
246
|
+
authHandler = createInteractiveAuth(ctx);
|
|
247
|
+
return authHandler;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* The context's RPC core (birpc group, session lifecycle, auth gate) —
|
|
251
|
+
* one per instance, shared by every transport binding (WS and SSE), so a
|
|
252
|
+
* WS peer and an SSE session live in the same session/broadcast space.
|
|
253
|
+
* Built lazily: an `unbound` host that never wires a transport pays
|
|
254
|
+
* nothing for it, not even the imports. `resolvedAuth` and `ctx` are
|
|
255
|
+
* assigned during `init()` before any caller can reach this.
|
|
256
|
+
*/
|
|
257
|
+
let resolvedAuth = false;
|
|
258
|
+
let corePromise;
|
|
259
|
+
function ensureCore() {
|
|
260
|
+
corePromise ??= import("./rpc-core-CqcJkAu9.mjs").then((n) => n.n).then(({ createContextRpcServer }) => createContextRpcServer({
|
|
261
|
+
context: ctx,
|
|
262
|
+
auth: resolvedAuth,
|
|
263
|
+
onPeerConnect: options.onPeerConnect,
|
|
264
|
+
onPeerDisconnect: options.onPeerDisconnect
|
|
265
|
+
}));
|
|
266
|
+
return corePromise;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* The SSE transport, built on the first request to its route so an
|
|
270
|
+
* instance nobody dials over SSE never loads it.
|
|
271
|
+
*/
|
|
272
|
+
let ssePromise;
|
|
273
|
+
function ensureSse() {
|
|
274
|
+
ssePromise ??= (async () => {
|
|
275
|
+
const [core, { attachSseRpcTransport }] = await Promise.all([ensureCore(), import("./rpc/transports/sse-server.mjs")]);
|
|
276
|
+
return attachSseRpcTransport(core.rpcGroup, {
|
|
277
|
+
allowedOrigins: options.allowedOrigins,
|
|
278
|
+
onConnected: core.onConnected,
|
|
279
|
+
onDisconnected: core.onDisconnected
|
|
280
|
+
});
|
|
281
|
+
})();
|
|
282
|
+
return ssePromise;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* A side-car server on its own port. `getPort` probes and the bind can
|
|
286
|
+
* still race (or disagree across the v4/v6 duals of `localhost`), so an
|
|
287
|
+
* auto-port side-car retries on a fresh random port instead of failing
|
|
288
|
+
* init; a pinned `ws.port` is honored as given and fails loudly.
|
|
289
|
+
*/
|
|
290
|
+
async function startSidecar(core) {
|
|
291
|
+
const sidecarHost = options.host ?? "localhost";
|
|
292
|
+
const start = (port) => bindHttpAndWs({
|
|
293
|
+
context: ctx,
|
|
294
|
+
core,
|
|
295
|
+
host: sidecarHost,
|
|
296
|
+
port,
|
|
297
|
+
path: withLeadingSlash(route),
|
|
298
|
+
allowedOrigins: options.allowedOrigins
|
|
299
|
+
});
|
|
300
|
+
if (ws.port != null) return await start(ws.port);
|
|
301
|
+
const { getPort } = await import("./dist-D8jAMwxU.mjs").then((n) => n.t);
|
|
302
|
+
let lastError;
|
|
303
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
304
|
+
const port = attempt === 0 && options.resolveSidecarPort ? await options.resolveSidecarPort(sidecarHost) : await getPort({
|
|
305
|
+
random: true,
|
|
306
|
+
host: sidecarHost
|
|
307
|
+
});
|
|
308
|
+
try {
|
|
309
|
+
return await start(port);
|
|
310
|
+
} catch (error) {
|
|
311
|
+
lastError = error;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
throw lastError;
|
|
315
|
+
}
|
|
316
|
+
async function init() {
|
|
317
|
+
const result = await options.init(api);
|
|
318
|
+
ctx = result.context;
|
|
319
|
+
dispose = result.dispose;
|
|
320
|
+
resolvedAuth = tier === "external" ? false : resolveAuth();
|
|
321
|
+
let websocketMeta;
|
|
322
|
+
if (tier === "sidecar") {
|
|
323
|
+
started = await startSidecar(await ensureCore());
|
|
324
|
+
websocketMeta = {
|
|
325
|
+
port: started.port,
|
|
326
|
+
path: route
|
|
327
|
+
};
|
|
328
|
+
} else if (tier === "server") {
|
|
329
|
+
started = await bindHttpAndWs({
|
|
330
|
+
context: ctx,
|
|
331
|
+
core: await ensureCore(),
|
|
332
|
+
host: options.host ?? "localhost",
|
|
333
|
+
port: 0,
|
|
334
|
+
server: options.server,
|
|
335
|
+
path: routePath,
|
|
336
|
+
allowedOrigins: options.allowedOrigins,
|
|
337
|
+
destroyUnmatched: options.destroyUnmatchedUpgrades
|
|
338
|
+
});
|
|
339
|
+
websocketMeta = { path: advertisedPath };
|
|
340
|
+
} else if (tier === "external") websocketMeta = ws.url;
|
|
341
|
+
else if (tier === "unbound") websocketMeta = { path: advertisedPath };
|
|
342
|
+
if (!wsDisabled && ws.url) websocketMeta = ws.url;
|
|
343
|
+
if (sseEnabled) app.use(sseRoutePath, defineHandler(async (event) => respondWith(event, await (await ensureSse()).handler(event.req))));
|
|
344
|
+
meta = {
|
|
345
|
+
backend: wsDisabled ? sseEnabled ? "sse" : "none" : "websocket",
|
|
346
|
+
...websocketMeta !== void 0 ? { websocket: websocketMeta } : {},
|
|
347
|
+
...sseEnabled ? { sse: { path: advertisedSsePath } } : {},
|
|
348
|
+
...result.mcp ? { mcp: result.mcp } : {}
|
|
349
|
+
};
|
|
350
|
+
await options.mount?.(ctx, meta, api);
|
|
351
|
+
maybePrintBanner();
|
|
352
|
+
maybeRegister();
|
|
353
|
+
}
|
|
354
|
+
const initPromise = init();
|
|
355
|
+
initPromise.catch(() => {});
|
|
356
|
+
const contextPromise = initPromise.then(() => ctx);
|
|
357
|
+
contextPromise.catch(() => {});
|
|
358
|
+
/**
|
|
359
|
+
* The `unbound` tier: the RPC core and its crossws adapter, bound to
|
|
360
|
+
* nothing. Built on the first `attach` / `handleUpgrade` — a host that
|
|
361
|
+
* never wires the socket (or whose runtime brings its own WS transport)
|
|
362
|
+
* pays nothing for it, not even the adapter's imports.
|
|
363
|
+
*/
|
|
364
|
+
let transportPromise;
|
|
365
|
+
function ensureTransport() {
|
|
366
|
+
transportPromise ??= initPromise.then(async () => {
|
|
367
|
+
const [core, { attachWsRpcTransport }] = await Promise.all([ensureCore(), import("./rpc/transports/ws-server.mjs")]);
|
|
368
|
+
transport = attachWsRpcTransport(core.rpcGroup, {
|
|
369
|
+
unbound: true,
|
|
370
|
+
path: routePath,
|
|
371
|
+
allowedOrigins: options.allowedOrigins,
|
|
372
|
+
onConnected: core.onConnected,
|
|
373
|
+
onDisconnected: core.onDisconnected
|
|
374
|
+
});
|
|
375
|
+
return transport;
|
|
376
|
+
});
|
|
377
|
+
return transportPromise;
|
|
378
|
+
}
|
|
379
|
+
async function handleRequest(request) {
|
|
380
|
+
await initPromise;
|
|
381
|
+
noteOrigin(new URL(request.url).origin);
|
|
382
|
+
const response = await app.fetch(request);
|
|
383
|
+
if (response.status === 404) return new Response(null, { status: 404 });
|
|
384
|
+
return response;
|
|
385
|
+
}
|
|
386
|
+
let nodeHandler;
|
|
387
|
+
function nodeMiddleware(req, res, next) {
|
|
388
|
+
let pathname = req.url ?? "/";
|
|
389
|
+
try {
|
|
390
|
+
pathname = new URL(pathname, "http://localhost").pathname;
|
|
391
|
+
} catch {}
|
|
392
|
+
if (!(samePath(pathname, baseNoSlash) || pathname.startsWith(base))) {
|
|
393
|
+
if (next) {
|
|
394
|
+
next();
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
res.statusCode = 404;
|
|
398
|
+
res.end();
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
initPromise.then(async () => {
|
|
402
|
+
const host = req.headers.host;
|
|
403
|
+
if (host) {
|
|
404
|
+
const encrypted = req.socket.encrypted;
|
|
405
|
+
noteOrigin(`${encrypted ? "https" : "http"}://${host}`);
|
|
406
|
+
}
|
|
407
|
+
if (!nodeHandler) {
|
|
408
|
+
const { toNodeHandler } = await import("h3/node");
|
|
409
|
+
nodeHandler = toNodeHandler(app);
|
|
410
|
+
}
|
|
411
|
+
return nodeHandler(req, res);
|
|
412
|
+
}).catch((err) => {
|
|
413
|
+
if (next) {
|
|
414
|
+
next(err);
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
res.statusCode = 500;
|
|
418
|
+
res.end();
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
/** The `unbound` tier is the only one whose socket the host may drive. */
|
|
422
|
+
function assertUnbound() {
|
|
423
|
+
if (tier === "disabled") throw diagnostics.DF0057();
|
|
424
|
+
if (tier === "external") throw diagnostics.DF0056({ url: ws.url });
|
|
425
|
+
if (tier !== "unbound") throw diagnostics.DF0055({ tier });
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Publish the socket's absolute URL on the context, so surfaces that hand
|
|
429
|
+
* out a complete endpoint (the hub's remote docks) work on this tier too.
|
|
430
|
+
* {@link bindHttpAndWs} does the same for the tiers it owns.
|
|
431
|
+
*/
|
|
432
|
+
function publishWsEndpoint(server) {
|
|
433
|
+
const record = () => {
|
|
434
|
+
const address = server.address();
|
|
435
|
+
if (typeof address !== "object" || !address) return;
|
|
436
|
+
const host = options.host ?? (address.address === "::" || address.address === "0.0.0.0" ? "localhost" : address.address);
|
|
437
|
+
getInternalContext(ctx).wsEndpoint = { url: `ws://${formatHostForUrl(host)}:${address.port}${routePath}` };
|
|
438
|
+
};
|
|
439
|
+
if (server.listening) record();
|
|
440
|
+
else server.once("listening", record);
|
|
441
|
+
}
|
|
442
|
+
function handleUpgrade(req, socket, head) {
|
|
443
|
+
assertUnbound();
|
|
444
|
+
if (transport) {
|
|
445
|
+
transport.handleUpgrade(req, socket, head);
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
ensureTransport().then((live) => live.handleUpgrade(req, socket, head)).catch(() => socket.destroy());
|
|
449
|
+
}
|
|
450
|
+
function attach(server) {
|
|
451
|
+
assertUnbound();
|
|
452
|
+
server.on("upgrade", handleUpgrade);
|
|
453
|
+
ensureTransport().then(() => publishWsEndpoint(server)).catch(() => {});
|
|
454
|
+
return () => server.off("upgrade", handleUpgrade);
|
|
455
|
+
}
|
|
456
|
+
return {
|
|
457
|
+
base,
|
|
458
|
+
handler: handleRequest,
|
|
459
|
+
nodeMiddleware,
|
|
460
|
+
ready: initPromise,
|
|
461
|
+
context: contextPromise,
|
|
462
|
+
connectionMeta: () => meta ?? options.onMetaUnavailable(),
|
|
463
|
+
handleUpgrade,
|
|
464
|
+
attach,
|
|
465
|
+
async close() {
|
|
466
|
+
await initPromise.catch(() => {});
|
|
467
|
+
await registerPromise?.catch(() => {});
|
|
468
|
+
registration?.unregister();
|
|
469
|
+
await dispose?.();
|
|
470
|
+
await ssePromise?.then((live) => live.close()).catch(() => {});
|
|
471
|
+
await started?.close();
|
|
472
|
+
await transportPromise?.then((live) => live.close()).catch(() => {});
|
|
473
|
+
},
|
|
474
|
+
internals: {
|
|
475
|
+
get started() {
|
|
476
|
+
return started;
|
|
477
|
+
},
|
|
478
|
+
get authHandler() {
|
|
479
|
+
return authHandler;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
//#endregion
|
|
485
|
+
export { normalizeHttpServerUrl as i, resolveInstanceRegister as n, samePath as r, createInstanceShell as t };
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { At as DevframeAgentHost$1, Ct as AgentResource, Dt as AgentToolInput, Et as AgentTool, Mt as EventEmitter, Ot as AgentToolProvider, St as AgentManifest, Tt as AgentResourceInput, jt as DevframeAgentHostEvents, kt as AgentToolProviderHandle, wt as AgentResourceContent, x as DevframeNodeContext, xt as AgentHandle, z as DevframeHost } from "../devframe-Bdd9YXTy.mjs";
|
|
2
|
+
import { v as RpcFunctionDefinitionAny } from "../types-CnJSgRVa.mjs";
|
|
3
|
+
import { a as InstanceShellInit, c as StartedServer, d as samePath, f as DevframeInstanceRecord, h as registerDevframeInstance, i as InstanceShellApi, l as createInstanceShell, m as listLiveDevframeInstances, n as InstanceRegisterConfig, o as InstanceShellInternals, p as DevframeInstanceRegistration, r as InstanceShell, s as InstanceWsTier, t as CreateInstanceShellOptions, u as resolveInstanceRegister } from "../instance-shell-DBTXTSjN.mjs";
|
|
4
|
+
import { n as CreateContextRpcServerOptions, r as createContextRpcServer, t as ContextRpcServer } from "../rpc-core-CGctXToO.mjs";
|
|
5
|
+
//#region src/node/agent-args.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* How {@link coerceAgentPositionalArgs} treats an args object that carries
|
|
8
|
+
* neither declared schemas nor `arg0`/`arg1`/… keys:
|
|
9
|
+
*
|
|
10
|
+
* - `'wrap'` — pass the object itself as the single positional argument.
|
|
11
|
+
* RPC-backed tools use this: an untyped RPC may take one raw object.
|
|
12
|
+
* - `'drop'` — call with zero arguments. Command-backed tools use this:
|
|
13
|
+
* a handler's positional parameters come solely from its declared
|
|
14
|
+
* `agent.args` schemas, so undeclared payload is ignored.
|
|
15
|
+
*/
|
|
16
|
+
type AgentArgsFallback = 'wrap' | 'drop';
|
|
17
|
+
/**
|
|
18
|
+
* Map the args payload an agent surface receives (MCP sends an object
|
|
19
|
+
* keyed `arg0`/`arg1`/…, matching the schema the adapter advertises) onto
|
|
20
|
+
* a handler's positional parameters. Shared by the agent host's RPC
|
|
21
|
+
* bridge and the hub's command-derived tools so the coercion cannot
|
|
22
|
+
* drift between them.
|
|
23
|
+
*
|
|
24
|
+
* - an array passes through as-is
|
|
25
|
+
* - `null`/`undefined` become a zero-argument call
|
|
26
|
+
* - with declared schemas, each schema reads its own `argN` key, in order
|
|
27
|
+
* - without schemas, `arg0`/`arg1`/… keys are collected when present
|
|
28
|
+
* - an empty object becomes a zero-argument call
|
|
29
|
+
* - anything else follows the {@link AgentArgsFallback}
|
|
30
|
+
*
|
|
31
|
+
* @experimental
|
|
32
|
+
*/
|
|
33
|
+
declare function coerceAgentPositionalArgs(args: unknown, schemas: readonly unknown[] | undefined, fallback?: AgentArgsFallback): unknown[];
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/node/host-agent.d.ts
|
|
36
|
+
/**
|
|
37
|
+
* Framework-neutral host aggregating the agent-exposed surface of a
|
|
38
|
+
* devframe. Auto-discovers RPC functions with an `agent` field from
|
|
39
|
+
* `ctx.rpc.definitions`, and accepts plugin-registered tools /
|
|
40
|
+
* resources via `registerTool` / `registerResource`.
|
|
41
|
+
*
|
|
42
|
+
* @experimental
|
|
43
|
+
*/
|
|
44
|
+
declare class DevframeAgentHost implements DevframeAgentHost$1 {
|
|
45
|
+
readonly context: DevframeNodeContext;
|
|
46
|
+
readonly events: EventEmitter<DevframeAgentHostEvents>;
|
|
47
|
+
private readonly tools;
|
|
48
|
+
private readonly resources;
|
|
49
|
+
private readonly providers;
|
|
50
|
+
private _rpcUnsubscribe;
|
|
51
|
+
constructor(context: DevframeNodeContext);
|
|
52
|
+
registerTool(input: AgentToolInput): AgentHandle;
|
|
53
|
+
unregisterTool(id: string): boolean;
|
|
54
|
+
registerToolProvider(provider: AgentToolProvider): AgentToolProviderHandle;
|
|
55
|
+
registerResource(input: AgentResourceInput): AgentHandle;
|
|
56
|
+
unregisterResource(id: string): boolean;
|
|
57
|
+
list(): AgentManifest;
|
|
58
|
+
getTool(id: string): AgentTool | undefined;
|
|
59
|
+
getResource(id: string): AgentResource | undefined;
|
|
60
|
+
invoke(id: string, args: unknown): Promise<unknown>;
|
|
61
|
+
read(id: string): Promise<AgentResourceContent>;
|
|
62
|
+
/** @internal */
|
|
63
|
+
_dispose(): void;
|
|
64
|
+
private _validateToolId;
|
|
65
|
+
private _projectTool;
|
|
66
|
+
/** Query every registered provider, projecting inputs to serializable tools. */
|
|
67
|
+
private _collectProviderTools;
|
|
68
|
+
private _collectRpcTools;
|
|
69
|
+
private _findRpcDefinition;
|
|
70
|
+
}
|
|
71
|
+
//#endregion
|
|
72
|
+
//#region src/node/host-h3.d.ts
|
|
73
|
+
interface CreateH3DevframeHostOptions {
|
|
74
|
+
/** The h3 app instance — registered once the CLI adapter lands. */
|
|
75
|
+
app?: unknown;
|
|
76
|
+
/**
|
|
77
|
+
* Host the standalone server listens on, e.g. `http://localhost:9999`.
|
|
78
|
+
* Consumed by `resolveOrigin` for dock entries that need an absolute URL.
|
|
79
|
+
* Pass a function for hosts that only learn their public origin later
|
|
80
|
+
* (e.g. `createHandler` derives it from the first incoming request).
|
|
81
|
+
*/
|
|
82
|
+
origin: string | (() => string);
|
|
83
|
+
/**
|
|
84
|
+
* Register a static-file handler at `base` serving files from `distDir`.
|
|
85
|
+
* Wired into the h3 app once the CLI adapter lands (commit 5). For now
|
|
86
|
+
* the CLI isn't running, so the default is a no-op.
|
|
87
|
+
*/
|
|
88
|
+
mount?: (base: string, distDir: string) => void | Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Namespace for storage paths returned by `getStorageDir`. Workspace
|
|
91
|
+
* state (committable) lives under `${workspaceRoot}/.devframe/`, project
|
|
92
|
+
* state under `${workspaceRoot}/node_modules/.<appName>/devframe/`, and
|
|
93
|
+
* global state under `${homedir()}/.<appName>/devframe/`. Pick the
|
|
94
|
+
* devtool's id (or another stable, filesystem-safe identifier) so the
|
|
95
|
+
* standalone host doesn't collide with other tools' storage.
|
|
96
|
+
*/
|
|
97
|
+
appName: string;
|
|
98
|
+
/**
|
|
99
|
+
* Workspace root used as the parent of the per-project storage
|
|
100
|
+
* directory. Defaults to `process.cwd()`.
|
|
101
|
+
*/
|
|
102
|
+
workspaceRoot?: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* h3-backed {@link DevframeHost} — used by the standalone CLI adapter.
|
|
106
|
+
*/
|
|
107
|
+
declare function createH3DevframeHost(options: CreateH3DevframeHostOptions): DevframeHost;
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region src/node/utils.d.ts
|
|
110
|
+
declare function normalizeHttpServerUrl(host: string, port: number | string): string;
|
|
111
|
+
//#endregion
|
|
112
|
+
//#region src/rpc/wire-codec.d.ts
|
|
113
|
+
/**
|
|
114
|
+
* The per-connection `serialize`/`deserialize` pair for a live RPC wire.
|
|
115
|
+
*
|
|
116
|
+
* @internal
|
|
117
|
+
* implementations; not part of the stable public API.
|
|
118
|
+
*/
|
|
119
|
+
interface RpcWireCodec {
|
|
120
|
+
serialize: (msg: any) => string;
|
|
121
|
+
deserialize: (raw: string) => any;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Build the per-connection wire codec every live transport (WS server, WS
|
|
125
|
+
* client, SSE server, SSE client) shares: per-method dispatch between strict
|
|
126
|
+
* JSON (methods declared `jsonSerializable: true`) and `s:`-prefixed
|
|
127
|
+
* structured-clone (everything else, including all error envelopes), with a
|
|
128
|
+
* request-id → method map so a response independently picks the same
|
|
129
|
+
* encoder as its request. One codec per connection — request-id spaces
|
|
130
|
+
* don't collide across connections.
|
|
131
|
+
*
|
|
132
|
+
* @internal
|
|
133
|
+
* implementations; not part of the stable public API.
|
|
134
|
+
*/
|
|
135
|
+
declare function createRpcWireCodec(definitions?: ReadonlyMap<string, Pick<RpcFunctionDefinitionAny, 'jsonSerializable'>>): RpcWireCodec;
|
|
136
|
+
/**
|
|
137
|
+
* Peek at a wire frame's birpc envelope without engaging a codec's
|
|
138
|
+
* request-id bookkeeping — used by the SSE transport to route a frame
|
|
139
|
+
* (park a POST for its response / answer with a bare 202) before it is
|
|
140
|
+
* handed to birpc proper.
|
|
141
|
+
*
|
|
142
|
+
* @internal
|
|
143
|
+
* implementations; not part of the stable public API.
|
|
144
|
+
*/
|
|
145
|
+
declare function peekRpcWireFrame(raw: string): {
|
|
146
|
+
t?: string;
|
|
147
|
+
i?: string;
|
|
148
|
+
};
|
|
149
|
+
//#endregion
|
|
150
|
+
export { type AgentArgsFallback, type ContextRpcServer, type CreateContextRpcServerOptions, CreateH3DevframeHostOptions, type CreateInstanceShellOptions, DevframeAgentHost, type DevframeInstanceRecord, type DevframeInstanceRegistration, type InstanceRegisterConfig, type InstanceShell, type InstanceShellApi, type InstanceShellInit, type InstanceShellInternals, type InstanceWsTier, type RpcWireCodec, type StartedServer, coerceAgentPositionalArgs, createContextRpcServer, createH3DevframeHost, createInstanceShell, createRpcWireCodec, listLiveDevframeInstances, normalizeHttpServerUrl, peekRpcWireFrame, registerDevframeInstance, resolveInstanceRegister, samePath };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { n as peekRpcWireFrame, t as createRpcWireCodec } from "../wire-codec-9VhIKnyp.mjs";
|
|
2
|
+
import { n as coerceAgentPositionalArgs, t as DevframeAgentHost } from "../host-agent-CpbAoqBx.mjs";
|
|
3
|
+
import { t as createH3DevframeHost } from "../host-h3-CzCZwtuV.mjs";
|
|
4
|
+
import { i as registerDevframeInstance, n as listLiveDevframeInstances } from "../instance-registry-BQqGoDO9.mjs";
|
|
5
|
+
import { i as normalizeHttpServerUrl, n as resolveInstanceRegister, r as samePath, t as createInstanceShell } from "../instance-shell-KRdee1QF.mjs";
|
|
6
|
+
import { t as createContextRpcServer } from "../rpc-core-CqcJkAu9.mjs";
|
|
7
|
+
export { DevframeAgentHost, coerceAgentPositionalArgs, createContextRpcServer, createH3DevframeHost, createInstanceShell, createRpcWireCodec, listLiveDevframeInstances, normalizeHttpServerUrl, peekRpcWireFrame, registerDevframeInstance, resolveInstanceRegister, samePath };
|
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-Bdd9YXTy.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-CZRd2K1C.mjs";
|
|
3
3
|
export { DevframeAuthHandler, buildOtpAuthUrl, exchangeTempAuthCode, getTempAuthCode, refreshTempAuthCode, revokeActiveConnectionsForToken, revokeAuthToken, verifyAuthToken };
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
import { i as
|
|
2
|
-
import {
|
|
3
|
-
//#region src/adapters/_shared.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Resolve the mount base path for a devframe's SPA. Hosted adapters
|
|
6
|
-
* (`vite`, `embedded`) default to `/__<id>/` so they don't collide
|
|
7
|
-
* with the host app; standalone adapters (`cli`, `spa`, `build`)
|
|
8
|
-
* default to `/` because they own the origin.
|
|
9
|
-
*
|
|
10
|
-
* The devframe author can override with `basePath` on the definition.
|
|
11
|
-
*/
|
|
12
|
-
declare function resolveBasePath(def: DevframeDefinition, kind: DevframeDeploymentKind): string;
|
|
13
|
-
declare function normalizeBasePath(base: string): string;
|
|
14
|
-
//#endregion
|
|
1
|
+
import { a as internalContextMap, i as getInternalContext, n as InternalAnonymousAuthStorage, r as RemoteTokenRecord, t as DevframeInternalContext } from "../context-CSCwoABx.mjs";
|
|
2
|
+
import { n as normalizeBasePath, r as resolveBasePath } from "../_shared-DmpWW-HH.mjs";
|
|
15
3
|
export { type DevframeInternalContext, type InternalAnonymousAuthStorage, type RemoteTokenRecord, getInternalContext, internalContextMap, normalizeBasePath, resolveBasePath };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
import { n as
|
|
1
|
+
import { n as resolveBasePath, t as normalizeBasePath } from "../_shared-CttmCMBi.mjs";
|
|
2
|
+
import { n as internalContextMap, t as getInternalContext } from "../context-C33rR7n0.mjs";
|
|
3
3
|
export { getInternalContext, internalContextMap, normalizeBasePath, resolveBasePath };
|