@hediet/linkrpc-hub 0.0.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/README.md +101 -0
- package/dist/chunks/config-BCvkg7jv.d.ts +566 -0
- package/dist/chunks/configFile-y6Phntqu.d.ts +9 -0
- package/dist/chunks/connectionTokenBinder.interfaces-B-beCg06.js +40 -0
- package/dist/chunks/connectionTokenBinder.interfaces-B-beCg06.js.map +1 -0
- package/dist/chunks/connectionTokenBinder.interfaces-BhzQ1DTS.d.ts +36 -0
- package/dist/chunks/hubConnectionAcceptor-B5-8JsFY.js +2768 -0
- package/dist/chunks/hubConnectionAcceptor-B5-8JsFY.js.map +1 -0
- package/dist/chunks/hubConnectionAcceptor-BwydvFa4.d.ts +1560 -0
- package/dist/chunks/index-CLIUrV88.d.ts +481 -0
- package/dist/chunks/node-CTXsQ6oa.js +460 -0
- package/dist/chunks/node-CTXsQ6oa.js.map +1 -0
- package/dist/chunks/nodeTransit-CWeFnbwt.js +444 -0
- package/dist/chunks/nodeTransit-CWeFnbwt.js.map +1 -0
- package/dist/chunks/nodeTransit-cmtZgdpW.d.ts +226 -0
- package/dist/chunks/runHub-P3YUwwdv.js +1797 -0
- package/dist/chunks/runHub-P3YUwwdv.js.map +1 -0
- package/dist/chunks/server-BAxchQhy.js +1368 -0
- package/dist/chunks/server-BAxchQhy.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +38 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.js +305 -0
- package/dist/config.js.map +1 -0
- package/dist/configFile.d.ts +2 -0
- package/dist/configFile.js +27 -0
- package/dist/configFile.js.map +1 -0
- package/dist/engine/runHub.d.ts +42 -0
- package/dist/engine/runHub.js +2 -0
- package/dist/hub/server/client.d.ts +2 -0
- package/dist/hub/server/client.js +2 -0
- package/dist/hub/server/connectionTokenBinder.d.ts +2 -0
- package/dist/hub/server/connectionTokenBinder.js +2 -0
- package/dist/hub/server/index.d.ts +5 -0
- package/dist/hub/server/index.js +5 -0
- package/dist/hub/server/node/index.d.ts +218 -0
- package/dist/hub/server/node/index.js +2 -0
- package/dist/hub/server/transit.d.ts +2 -0
- package/dist/hub/server/transit.js +2 -0
- package/dist/index.d.ts +512 -0
- package/dist/index.js +309 -0
- package/dist/index.js.map +1 -0
- package/dist/serve.d.ts +14 -0
- package/dist/serve.js +31 -0
- package/dist/serve.js.map +1 -0
- package/dist/spawn.d.ts +12 -0
- package/dist/spawn.js +25 -0
- package/dist/spawn.js.map +1 -0
- package/package.json +83 -0
package/dist/config.js
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/config.ts
|
|
3
|
+
/**
|
|
4
|
+
* Declarative hub configuration shared by the CLI (`serve`, `connect`,
|
|
5
|
+
* `tunnel`, `-c, --config`), the server hub, and the VS Code extension. One
|
|
6
|
+
* config describes a hub by its **transports**:
|
|
7
|
+
*
|
|
8
|
+
* - {@link HubConfig.listeners} — inbound: accept many peers (websocket / unix
|
|
9
|
+
* socket). Each peer is admitted by the listener's ordered {@link
|
|
10
|
+
* ConnectionHandlerSchema handlers} (keyed on the presented token), which also
|
|
11
|
+
* provision its root services (identity, granted namespace, minting).
|
|
12
|
+
* - {@link HubConfig.endpoints} — outbound: dial a single far end (a remote
|
|
13
|
+
* hub over `ws`/`socket`, or a spawned child over `cmd-env`/`cmd-stdio`).
|
|
14
|
+
* Dial-out has no token, so an endpoint carries a single inline
|
|
15
|
+
* {@link provisionFields provision} instead of handlers.
|
|
16
|
+
* - {@link HubConfig.namedEndpoints} — sugar over `endpoints`: the map key
|
|
17
|
+
* becomes the `grantedServiceId` and the `managedIdentity.slot`
|
|
18
|
+
* (`endpoint:<name>`) unless overridden.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* A **provision**: the root services a connection is granted once admitted.
|
|
22
|
+
* Shared by listener handlers (static/anonymous forms) and endpoints. Each
|
|
23
|
+
* field is optional and names the root interface it enables.
|
|
24
|
+
*/
|
|
25
|
+
const ConnectionTokenBinderSchema = z.object({
|
|
26
|
+
/** Managed-identity slots this binder may mint (literal string prefix). */
|
|
27
|
+
identitySlotPrefix: z.string().min(1).optional(),
|
|
28
|
+
/** ServiceId namespaces this binder may grant (literal string prefix). */
|
|
29
|
+
serviceIdPrefix: z.string().min(1).optional()
|
|
30
|
+
});
|
|
31
|
+
const provisionFields = {
|
|
32
|
+
/**
|
|
33
|
+
* Managed identity for the connection (`identity::*`), provisioned under
|
|
34
|
+
* `slot`. Omit for no managed identity.
|
|
35
|
+
*/
|
|
36
|
+
managedIdentity: z.object({ slot: z.string().min(1) }).optional(),
|
|
37
|
+
/**
|
|
38
|
+
* ServiceId namespace the connection may claim freely
|
|
39
|
+
* (`hubGrantedServiceId::get`). Omit to grant no freely-claimable namespace.
|
|
40
|
+
*/
|
|
41
|
+
grantedServiceId: z.string().min(1).optional(),
|
|
42
|
+
/**
|
|
43
|
+
* Authorize the connection to mint single-use connection tokens by serving
|
|
44
|
+
* `connectionTokenBinder::bindConnectionToken` at its overlay root. The two
|
|
45
|
+
* prefixes bound **independent axes** of what a minted token may carry; set
|
|
46
|
+
* either, both, or neither.
|
|
47
|
+
*/
|
|
48
|
+
connectionTokenBinder: ConnectionTokenBinderSchema.optional()
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* A listener **connection handler**: a token match + (for the static forms) the
|
|
52
|
+
* provision to install when it claims. Discriminated by `token`:
|
|
53
|
+
*
|
|
54
|
+
* - `anonymous` — claims **any** connection (the catch-all "no auth"); provisions
|
|
55
|
+
* the inline fields.
|
|
56
|
+
* - `static` — claims connections whose presented token equals `value`;
|
|
57
|
+
* provisions the inline fields.
|
|
58
|
+
* - `bound` — claims connections whose token is live in the hub's
|
|
59
|
+
* connection-token store, **redeeming** it (single-use). The provision is
|
|
60
|
+
* **intrinsic** to the token's mint binding (identity slot and/or granted
|
|
61
|
+
* namespace), so it carries no inline provision.
|
|
62
|
+
*/
|
|
63
|
+
const ConnectionHandlerSchema = z.discriminatedUnion("token", [
|
|
64
|
+
z.object({
|
|
65
|
+
token: z.literal("anonymous"),
|
|
66
|
+
...provisionFields
|
|
67
|
+
}),
|
|
68
|
+
z.object({
|
|
69
|
+
token: z.literal("static"),
|
|
70
|
+
value: z.string().min(1),
|
|
71
|
+
...provisionFields
|
|
72
|
+
}),
|
|
73
|
+
z.object({ token: z.literal("bound") })
|
|
74
|
+
]);
|
|
75
|
+
/** Routing fields common to every endpoint (outbound transport). */
|
|
76
|
+
const routingFields = {
|
|
77
|
+
/** The far end serves these service ids; route matching calls OUT to it. */
|
|
78
|
+
routeServiceIds: z.array(z.string().min(1)).default([]),
|
|
79
|
+
/** I serve these service ids; register them on the far end's hub. */
|
|
80
|
+
claimServiceIds: z.array(z.string().min(1)).default([]),
|
|
81
|
+
/** Catch-all: anything not otherwise routed goes to this transport. */
|
|
82
|
+
defaultRoute: z.boolean().default(false),
|
|
83
|
+
/**
|
|
84
|
+
* The root services the far end is provisioned with (`managedIdentity`,
|
|
85
|
+
* `grantedServiceId`, `connectionTokenBinder`). Only honored on `cmd-env`
|
|
86
|
+
* endpoints (the only outbound transport that gets an overlay-root front
|
|
87
|
+
* door); `connectionTokenBinder` is rejected on other endpoint kinds. Each
|
|
88
|
+
* binder prefix (e.g. `"docker/"`) is matched against the requested value as
|
|
89
|
+
* a literal string prefix — it grants an unbounded family, so scope it
|
|
90
|
+
* narrowly. The token minted here is later redeemed by a peer on a listener
|
|
91
|
+
* `{ token: "bound" }` handler.
|
|
92
|
+
*/
|
|
93
|
+
...provisionFields
|
|
94
|
+
};
|
|
95
|
+
/** Universal copy-paste form: a strict endpoint URI plus an optional token. */
|
|
96
|
+
const uriEndpoint = z.object({
|
|
97
|
+
kind: z.literal("uri"),
|
|
98
|
+
/** e.g. `wss://host/?…`, `unix:/run/hub.sock`, `npipe://./pipe/x`. */
|
|
99
|
+
uri: z.string().min(1),
|
|
100
|
+
token: z.string().optional(),
|
|
101
|
+
...routingFields
|
|
102
|
+
});
|
|
103
|
+
/** A running WebSocket hub. */
|
|
104
|
+
const wsEndpoint = z.object({
|
|
105
|
+
kind: z.literal("ws"),
|
|
106
|
+
url: z.string().min(1),
|
|
107
|
+
token: z.string().optional(),
|
|
108
|
+
...routingFields
|
|
109
|
+
});
|
|
110
|
+
/** A named pipe / unix-domain socket the far end already listens on. */
|
|
111
|
+
const socketEndpoint = z.object({
|
|
112
|
+
kind: z.literal("socket"),
|
|
113
|
+
path: z.string().min(1),
|
|
114
|
+
token: z.string().optional(),
|
|
115
|
+
...routingFields
|
|
116
|
+
});
|
|
117
|
+
const commandFields = {
|
|
118
|
+
/** Verbatim command line (run through the shell). Use this or `argv`. */
|
|
119
|
+
cmd: z.string().optional(),
|
|
120
|
+
/** Pre-split argv (no shell). Use this or `cmd`. */
|
|
121
|
+
argv: z.array(z.string()).optional(),
|
|
122
|
+
/** Extra environment variables for the spawned child. */
|
|
123
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
124
|
+
/** Working directory for the spawned child. */
|
|
125
|
+
cwd: z.string().optional()
|
|
126
|
+
};
|
|
127
|
+
/** Spawn a child against a private hub socket; it dials back as a participant. */
|
|
128
|
+
const cmdEnvEndpoint = z.object({
|
|
129
|
+
kind: z.literal("cmd-env"),
|
|
130
|
+
...commandFields,
|
|
131
|
+
...routingFields
|
|
132
|
+
});
|
|
133
|
+
/** Spawn a child and talk linkrpc over its stdin/stdout. */
|
|
134
|
+
const cmdStdioEndpoint = z.object({
|
|
135
|
+
kind: z.literal("cmd-stdio"),
|
|
136
|
+
...commandFields,
|
|
137
|
+
...routingFields
|
|
138
|
+
});
|
|
139
|
+
/**
|
|
140
|
+
* Outbound participant kinds that can be attached to an already-running Hub
|
|
141
|
+
* without host-specific admission or identity provisioning.
|
|
142
|
+
*/
|
|
143
|
+
const ParticipantConnectorConfigSchema = z.discriminatedUnion("kind", [
|
|
144
|
+
uriEndpoint,
|
|
145
|
+
wsEndpoint,
|
|
146
|
+
socketEndpoint,
|
|
147
|
+
cmdStdioEndpoint
|
|
148
|
+
]);
|
|
149
|
+
const EndpointConfigSchema = z.discriminatedUnion("kind", [
|
|
150
|
+
uriEndpoint,
|
|
151
|
+
wsEndpoint,
|
|
152
|
+
socketEndpoint,
|
|
153
|
+
cmdEnvEndpoint,
|
|
154
|
+
cmdStdioEndpoint
|
|
155
|
+
]);
|
|
156
|
+
/** Fields a listener shares regardless of transport type. */
|
|
157
|
+
const listenerCommon = {
|
|
158
|
+
/**
|
|
159
|
+
* Ordered connection handlers. Each accepted peer is admitted by the first
|
|
160
|
+
* handler whose token check claims it (see {@link ConnectionHandlerSchema});
|
|
161
|
+
* that handler also provisions the peer's root services. **Required** — an
|
|
162
|
+
* empty array accepts no connection.
|
|
163
|
+
*/
|
|
164
|
+
handlers: z.array(ConnectionHandlerSchema).default([]) };
|
|
165
|
+
const websocketListener = z.object({
|
|
166
|
+
type: z.literal("websocket"),
|
|
167
|
+
host: z.string().default("127.0.0.1"),
|
|
168
|
+
port: z.number().int().min(0).max(65535).default(7878),
|
|
169
|
+
path: z.string().startsWith("/").default("/"),
|
|
170
|
+
healthPath: z.string().startsWith("/").nullable().default("/healthz"),
|
|
171
|
+
maxPayload: z.number().int().positive().default(16777216),
|
|
172
|
+
/** Optional `Origin` allow-list for browser clients. */
|
|
173
|
+
allowedOrigins: z.array(z.string()).default([]),
|
|
174
|
+
...listenerCommon
|
|
175
|
+
});
|
|
176
|
+
const socketListener = z.object({
|
|
177
|
+
type: z.literal("socket"),
|
|
178
|
+
/** UDS path (posix) or named pipe (`\\.\pipe\…`, win32). */
|
|
179
|
+
path: z.string().min(1),
|
|
180
|
+
...listenerCommon
|
|
181
|
+
});
|
|
182
|
+
const ListenerConfigSchema = z.discriminatedUnion("type", [websocketListener, socketListener]);
|
|
183
|
+
/**
|
|
184
|
+
* Forward-checking policy for the hub's inbound listeners. When enabled, the
|
|
185
|
+
* hub mints an admin signing identity, serves the signed
|
|
186
|
+
* `hubServiceIdRegistry::registerServiceId` + `hubAccess` front doors, and gates
|
|
187
|
+
* every forwarded (fully-qualified) call at each listener boundary:
|
|
188
|
+
*
|
|
189
|
+
* - `verifySignatures` — forwarded calls must carry a valid `$hubrpc`
|
|
190
|
+
* signature (authenticity).
|
|
191
|
+
* - `requireCapability` — forwarded calls must additionally present a
|
|
192
|
+
* capability chain rooting at the hub admin (authorization). Granting
|
|
193
|
+
* capabilities is gated by the {@link HubAccessManifestHost} consent rendezvous.
|
|
194
|
+
*
|
|
195
|
+
* `true` is shorthand for both flags on; `false` disables forward checking
|
|
196
|
+
* entirely (open hub, no consent surface).
|
|
197
|
+
*/
|
|
198
|
+
const ForwardCheckingSchema = z.union([z.boolean(), z.object({
|
|
199
|
+
verifySignatures: z.boolean().default(true),
|
|
200
|
+
requireCapability: z.boolean().default(true)
|
|
201
|
+
})]).default(true);
|
|
202
|
+
/**
|
|
203
|
+
* Where the built-in terminal consent approver sources its pending requests
|
|
204
|
+
* from. The approver consumes `hubAccessManifest::{getDesired,watchDesired,
|
|
205
|
+
* setCurrent}` **over a connection** — never the in-process host object — so the
|
|
206
|
+
* same loop works against a remote source unchanged.
|
|
207
|
+
*
|
|
208
|
+
* - `true` (default) — consume this hub's own manifest (served under
|
|
209
|
+
* {@link HubConfig.hubServiceId}). The common, local-operator case.
|
|
210
|
+
* - `{ serviceId }` — consume the manifest served at `serviceId` (e.g. an
|
|
211
|
+
* upstream hub the operator approves on behalf of).
|
|
212
|
+
* - `false` — install no built-in approver; rely entirely on external approvers
|
|
213
|
+
* (configured {@link HubConfig.rootPrincipalIds}) deciding via the manifest.
|
|
214
|
+
*
|
|
215
|
+
* The approver is only started when stdin is a TTY (it drives a terminal
|
|
216
|
+
* prompt); a non-interactive hub is keyless regardless of this setting.
|
|
217
|
+
*/
|
|
218
|
+
const ConsentApproverSchema = z.union([z.boolean(), z.object({ serviceId: z.string().min(1) })]).default(true);
|
|
219
|
+
const HubConfigSchema = z.object({
|
|
220
|
+
/**
|
|
221
|
+
* Conventional pointer to a JSON Schema. Ignored at runtime; present so
|
|
222
|
+
* editors validate against `--print-schema` output.
|
|
223
|
+
*/
|
|
224
|
+
$schema: z.string().optional(),
|
|
225
|
+
/**
|
|
226
|
+
* The hub's own service id: the prefix under which it mounts its global
|
|
227
|
+
* services (`hubAccess`, `hubrpc.directory`, reflection) and the target of
|
|
228
|
+
* each overlay's `hubrpc.directory` referral. Defaults to `'hub'`.
|
|
229
|
+
*/
|
|
230
|
+
hubServiceId: z.string().min(1).default("hub"),
|
|
231
|
+
/** Inbound transports: accept many peers. */
|
|
232
|
+
listeners: z.array(ListenerConfigSchema).default([]),
|
|
233
|
+
/** Outbound transports: dial a single far end each. */
|
|
234
|
+
endpoints: z.array(EndpointConfigSchema).default([]),
|
|
235
|
+
/**
|
|
236
|
+
* Sugar over {@link endpoints}: the map key becomes the entry's
|
|
237
|
+
* `grantedServiceId` and its `managedIdentity.slot` (`endpoint:<name>`)
|
|
238
|
+
* unless overridden.
|
|
239
|
+
*/
|
|
240
|
+
namedEndpoints: z.record(z.string().min(1), EndpointConfigSchema).default({}),
|
|
241
|
+
/**
|
|
242
|
+
* Gate forwarded calls on inbound listeners. Defaults to `true`: signatures
|
|
243
|
+
* are verified and a hub-admin-rooted capability is required, with consent
|
|
244
|
+
* driven through the CLI consent prompt. Set `false` for an open hub.
|
|
245
|
+
*/
|
|
246
|
+
forwardChecking: ForwardCheckingSchema,
|
|
247
|
+
/**
|
|
248
|
+
* Persistent identity slot used to mint the hub's admin signing identity
|
|
249
|
+
* (the capability root) when {@link forwardChecking} is enabled. Stored
|
|
250
|
+
* alongside other provisioned identities.
|
|
251
|
+
*/
|
|
252
|
+
adminIdentitySlot: z.string().min(1).default("hub-admin"),
|
|
253
|
+
/**
|
|
254
|
+
* Additional capability root principal ids the forwarded-call gate trusts,
|
|
255
|
+
* beyond the hub's own admin identity. Lets an external participant (e.g. a
|
|
256
|
+
* dedicated access-granting service) mint capabilities the hub honors
|
|
257
|
+
* without sharing the hub admin key. Only consulted when
|
|
258
|
+
* {@link forwardChecking} requires a capability.
|
|
259
|
+
*/
|
|
260
|
+
rootPrincipalIds: z.array(z.string().min(1)).default([]),
|
|
261
|
+
/**
|
|
262
|
+
* Source for the built-in terminal consent approver. See
|
|
263
|
+
* {@link ConsentApproverSchema}. Defaults to `true` (this hub's own manifest).
|
|
264
|
+
* Only takes effect when {@link forwardChecking} requires a capability and
|
|
265
|
+
* stdin is interactive.
|
|
266
|
+
*/
|
|
267
|
+
consentApprover: ConsentApproverSchema
|
|
268
|
+
});
|
|
269
|
+
/** Parse + validate an in-memory config object. Throws `ZodError` on failure. */
|
|
270
|
+
function parseHubConfig(raw) {
|
|
271
|
+
return HubConfigSchema.parse(_applyNamedEndpointDefaults(raw));
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Apply `namedEndpoints` sugar before validation: each entry's key becomes its
|
|
275
|
+
* `grantedServiceId` and its `managedIdentity.slot` (`endpoint:<name>`)
|
|
276
|
+
* unless set. Done pre-parse so Zod's own defaults don't erase the
|
|
277
|
+
* "was it omitted?" signal.
|
|
278
|
+
*/
|
|
279
|
+
function _applyNamedEndpointDefaults(raw) {
|
|
280
|
+
if (raw === null || typeof raw !== "object") return raw;
|
|
281
|
+
const r = raw;
|
|
282
|
+
const named = r.namedEndpoints;
|
|
283
|
+
if (named === null || typeof named !== "object") return raw;
|
|
284
|
+
const out = {};
|
|
285
|
+
for (const [key, value] of Object.entries(named)) if (value !== null && typeof value === "object") {
|
|
286
|
+
const v = value;
|
|
287
|
+
out[key] = {
|
|
288
|
+
...v,
|
|
289
|
+
grantedServiceId: v.grantedServiceId ?? key,
|
|
290
|
+
managedIdentity: v.managedIdentity ?? { slot: `endpoint:${key}` }
|
|
291
|
+
};
|
|
292
|
+
} else out[key] = value;
|
|
293
|
+
return {
|
|
294
|
+
...r,
|
|
295
|
+
namedEndpoints: out
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
/** JSON-Schema for the config file (for `--print-schema` / editor tooling). */
|
|
299
|
+
function hubConfigJsonSchema() {
|
|
300
|
+
return z.toJSONSchema(HubConfigSchema, { target: "draft-2020-12" });
|
|
301
|
+
}
|
|
302
|
+
//#endregion
|
|
303
|
+
export { ConnectionHandlerSchema, ConnectionTokenBinderSchema, ConsentApproverSchema, EndpointConfigSchema, ForwardCheckingSchema, HubConfigSchema, ListenerConfigSchema, ParticipantConnectorConfigSchema, hubConfigJsonSchema, parseHubConfig };
|
|
304
|
+
|
|
305
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","names":[],"sources":["../src/config.ts"],"sourcesContent":["/**\n * Declarative hub configuration shared by the CLI (`serve`, `connect`,\n * `tunnel`, `-c, --config`), the server hub, and the VS Code extension. One\n * config describes a hub by its **transports**:\n *\n * - {@link HubConfig.listeners} — inbound: accept many peers (websocket / unix\n * socket). Each peer is admitted by the listener's ordered {@link\n * ConnectionHandlerSchema handlers} (keyed on the presented token), which also\n * provision its root services (identity, granted namespace, minting).\n * - {@link HubConfig.endpoints} — outbound: dial a single far end (a remote\n * hub over `ws`/`socket`, or a spawned child over `cmd-env`/`cmd-stdio`).\n * Dial-out has no token, so an endpoint carries a single inline\n * {@link provisionFields provision} instead of handlers.\n * - {@link HubConfig.namedEndpoints} — sugar over `endpoints`: the map key\n * becomes the `grantedServiceId` and the `managedIdentity.slot`\n * (`endpoint:<name>`) unless overridden.\n */\nimport { z } from 'zod';\n\n/**\n * A **provision**: the root services a connection is granted once admitted.\n * Shared by listener handlers (static/anonymous forms) and endpoints. Each\n * field is optional and names the root interface it enables.\n */\nexport const ConnectionTokenBinderSchema = z.object({\n /** Managed-identity slots this binder may mint (literal string prefix). */\n identitySlotPrefix: z.string().min(1).optional(),\n /** ServiceId namespaces this binder may grant (literal string prefix). */\n serviceIdPrefix: z.string().min(1).optional(),\n});\nexport type ConnectionTokenBinderConfig = z.infer<typeof ConnectionTokenBinderSchema>;\n\nconst provisionFields = {\n /**\n * Managed identity for the connection (`identity::*`), provisioned under\n * `slot`. Omit for no managed identity.\n */\n managedIdentity: z.object({ slot: z.string().min(1) }).optional(),\n /**\n * ServiceId namespace the connection may claim freely\n * (`hubGrantedServiceId::get`). Omit to grant no freely-claimable namespace.\n */\n grantedServiceId: z.string().min(1).optional(),\n /**\n * Authorize the connection to mint single-use connection tokens by serving\n * `connectionTokenBinder::bindConnectionToken` at its overlay root. The two\n * prefixes bound **independent axes** of what a minted token may carry; set\n * either, both, or neither.\n */\n connectionTokenBinder: ConnectionTokenBinderSchema.optional(),\n};\n\nexport type ProvisionConfig = z.infer<z.ZodObject<typeof provisionFields>>;\n\n/**\n * A listener **connection handler**: a token match + (for the static forms) the\n * provision to install when it claims. Discriminated by `token`:\n *\n * - `anonymous` — claims **any** connection (the catch-all \"no auth\"); provisions\n * the inline fields.\n * - `static` — claims connections whose presented token equals `value`;\n * provisions the inline fields.\n * - `bound` — claims connections whose token is live in the hub's\n * connection-token store, **redeeming** it (single-use). The provision is\n * **intrinsic** to the token's mint binding (identity slot and/or granted\n * namespace), so it carries no inline provision.\n */\nexport const ConnectionHandlerSchema = z.discriminatedUnion('token', [\n z.object({ token: z.literal('anonymous'), ...provisionFields }),\n z.object({ token: z.literal('static'), value: z.string().min(1), ...provisionFields }),\n z.object({ token: z.literal('bound') }),\n]);\nexport type ConnectionHandlerConfig = z.infer<typeof ConnectionHandlerSchema>;\n\n/** Routing fields common to every endpoint (outbound transport). */\nconst routingFields = {\n /** The far end serves these service ids; route matching calls OUT to it. */\n routeServiceIds: z.array(z.string().min(1)).default([]),\n /** I serve these service ids; register them on the far end's hub. */\n claimServiceIds: z.array(z.string().min(1)).default([]),\n /** Catch-all: anything not otherwise routed goes to this transport. */\n defaultRoute: z.boolean().default(false),\n /**\n * The root services the far end is provisioned with (`managedIdentity`,\n * `grantedServiceId`, `connectionTokenBinder`). Only honored on `cmd-env`\n * endpoints (the only outbound transport that gets an overlay-root front\n * door); `connectionTokenBinder` is rejected on other endpoint kinds. Each\n * binder prefix (e.g. `\"docker/\"`) is matched against the requested value as\n * a literal string prefix — it grants an unbounded family, so scope it\n * narrowly. The token minted here is later redeemed by a peer on a listener\n * `{ token: \"bound\" }` handler.\n */\n ...provisionFields,\n};\n\n// ---- endpoints (outbound) -----------------------------------------------\n\n/** Universal copy-paste form: a strict endpoint URI plus an optional token. */\nconst uriEndpoint = z.object({\n kind: z.literal('uri'),\n /** e.g. `wss://host/?…`, `unix:/run/hub.sock`, `npipe://./pipe/x`. */\n uri: z.string().min(1),\n token: z.string().optional(),\n ...routingFields,\n});\n\n/** A running WebSocket hub. */\nconst wsEndpoint = z.object({\n kind: z.literal('ws'),\n url: z.string().min(1),\n token: z.string().optional(),\n ...routingFields,\n});\n\n/** A named pipe / unix-domain socket the far end already listens on. */\nconst socketEndpoint = z.object({\n kind: z.literal('socket'),\n path: z.string().min(1),\n token: z.string().optional(),\n ...routingFields,\n});\n\nconst commandFields = {\n /** Verbatim command line (run through the shell). Use this or `argv`. */\n cmd: z.string().optional(),\n /** Pre-split argv (no shell). Use this or `cmd`. */\n argv: z.array(z.string()).optional(),\n /** Extra environment variables for the spawned child. */\n env: z.record(z.string(), z.string()).optional(),\n /** Working directory for the spawned child. */\n cwd: z.string().optional(),\n};\n\n/** Spawn a child against a private hub socket; it dials back as a participant. */\nconst cmdEnvEndpoint = z.object({\n kind: z.literal('cmd-env'),\n ...commandFields,\n ...routingFields,\n});\n\n/** Spawn a child and talk linkrpc over its stdin/stdout. */\nconst cmdStdioEndpoint = z.object({\n kind: z.literal('cmd-stdio'),\n ...commandFields,\n ...routingFields,\n});\n\n/**\n * Outbound participant kinds that can be attached to an already-running Hub\n * without host-specific admission or identity provisioning.\n */\nexport const ParticipantConnectorConfigSchema = z.discriminatedUnion('kind', [\n uriEndpoint,\n wsEndpoint,\n socketEndpoint,\n cmdStdioEndpoint,\n]);\nexport type ParticipantConnectorConfig = z.infer<typeof ParticipantConnectorConfigSchema>;\n\nexport const EndpointConfigSchema = z.discriminatedUnion('kind', [\n uriEndpoint,\n wsEndpoint,\n socketEndpoint,\n cmdEnvEndpoint,\n cmdStdioEndpoint,\n]);\nexport type EndpointConfig = z.infer<typeof EndpointConfigSchema>;\n\n// ---- listeners (inbound) ------------------------------------------------\n\n/** Fields a listener shares regardless of transport type. */\nconst listenerCommon = {\n /**\n * Ordered connection handlers. Each accepted peer is admitted by the first\n * handler whose token check claims it (see {@link ConnectionHandlerSchema});\n * that handler also provisions the peer's root services. **Required** — an\n * empty array accepts no connection.\n */\n handlers: z.array(ConnectionHandlerSchema).default([]),\n};\n\nconst websocketListener = z.object({\n type: z.literal('websocket'),\n host: z.string().default('127.0.0.1'),\n port: z.number().int().min(0).max(65535).default(7878),\n path: z.string().startsWith('/').default('/'),\n healthPath: z.string().startsWith('/').nullable().default('/healthz'),\n maxPayload: z.number().int().positive().default(16 * 1024 * 1024),\n /** Optional `Origin` allow-list for browser clients. */\n allowedOrigins: z.array(z.string()).default([]),\n ...listenerCommon,\n});\n\nconst socketListener = z.object({\n type: z.literal('socket'),\n /** UDS path (posix) or named pipe (`\\\\.\\pipe\\…`, win32). */\n path: z.string().min(1),\n ...listenerCommon,\n});\n\nexport const ListenerConfigSchema = z.discriminatedUnion('type', [\n websocketListener,\n socketListener,\n]);\nexport type ListenerConfig = z.infer<typeof ListenerConfigSchema>;\n\n// ---- forward checking ---------------------------------------------------\n\n/**\n * Forward-checking policy for the hub's inbound listeners. When enabled, the\n * hub mints an admin signing identity, serves the signed\n * `hubServiceIdRegistry::registerServiceId` + `hubAccess` front doors, and gates\n * every forwarded (fully-qualified) call at each listener boundary:\n *\n * - `verifySignatures` — forwarded calls must carry a valid `$hubrpc`\n * signature (authenticity).\n * - `requireCapability` — forwarded calls must additionally present a\n * capability chain rooting at the hub admin (authorization). Granting\n * capabilities is gated by the {@link HubAccessManifestHost} consent rendezvous.\n *\n * `true` is shorthand for both flags on; `false` disables forward checking\n * entirely (open hub, no consent surface).\n */\nexport const ForwardCheckingSchema = z.union([\n z.boolean(),\n z.object({\n verifySignatures: z.boolean().default(true),\n requireCapability: z.boolean().default(true),\n }),\n]).default(true);\nexport type ForwardCheckingConfig = z.infer<typeof ForwardCheckingSchema>;\n\n/**\n * Where the built-in terminal consent approver sources its pending requests\n * from. The approver consumes `hubAccessManifest::{getDesired,watchDesired,\n * setCurrent}` **over a connection** — never the in-process host object — so the\n * same loop works against a remote source unchanged.\n *\n * - `true` (default) — consume this hub's own manifest (served under\n * {@link HubConfig.hubServiceId}). The common, local-operator case.\n * - `{ serviceId }` — consume the manifest served at `serviceId` (e.g. an\n * upstream hub the operator approves on behalf of).\n * - `false` — install no built-in approver; rely entirely on external approvers\n * (configured {@link HubConfig.rootPrincipalIds}) deciding via the manifest.\n *\n * The approver is only started when stdin is a TTY (it drives a terminal\n * prompt); a non-interactive hub is keyless regardless of this setting.\n */\nexport const ConsentApproverSchema = z.union([\n z.boolean(),\n z.object({ serviceId: z.string().min(1) }),\n]).default(true);\nexport type ConsentApproverConfig = z.infer<typeof ConsentApproverSchema>;\n\n// ---- top level ----------------------------------------------------------\n\nexport const HubConfigSchema = z.object({\n /**\n * Conventional pointer to a JSON Schema. Ignored at runtime; present so\n * editors validate against `--print-schema` output.\n */\n $schema: z.string().optional(),\n /**\n * The hub's own service id: the prefix under which it mounts its global\n * services (`hubAccess`, `hubrpc.directory`, reflection) and the target of\n * each overlay's `hubrpc.directory` referral. Defaults to `'hub'`.\n */\n hubServiceId: z.string().min(1).default('hub'),\n /** Inbound transports: accept many peers. */\n listeners: z.array(ListenerConfigSchema).default([]),\n /** Outbound transports: dial a single far end each. */\n endpoints: z.array(EndpointConfigSchema).default([]),\n /**\n * Sugar over {@link endpoints}: the map key becomes the entry's\n * `grantedServiceId` and its `managedIdentity.slot` (`endpoint:<name>`)\n * unless overridden.\n */\n namedEndpoints: z.record(z.string().min(1), EndpointConfigSchema).default({}),\n /**\n * Gate forwarded calls on inbound listeners. Defaults to `true`: signatures\n * are verified and a hub-admin-rooted capability is required, with consent\n * driven through the CLI consent prompt. Set `false` for an open hub.\n */\n forwardChecking: ForwardCheckingSchema,\n /**\n * Persistent identity slot used to mint the hub's admin signing identity\n * (the capability root) when {@link forwardChecking} is enabled. Stored\n * alongside other provisioned identities.\n */\n adminIdentitySlot: z.string().min(1).default('hub-admin'),\n /**\n * Additional capability root principal ids the forwarded-call gate trusts,\n * beyond the hub's own admin identity. Lets an external participant (e.g. a\n * dedicated access-granting service) mint capabilities the hub honors\n * without sharing the hub admin key. Only consulted when\n * {@link forwardChecking} requires a capability.\n */\n rootPrincipalIds: z.array(z.string().min(1)).default([]),\n /**\n * Source for the built-in terminal consent approver. See\n * {@link ConsentApproverSchema}. Defaults to `true` (this hub's own manifest).\n * Only takes effect when {@link forwardChecking} requires a capability and\n * stdin is interactive.\n */\n consentApprover: ConsentApproverSchema,\n});\nexport type HubConfig = z.infer<typeof HubConfigSchema>;\n\n/** Parse + validate an in-memory config object. Throws `ZodError` on failure. */\nexport function parseHubConfig(raw: unknown): HubConfig {\n return HubConfigSchema.parse(_applyNamedEndpointDefaults(raw));\n}\n\n/**\n * Apply `namedEndpoints` sugar before validation: each entry's key becomes its\n * `grantedServiceId` and its `managedIdentity.slot` (`endpoint:<name>`)\n * unless set. Done pre-parse so Zod's own defaults don't erase the\n * \"was it omitted?\" signal.\n */\nfunction _applyNamedEndpointDefaults(raw: unknown): unknown {\n if (raw === null || typeof raw !== 'object') return raw;\n const r = raw as Record<string, unknown>;\n const named = r.namedEndpoints;\n if (named === null || typeof named !== 'object') return raw;\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(named as Record<string, unknown>)) {\n if (value !== null && typeof value === 'object') {\n const v = value as Record<string, unknown>;\n out[key] = {\n ...v,\n grantedServiceId: v.grantedServiceId ?? key,\n managedIdentity: v.managedIdentity ?? { slot: `endpoint:${key}` },\n };\n } else {\n out[key] = value;\n }\n }\n return { ...r, namedEndpoints: out };\n}\n\n/** JSON-Schema for the config file (for `--print-schema` / editor tooling). */\nexport function hubConfigJsonSchema(): unknown {\n return z.toJSONSchema(HubConfigSchema, { target: 'draft-2020-12' });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAa,8BAA8B,EAAE,OAAO;;CAEhD,oBAAoB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;;CAE/C,iBAAiB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;AAChD,CAAC;AAGD,MAAM,kBAAkB;;;;;CAKpB,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;;;;;CAKhE,kBAAkB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;;;;;;;CAO7C,uBAAuB,4BAA4B,SAAS;AAChE;;;;;;;;;;;;;;AAiBA,MAAa,0BAA0B,EAAE,mBAAmB,SAAS;CACjE,EAAE,OAAO;EAAE,OAAO,EAAE,QAAQ,WAAW;EAAG,GAAG;CAAgB,CAAC;CAC9D,EAAE,OAAO;EAAE,OAAO,EAAE,QAAQ,QAAQ;EAAG,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;EAAG,GAAG;CAAgB,CAAC;CACrF,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,OAAO,EAAE,CAAC;AAC1C,CAAC;;AAID,MAAM,gBAAgB;;CAElB,iBAAiB,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;;CAEtD,iBAAiB,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;;CAEtD,cAAc,EAAE,QAAQ,CAAC,CAAC,QAAQ,KAAK;;;;;;;;;;;CAWvC,GAAG;AACP;;AAKA,MAAM,cAAc,EAAE,OAAO;CACzB,MAAM,EAAE,QAAQ,KAAK;;CAErB,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACrB,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;CAC3B,GAAG;AACP,CAAC;;AAGD,MAAM,aAAa,EAAE,OAAO;CACxB,MAAM,EAAE,QAAQ,IAAI;CACpB,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACrB,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;CAC3B,GAAG;AACP,CAAC;;AAGD,MAAM,iBAAiB,EAAE,OAAO;CAC5B,MAAM,EAAE,QAAQ,QAAQ;CACxB,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACtB,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;CAC3B,GAAG;AACP,CAAC;AAED,MAAM,gBAAgB;;CAElB,KAAK,EAAE,OAAO,CAAC,CAAC,SAAS;;CAEzB,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS;;CAEnC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS;;CAE/C,KAAK,EAAE,OAAO,CAAC,CAAC,SAAS;AAC7B;;AAGA,MAAM,iBAAiB,EAAE,OAAO;CAC5B,MAAM,EAAE,QAAQ,SAAS;CACzB,GAAG;CACH,GAAG;AACP,CAAC;;AAGD,MAAM,mBAAmB,EAAE,OAAO;CAC9B,MAAM,EAAE,QAAQ,WAAW;CAC3B,GAAG;CACH,GAAG;AACP,CAAC;;;;;AAMD,MAAa,mCAAmC,EAAE,mBAAmB,QAAQ;CACzE;CACA;CACA;CACA;AACJ,CAAC;AAGD,MAAa,uBAAuB,EAAE,mBAAmB,QAAQ;CAC7D;CACA;CACA;CACA;CACA;AACJ,CAAC;;AAMD,MAAM,iBAAiB;;;;;;;AAOnB,UAAU,EAAE,MAAM,uBAAuB,CAAC,CAAC,QAAQ,CAAC,CAAC,EACzD;AAEA,MAAM,oBAAoB,EAAE,OAAO;CAC/B,MAAM,EAAE,QAAQ,WAAW;CAC3B,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,WAAW;CACpC,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,IAAI;CACrD,MAAM,EAAE,OAAO,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,QAAQ,GAAG;CAC5C,YAAY,EAAE,OAAO,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,UAAU;CACpE,YAAY,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,QAAgB;;CAEhE,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;CAC9C,GAAG;AACP,CAAC;AAED,MAAM,iBAAiB,EAAE,OAAO;CAC5B,MAAM,EAAE,QAAQ,QAAQ;;CAExB,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACtB,GAAG;AACP,CAAC;AAED,MAAa,uBAAuB,EAAE,mBAAmB,QAAQ,CAC7D,mBACA,cACJ,CAAC;;;;;;;;;;;;;;;;AAoBD,MAAa,wBAAwB,EAAE,MAAM,CACzC,EAAE,QAAQ,GACV,EAAE,OAAO;CACL,kBAAkB,EAAE,QAAQ,CAAC,CAAC,QAAQ,IAAI;CAC1C,mBAAmB,EAAE,QAAQ,CAAC,CAAC,QAAQ,IAAI;AAC/C,CAAC,CACL,CAAC,CAAC,CAAC,QAAQ,IAAI;;;;;;;;;;;;;;;;;AAmBf,MAAa,wBAAwB,EAAE,MAAM,CACzC,EAAE,QAAQ,GACV,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAC7C,CAAC,CAAC,CAAC,QAAQ,IAAI;AAKf,MAAa,kBAAkB,EAAE,OAAO;;;;;CAKpC,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;;;;;;CAM7B,cAAc,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,KAAK;;CAE7C,WAAW,EAAE,MAAM,oBAAoB,CAAC,CAAC,QAAQ,CAAC,CAAC;;CAEnD,WAAW,EAAE,MAAM,oBAAoB,CAAC,CAAC,QAAQ,CAAC,CAAC;;;;;;CAMnD,gBAAgB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,CAAC,QAAQ,CAAC,CAAC;;;;;;CAM5E,iBAAiB;;;;;;CAMjB,mBAAmB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,WAAW;;;;;;;;CAQxD,kBAAkB,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;;;;;;;CAOvD,iBAAiB;AACrB,CAAC;;AAID,SAAgB,eAAe,KAAyB;CACpD,OAAO,gBAAgB,MAAM,4BAA4B,GAAG,CAAC;AACjE;;;;;;;AAQA,SAAS,4BAA4B,KAAuB;CACxD,IAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU,OAAO;CACpD,MAAM,IAAI;CACV,MAAM,QAAQ,EAAE;CAChB,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU,OAAO;CACxD,MAAM,MAA+B,CAAC;CACtC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAgC,GACtE,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;EAC7C,MAAM,IAAI;EACV,IAAI,OAAO;GACP,GAAG;GACH,kBAAkB,EAAE,oBAAoB;GACxC,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,YAAY,MAAM;EACpE;CACJ,OACI,IAAI,OAAO;CAGnB,OAAO;EAAE,GAAG;EAAG,gBAAgB;CAAI;AACvC;;AAGA,SAAgB,sBAA+B;CAC3C,OAAO,EAAE,aAAa,iBAAiB,EAAE,QAAQ,gBAAgB,CAAC;AACtE"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { hubConfigJsonSchema, parseHubConfig } from "./config.js";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
//#region src/configFile.ts
|
|
4
|
+
/** Read and validate a hub config file. */
|
|
5
|
+
function loadHubConfig(configPath) {
|
|
6
|
+
let text;
|
|
7
|
+
try {
|
|
8
|
+
text = fs.readFileSync(configPath, "utf8");
|
|
9
|
+
} catch (error) {
|
|
10
|
+
throw new Error(`cannot read config '${configPath}': ${error.message}`);
|
|
11
|
+
}
|
|
12
|
+
let raw;
|
|
13
|
+
try {
|
|
14
|
+
raw = JSON.parse(text);
|
|
15
|
+
} catch (error) {
|
|
16
|
+
throw new Error(`invalid JSON in '${configPath}': ${error.message}`);
|
|
17
|
+
}
|
|
18
|
+
return parseHubConfig(raw);
|
|
19
|
+
}
|
|
20
|
+
/** The config JSON Schema, pretty-printed. */
|
|
21
|
+
function printHubConfigSchema() {
|
|
22
|
+
return JSON.stringify(hubConfigJsonSchema(), null, 2);
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { loadHubConfig, printHubConfigSchema };
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=configFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configFile.js","names":[],"sources":["../src/configFile.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport { type HubConfig, hubConfigJsonSchema, parseHubConfig } from './config';\n\n/** Read and validate a hub config file. */\nexport function loadHubConfig(configPath: string): HubConfig {\n let text: string;\n try {\n text = fs.readFileSync(configPath, 'utf8');\n } catch (error) {\n throw new Error(`cannot read config '${configPath}': ${(error as Error).message}`);\n }\n let raw: unknown;\n try {\n raw = JSON.parse(text);\n } catch (error) {\n throw new Error(`invalid JSON in '${configPath}': ${(error as Error).message}`);\n }\n return parseHubConfig(raw);\n}\n\n/** The config JSON Schema, pretty-printed. */\nexport function printHubConfigSchema(): string {\n return JSON.stringify(hubConfigJsonSchema(), null, 2);\n}\n"],"mappings":";;;;AAIA,SAAgB,cAAc,YAA+B;CACzD,IAAI;CACJ,IAAI;EACA,OAAO,GAAG,aAAa,YAAY,MAAM;CAC7C,SAAS,OAAO;EACZ,MAAM,IAAI,MAAM,uBAAuB,WAAW,KAAM,MAAgB,SAAS;CACrF;CACA,IAAI;CACJ,IAAI;EACA,MAAM,KAAK,MAAM,IAAI;CACzB,SAAS,OAAO;EACZ,MAAM,IAAI,MAAM,oBAAoB,WAAW,KAAM,MAAgB,SAAS;CAClF;CACA,OAAO,eAAe,GAAG;AAC7B;;AAGA,SAAgB,uBAA+B;CAC3C,OAAO,KAAK,UAAU,oBAAoB,GAAG,MAAM,CAAC;AACxD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { d as HubConfig, p as ListenerConfig } from "../chunks/config-BCvkg7jv.js";
|
|
2
|
+
import "../chunks/index-CLIUrV88.js";
|
|
3
|
+
import { Et as Hub } from "../chunks/hubConnectionAcceptor-BwydvFa4.js";
|
|
4
|
+
//#region src/engine/runHub.d.ts
|
|
5
|
+
interface RunHubOptions {
|
|
6
|
+
readonly config: HubConfig;
|
|
7
|
+
/** Sink for human log lines (child output, listener bindings). Default: stderr. */
|
|
8
|
+
readonly log?: (line: string) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Forward this process's stdin to the single `cmd-*` endpoint. Throws at
|
|
11
|
+
* startup when more than one `cmd-*` endpoint is configured.
|
|
12
|
+
*/
|
|
13
|
+
readonly cmdInteractive?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Log every JSON-RPC message routed through the hub to {@link log}, one
|
|
16
|
+
* coalesced flow per line (the same rendering as the VS Code "linkrpc
|
|
17
|
+
* Flows" channel). Off by default — when omitted the hub installs no
|
|
18
|
+
* transit observer and pays no cost.
|
|
19
|
+
*/
|
|
20
|
+
readonly logMessages?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** A bound listener, reported for logging / `serve` startup output. */
|
|
23
|
+
interface ListenerInfo {
|
|
24
|
+
readonly type: ListenerConfig['type'];
|
|
25
|
+
readonly address: string;
|
|
26
|
+
}
|
|
27
|
+
/** A running hub. Connect a local client via {@link controlEndpoint}. */
|
|
28
|
+
interface RunningHub {
|
|
29
|
+
readonly hub: Hub;
|
|
30
|
+
readonly listeners: readonly ListenerInfo[];
|
|
31
|
+
/** Private local socket (allow-all) for in-process CLI clients. */
|
|
32
|
+
readonly controlEndpoint: {
|
|
33
|
+
readonly path: string;
|
|
34
|
+
readonly token: string;
|
|
35
|
+
};
|
|
36
|
+
dispose(): void;
|
|
37
|
+
}
|
|
38
|
+
/** Build + start a hub from a config. Resolves once all transports are wired. */
|
|
39
|
+
declare function runHub(opts: RunHubOptions): Promise<RunningHub>;
|
|
40
|
+
//#endregion
|
|
41
|
+
export { ListenerInfo, RunHubOptions, RunningHub, runHub };
|
|
42
|
+
//# sourceMappingURL=runHub.d.ts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { Et as Hub, Tt as AttachedLink, _ as RootProvision, _t as RootOverlay, ct as createHubServiceInterfaces, gt as registerIdentityServices, ht as registerHubServices, n as HubConnectionAcceptor, v as anonymousHandler } from "../../chunks/hubConnectionAcceptor-BwydvFa4.js";
|
|
2
|
+
export { type AttachedLink, Hub, HubConnectionAcceptor, RootOverlay, type RootProvision, anonymousHandler, createHubServiceInterfaces, registerHubServices, registerIdentityServices };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { _ as RootOverlay, a as anonymousHandler, b as Hub, f as createHubServiceInterfaces, g as registerIdentityServices, h as registerHubServices, t as HubConnectionAcceptor } from "../../chunks/hubConnectionAcceptor-B5-8JsFY.js";
|
|
2
|
+
export { Hub, HubConnectionAcceptor, RootOverlay, anonymousHandler, createHubServiceInterfaces, registerHubServices, registerIdentityServices };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { C as validatePrefix, S as ForwardingTable, _ as withVerifiedSignature, a as IdentityKeystore, b as RegisteredServiceId, c as IdentitySnooze, d as SlotByIdAndTimeResult, f as SlotId, g as withFullyQualifiedCallGate, h as withForwardedCallGate, i as createSqliteIdentityKeystore, l as SlotAccessKey, m as ForwardedCallGateOptions, n as SqliteIdentityKeystoreOptions, o as IdentityKeystoreOptions, p as createIdentityKeystore, r as SqliteIdentitySlot, s as IdentitySlot, t as SqliteIdentityKeystore, u as SlotByIdAndKeyResult, v as MintCapabilityOptions, x as hubRegisterServiceId, y as mintCapability } from "../../chunks/index-CLIUrV88.js";
|
|
2
|
+
import { _ as formatFlowSummary, a as FlowSummary, c as TrafficFlowAggregator, d as TransitDisposition, f as TransitEndpoint, g as createFlowLogger, h as WireTapOptions, i as FlowStreamMessage, l as TransitAggregator, m as TransitKind, n as FlowLoggerOptions, o as NodeTransit, p as TransitError, r as FlowStatus, s as NodeTransitObserver, t as FlowLogger, u as TransitAggregatorOptions, v as tapTransport } from "../../chunks/nodeTransit-cmtZgdpW.js";
|
|
3
|
+
import { $ as AccessSlotRequest, A as AccessCallIntent, At as PendingRequestInfo, B as AccessRequestArgs, C as staticTokenHandler, Ct as HubTrafficSubscription, D as TokenIdentityBinding, Dt as HubOptions, E as MintedToken, Et as Hub, F as AccessDirectPermission, G as AccessDurationName, H as HubAccessHandlers, I as AccessDuration, J as ProposeArgs, K as CapabilityProposal, L as AccessExtendArgs, M as AccessDecision, N as AccessDirectArgs, O as TokenIdentityStore, Ot as IDisposable, P as AccessDirectDecision, Q as AccessSlotCandidate, R as AccessExtendDecision, S as resolveConnectionHandler, St as HubTrafficSource, T as registerConnectionTokenBinderService, Tt as AttachedLink, U as RegisterHubAccessOptions, V as AccessSlotBinding, W as registerHubAccessService, X as AccessInterfaceRequirement, Y as durationToExp, Z as AccessMemberRequirement, _ as RootProvision, _t as RootOverlay, a as PrefixPolicy, at as resolveAccessCandidates, b as fixedProvisionHandler, bt as OverlaySplitterInspection, c as ConnectionProvenance, ct as createHubServiceInterfaces, d as WithProvenance, dt as registerHubServiceIdRegistry, et as DirectoryEntry, f as WithProvenanceOptions, ft as withRequestIdContext, g as ConnectionHandlerFactory, gt as registerIdentityServices, h as ConnectionHandler, ht as registerHubServices, i as ClaimContext, it as fetchFullDirectory, j as AccessConsumer, k as TokenIdentityStoreOptions, kt as IHubLogger, l as ConnectionProvenanceProvider, lt as HubRegisterOptions, m as ConnectionContext, mt as RegisterIdentityServicesOptions, n as HubConnectionAcceptor, nt as ResolvedCandidates, o as PrincipalIdPrefixPolicy, ot as HubServices, p as withProvenance, pt as RegisterHubServicesOptions, q as CapabilityProposalIssuer, r as HubConnectionAcceptorOptions, rt as candidatesForSlot, s as PrincipalIdPrefixPolicyOptions, st as HubServicesOptions, t as HubAccessConfig, tt as ResolvedAccessSlot, u as ITransportWithProvenance, ut as RegisterCallContext, v as anonymousHandler, vt as RootOverlayOptions, w as RegisterConnectionTokenBinderOptions, wt as HubTrafficWatchOptions, x as provisionRoot, xt as HubInspector, y as boundTokenHandler, yt as OverlaySplitter, z as AccessExtendMember } from "../../chunks/hubConnectionAcceptor-BwydvFa4.js";
|
|
4
|
+
import { t as connectionTokenBinderInterface } from "../../chunks/connectionTokenBinder.interfaces-BhzQ1DTS.js";
|
|
5
|
+
export { type AccessCallIntent, type AccessConsumer, type AccessDecision, type AccessDirectArgs, type AccessDirectDecision, type AccessDirectPermission, type AccessDuration, type AccessDurationName, type AccessExtendArgs, type AccessExtendDecision, type AccessExtendMember, type AccessInterfaceRequirement, type AccessMemberRequirement, type AccessRequestArgs, type AccessSlotBinding, type AccessSlotCandidate, type AccessSlotRequest, type AttachedLink, type CapabilityProposal, CapabilityProposalIssuer, type ClaimContext, type ConnectionContext, type ConnectionHandler, type ConnectionHandlerFactory, type ConnectionProvenance, type ConnectionProvenanceProvider, type DirectoryEntry, type FlowLogger, type FlowLoggerOptions, type FlowStatus, type FlowStreamMessage, type FlowSummary, type ForwardedCallGateOptions, ForwardingTable, Hub, type HubAccessConfig, type HubAccessHandlers, HubConnectionAcceptor, type HubConnectionAcceptorOptions, HubInspector, type HubOptions, type HubRegisterOptions, type HubServices, type HubServicesOptions, type HubTrafficSource, type HubTrafficSubscription, type HubTrafficWatchOptions, type IDisposable, type IHubLogger, type ITransportWithProvenance, type IdentityKeystore, type IdentityKeystoreOptions, type IdentitySlot, type IdentitySnooze, type MintCapabilityOptions, type MintedToken, type NodeTransit, type NodeTransitObserver, OverlaySplitter, type OverlaySplitterInspection, type PendingRequestInfo, type PrefixPolicy, PrincipalIdPrefixPolicy, type PrincipalIdPrefixPolicyOptions, type ProposeArgs, type RegisterCallContext, type RegisterConnectionTokenBinderOptions, type RegisterHubAccessOptions, type RegisterHubServicesOptions, type RegisterIdentityServicesOptions, RegisteredServiceId, type ResolvedAccessSlot, type ResolvedCandidates, RootOverlay, type RootOverlayOptions, type RootProvision, type SlotAccessKey, type SlotByIdAndKeyResult, type SlotByIdAndTimeResult, type SlotId, type SqliteIdentityKeystore, type SqliteIdentityKeystoreOptions, type SqliteIdentitySlot, type TokenIdentityBinding, TokenIdentityStore, type TokenIdentityStoreOptions, TrafficFlowAggregator, TransitAggregator, type TransitAggregatorOptions, type TransitDisposition, type TransitEndpoint, type TransitError, type TransitKind, type WireTapOptions, type WithProvenance, type WithProvenanceOptions, anonymousHandler, boundTokenHandler, candidatesForSlot, connectionTokenBinderInterface, createFlowLogger, createHubServiceInterfaces, createIdentityKeystore, createSqliteIdentityKeystore, durationToExp, fetchFullDirectory, fixedProvisionHandler, formatFlowSummary, hubRegisterServiceId, mintCapability, provisionRoot, registerConnectionTokenBinderService, registerHubAccessService, registerHubServiceIdRegistry, registerHubServices, registerIdentityServices, resolveAccessCandidates, resolveConnectionHandler, staticTokenHandler, tapTransport, validatePrefix, withForwardedCallGate, withFullyQualifiedCallGate, withProvenance, withRequestIdContext, withVerifiedSignature };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { S as validatePrefix, _ as RootOverlay, a as anonymousHandler, b as Hub, c as provisionRoot, d as registerConnectionTokenBinderService, f as createHubServiceInterfaces, g as registerIdentityServices, h as registerHubServices, i as withVerifiedSignature, l as resolveConnectionHandler, m as withRequestIdContext, n as withForwardedCallGate, o as boundTokenHandler, p as registerHubServiceIdRegistry, r as withFullyQualifiedCallGate, s as fixedProvisionHandler, t as HubConnectionAcceptor, u as staticTokenHandler, v as OverlaySplitter, x as ForwardingTable, y as HubInspector } from "../../chunks/hubConnectionAcceptor-B5-8JsFY.js";
|
|
2
|
+
import { a as tapTransport, i as formatFlowSummary, n as TransitAggregator, r as createFlowLogger, t as TrafficFlowAggregator } from "../../chunks/nodeTransit-CWeFnbwt.js";
|
|
3
|
+
import { a as TokenIdentityStore, c as durationToExp, d as fetchFullDirectory, f as resolveAccessCandidates, i as withProvenance, l as mintCapability, m as hubRegisterServiceId, n as createSqliteIdentityKeystore, o as registerHubAccessService, p as RegisteredServiceId, r as PrincipalIdPrefixPolicy, s as CapabilityProposalIssuer, t as createIdentityKeystore, u as candidatesForSlot } from "../../chunks/server-BAxchQhy.js";
|
|
4
|
+
import { t as connectionTokenBinderInterface } from "../../chunks/connectionTokenBinder.interfaces-B-beCg06.js";
|
|
5
|
+
export { CapabilityProposalIssuer, ForwardingTable, Hub, HubConnectionAcceptor, HubInspector, OverlaySplitter, PrincipalIdPrefixPolicy, RegisteredServiceId, RootOverlay, TokenIdentityStore, TrafficFlowAggregator, TransitAggregator, anonymousHandler, boundTokenHandler, candidatesForSlot, connectionTokenBinderInterface, createFlowLogger, createHubServiceInterfaces, createIdentityKeystore, createSqliteIdentityKeystore, durationToExp, fetchFullDirectory, fixedProvisionHandler, formatFlowSummary, hubRegisterServiceId, mintCapability, provisionRoot, registerConnectionTokenBinderService, registerHubAccessService, registerHubServiceIdRegistry, registerHubServices, registerIdentityServices, resolveAccessCandidates, resolveConnectionHandler, staticTokenHandler, tapTransport, validatePrefix, withForwardedCallGate, withFullyQualifiedCallGate, withProvenance, withRequestIdContext, withVerifiedSignature };
|