@nylorun/runtime 0.16.0-beta → 0.19.0-beta
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/CHANGELOG.md +207 -0
- package/README.md +105 -63
- package/dist/adapters/execution/restate.d.ts +1 -3
- package/dist/adapters/execution/restate.js +4 -31
- package/dist/adapters/replication/pgoutput.js +1 -1
- package/dist/adapters/sandbox/local.js +1 -1
- package/dist/adapters/sandbox/virtual.js +1 -1
- package/dist/api/ag-ui/endpoint.js +1 -2
- package/dist/api/ag-ui/routes.d.ts +1 -1
- package/dist/api/ag-ui/routes.js +11 -13
- package/dist/api/ag-ui/translate.d.ts +1 -3
- package/dist/api/ag-ui/translate.js +2 -17
- package/dist/api/components.d.ts +4783 -2588
- package/dist/api/components.js +19 -21
- package/dist/api/gate/routes.d.ts +7 -8
- package/dist/api/gate/routes.js +58 -52
- package/dist/api/http/app.d.ts +6 -0
- package/dist/api/http/app.js +20 -14
- package/dist/api/http/define.d.ts +22 -13
- package/dist/api/http/define.js +43 -39
- package/dist/api/http/routes/access.d.ts +3 -19
- package/dist/api/http/routes/access.js +25 -184
- package/dist/api/http/routes/artifacts.js +3 -7
- package/dist/api/http/routes/files.d.ts +8 -0
- package/dist/api/http/routes/files.js +77 -0
- package/dist/api/http/routes/keys.d.ts +10 -0
- package/dist/api/http/routes/keys.js +64 -0
- package/dist/api/http/routes/me.d.ts +13 -0
- package/dist/api/http/routes/me.js +48 -0
- package/dist/api/http/routes/reads.d.ts +66 -0
- package/dist/api/http/routes/reads.js +127 -0
- package/dist/api/http/routes/sandboxes.d.ts +2 -2
- package/dist/api/http/routes/sandboxes.js +8 -7
- package/dist/api/http/routes/sessions.js +31 -20
- package/dist/api/http/routes/tenant.js +15 -18
- package/dist/api/http/routes/vaults.d.ts +13 -3
- package/dist/api/http/routes/vaults.js +136 -64
- package/dist/api/openapi.d.ts +10 -11
- package/dist/api/openapi.js +292 -68
- package/dist/artifacts/links.js +6 -6
- package/dist/artifacts/service.js +1 -1
- package/dist/core/flow-host.d.ts +44 -23
- package/dist/core/flow-host.js +88 -106
- package/dist/core/provider.d.ts +4 -1
- package/dist/core/provider.js +6 -1
- package/dist/core/sandbox-routes.d.ts +0 -9
- package/dist/core/sandbox-routes.js +2 -21
- package/dist/execution/memory.d.ts +4 -5
- package/dist/execution/memory.js +11 -25
- package/dist/execution/types.d.ts +3 -33
- package/dist/execution/types.js +2 -12
- package/dist/gates/http-tool.d.ts +86 -0
- package/dist/gates/http-tool.js +197 -0
- package/dist/gates/mcp-handler.d.ts +3 -0
- package/dist/gates/mcp-handler.js +6 -4
- package/dist/gates/meter.d.ts +2 -2
- package/dist/gates/meter.js +6 -0
- package/dist/gates/tenant-vaults.d.ts +19 -14
- package/dist/gates/tenant-vaults.js +17 -12
- package/dist/gates/tool-calls.d.ts +7 -15
- package/dist/gates/tool-calls.js +4 -4
- package/dist/gates/tool-client.d.ts +1 -1
- package/dist/gates/tool-client.js +23 -47
- package/dist/gates/tool-contract.d.ts +27 -39
- package/dist/gates/tool-contract.js +30 -21
- package/dist/gates/tool-gate.d.ts +25 -24
- package/dist/gates/tool-gate.js +11 -7
- package/dist/harness/calls.d.ts +10 -4
- package/dist/harness/calls.js +15 -6
- package/dist/harness/executors.d.ts +1 -1
- package/dist/harness/executors.js +17 -12
- package/dist/harness/main.d.ts +2 -2
- package/dist/harness/main.js +5 -13
- package/dist/harness/service.d.ts +4 -5
- package/dist/harness/service.js +9 -2
- package/dist/harness-api/in-process.js +2 -2
- package/dist/harness-api/record.d.ts +6 -3
- package/dist/harness-api/record.js +65 -72
- package/dist/harness-api/server.d.ts +1 -9
- package/dist/harness-api/server.js +19 -17
- package/dist/harness-api/start.js +1 -5
- package/dist/harness-api/workspace.js +2 -3
- package/dist/harness-api/ws-server.js +1 -1
- package/dist/host/app.d.ts +2 -10
- package/dist/host/app.js +24 -44
- package/dist/host/config-for.d.ts +5 -5
- package/dist/host/config-for.js +2 -3
- package/dist/host/config.d.ts +0 -11
- package/dist/host/create-host.d.ts +3 -40
- package/dist/host/create-host.js +18 -91
- package/dist/host/environment.d.ts +0 -3
- package/dist/host/environment.js +0 -9
- package/dist/host/gates.d.ts +4 -1
- package/dist/host/gates.js +9 -3
- package/dist/host/http.d.ts +1 -2
- package/dist/host/http.js +1 -7
- package/dist/host/index.d.ts +2 -2
- package/dist/host/index.js +2 -2
- package/dist/host/main.js +55 -40
- package/dist/host/operate.d.ts +29 -0
- package/dist/host/operate.js +223 -0
- package/dist/host/stack-config.d.ts +23 -20
- package/dist/host/stack-config.js +28 -44
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -1
- package/dist/infra/workers.d.ts +1 -1
- package/dist/keys/client.js +9 -1
- package/dist/keys/keys.d.ts +12 -2
- package/dist/keys/keys.js +10 -2
- package/dist/management-openapi.json +6491 -0
- package/dist/mcp/connect.d.ts +8 -4
- package/dist/mcp/connect.js +8 -27
- package/dist/mcp/pool.d.ts +6 -9
- package/dist/mcp/pool.js +8 -18
- package/dist/mcp/snapshot.d.ts +8 -2
- package/dist/mcp/snapshot.js +29 -2
- package/dist/media.d.ts +1 -1
- package/dist/media.js +1 -1
- package/dist/model/pi-model.js +3 -0
- package/dist/openapi.json +6228 -15615
- package/dist/reads/access.d.ts +4 -0
- package/dist/reads/access.js +12 -0
- package/dist/reads/cursor.d.ts +11 -0
- package/dist/reads/cursor.js +80 -0
- package/dist/reads/types.d.ts +25 -0
- package/dist/reads/types.js +1 -0
- package/dist/sandbox/manager.d.ts +16 -0
- package/dist/sandbox/manager.js +40 -0
- package/dist/sandbox/session-sandbox.js +13 -3
- package/dist/sandbox/skills.d.ts +13 -0
- package/dist/sandbox/skills.js +46 -0
- package/dist/sandbox/types.d.ts +2 -2
- package/dist/store/ownership.d.ts +9 -0
- package/dist/store/ownership.js +13 -0
- package/dist/store/postgres/connect.d.ts +2 -0
- package/dist/store/postgres/connect.js +29 -0
- package/dist/store/postgres/drizzle/0008_installation_vaults.sql +2 -0
- package/dist/store/postgres/drizzle/0009_oauth_pending.sql +19 -0
- package/dist/store/postgres/drizzle/0010_oss_auth_removals.sql +3 -0
- package/dist/store/postgres/drizzle/0011_key_roles.sql +3 -0
- package/dist/store/postgres/drizzle/0012_session_reads.sql +8 -0
- package/dist/store/postgres/drizzle/0013_definition_files.sql +16 -0
- package/dist/store/postgres/drizzle/0014_action_endpoints_removed.sql +2 -0
- package/dist/store/postgres/drizzle/meta/_journal.json +49 -0
- package/dist/store/postgres/reads.d.ts +3 -0
- package/dist/store/postgres/reads.js +272 -0
- package/dist/store/postgres/schema.d.ts +423 -594
- package/dist/store/postgres/schema.js +84 -101
- package/dist/store/postgres/store.js +96 -248
- package/dist/store/postgres/tenant.d.ts +34 -2
- package/dist/store/postgres/tenant.js +16 -32
- package/dist/store/types.d.ts +44 -119
- package/dist/store/types.js +0 -1
- package/dist/streams/control.d.ts +0 -7
- package/dist/streams/control.js +0 -13
- package/dist/streams/types.d.ts +2 -20
- package/dist/streams/types.js +1 -1
- package/dist/tenant/advance.d.ts +3 -3
- package/dist/tenant/advance.js +10 -7
- package/dist/tenant/auth.d.ts +24 -15
- package/dist/tenant/auth.js +44 -55
- package/dist/tenant/cause.d.ts +3 -3
- package/dist/tenant/cause.js +1 -1
- package/dist/tenant/commands.d.ts +2 -18
- package/dist/tenant/commands.js +38 -179
- package/dist/tenant/context.d.ts +33 -45
- package/dist/tenant/definition-files.d.ts +24 -0
- package/dist/tenant/definition-files.js +103 -0
- package/dist/tenant/effects.d.ts +20 -18
- package/dist/tenant/effects.js +59 -133
- package/dist/tenant/ephemeral.d.ts +21 -8
- package/dist/tenant/ephemeral.js +11 -12
- package/dist/tenant/host-token.js +5 -5
- package/dist/tenant/identity-file.d.ts +75 -0
- package/dist/tenant/identity-file.js +202 -0
- package/dist/tenant/issuers.d.ts +48 -0
- package/dist/tenant/issuers.js +311 -0
- package/dist/tenant/jwt.js +3 -3
- package/dist/tenant/module.d.ts +1 -4
- package/dist/tenant/module.js +3 -12
- package/dist/tenant/operator-keys.d.ts +44 -0
- package/dist/tenant/operator-keys.js +87 -0
- package/dist/tenant/outbound.d.ts +40 -1
- package/dist/tenant/outbound.js +167 -18
- package/dist/tenant/paths.d.ts +1 -1
- package/dist/tenant/paths.js +1 -3
- package/dist/tenant/principals.d.ts +13 -13
- package/dist/tenant/principals.js +35 -36
- package/dist/tenant/run-token.js +6 -6
- package/dist/tenant/runtime.d.ts +5 -3
- package/dist/tenant/runtime.js +29 -15
- package/dist/tenant/sandboxes.d.ts +9 -6
- package/dist/tenant/sandboxes.js +16 -5
- package/dist/tenant/scheduler.d.ts +1 -5
- package/dist/tenant/scheduler.js +2 -5
- package/dist/tenant/session-streams.d.ts +8 -11
- package/dist/tenant/session-streams.js +48 -32
- package/dist/tenant/session.d.ts +8 -41
- package/dist/tenant/session.js +0 -37
- package/dist/tenant/sessions.d.ts +2 -2
- package/dist/tenant/sessions.js +17 -9
- package/dist/tenant/signing-keys.d.ts +3 -2
- package/dist/tenant/signing-keys.js +5 -5
- package/dist/tenant/skill-tool.d.ts +20 -0
- package/dist/tenant/skill-tool.js +72 -0
- package/dist/tenant/slim.d.ts +1 -1
- package/dist/tenant/slim.js +1 -1
- package/dist/tenant/status.js +7 -12
- package/dist/tenant/store-pg.d.ts +15 -0
- package/dist/tenant/store-pg.js +7 -3
- package/dist/tenant/streams.d.ts +3 -11
- package/dist/tenant/streams.js +2 -29
- package/dist/tenant/sweep.js +0 -5
- package/dist/tenant/transcript.d.ts +2 -2
- package/dist/tenant/transcript.js +2 -2
- package/dist/tenant/types.d.ts +33 -19
- package/dist/tenant/worker.d.ts +1 -3
- package/dist/tenant/worker.js +3 -8
- package/dist/vault/crypto.d.ts +7 -0
- package/dist/vault/crypto.js +16 -0
- package/dist/vault/oauth.d.ts +55 -0
- package/dist/vault/oauth.js +186 -0
- package/dist/vault/service.d.ts +54 -7
- package/dist/vault/service.js +261 -17
- package/dist/vault/sources.d.ts +60 -0
- package/dist/vault/sources.js +196 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -4
- package/dist/admin-openapi.json +0 -604
- package/dist/api/http/routes/actions.d.ts +0 -8
- package/dist/api/http/routes/actions.js +0 -76
- package/dist/api/http/routes/endpoints.d.ts +0 -7
- package/dist/api/http/routes/endpoints.js +0 -100
- package/dist/host/admin-api.d.ts +0 -23
- package/dist/host/admin-api.js +0 -74
- package/dist/host/cors.d.ts +0 -27
- package/dist/host/cors.js +0 -64
- package/dist/mcp/stdio.d.ts +0 -17
- package/dist/mcp/stdio.js +0 -82
- package/dist/tenant/access-policy.d.ts +0 -30
- package/dist/tenant/access-policy.js +0 -52
- package/dist/tenant/actions.d.ts +0 -14
- package/dist/tenant/actions.js +0 -29
- package/dist/tenant/browser.d.ts +0 -15
- package/dist/tenant/browser.js +0 -39
- package/dist/tenant/delivery-token.d.ts +0 -41
- package/dist/tenant/delivery-token.js +0 -104
- package/dist/tenant/delivery.d.ts +0 -62
- package/dist/tenant/delivery.js +0 -481
- package/dist/tenant/endpoints.d.ts +0 -67
- package/dist/tenant/endpoints.js +0 -90
- package/dist/tenant/subject-limits.d.ts +0 -16
- package/dist/tenant/subject-limits.js +0 -45
- package/dist/tenant/tokens.d.ts +0 -14
- package/dist/tenant/tokens.js +0 -187
package/dist/host/app.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
2
|
import { RESPONSE_ALREADY_SENT } from "@hono/node-server/utils/response";
|
|
3
|
-
import { checkCompatibility, HOST_PROTOCOL, PROTOCOL_HEADER,
|
|
3
|
+
import { checkCompatibility, HOST_PROTOCOL, PROTOCOL_HEADER, TENANT_HEADER, } from "@nylorun/core/compatibility";
|
|
4
4
|
import { RUNTIME_VERSION } from "../version.js";
|
|
5
5
|
import { findTenantRoute } from "../api/http/app.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { adminKeyMatches, headerValue, isJsonContentType, jsonResponse, opaqueNotFoundResponse, protocolRejectedResponse, readBearer, pathnameIsLogged, redactRoutePath, rejectedResponse, requestHasBody, } from "./http.js";
|
|
6
|
+
import { managementDocument, runtimeDocument } from "../api/openapi.js";
|
|
7
|
+
import { headerValue, isJsonContentType, jsonResponse, opaqueNotFoundResponse, protocolRejectedResponse, pathnameIsLogged, redactRoutePath, rejectedResponse, requestHasBody, } from "./http.js";
|
|
9
8
|
export function createHostApp(options) {
|
|
10
9
|
const { module, logger } = options;
|
|
11
10
|
const app = new Hono();
|
|
@@ -27,20 +26,16 @@ export function createHostApp(options) {
|
|
|
27
26
|
}
|
|
28
27
|
});
|
|
29
28
|
app.use(async (c, next) => {
|
|
30
|
-
const { incoming
|
|
29
|
+
const { incoming } = c.env;
|
|
31
30
|
if (headerValue(incoming, "origin") !== undefined) {
|
|
32
|
-
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
const tenantRoute = route[0] === "v1" && route[1] !== "admin";
|
|
36
|
-
// The operator listener never serves browsers.
|
|
37
|
-
if (!options.browserAccess || role === "operator" || !tenantRoute)
|
|
31
|
+
// Only Tenant routes; the Tenant then accepts only a trusted issuer's token from a
|
|
32
|
+
// browser.
|
|
33
|
+
if (pathnameOf(incoming).split("/").filter(Boolean)[0] !== "v1")
|
|
38
34
|
return rejectedResponse(403, "origin_rejected", "Browser Origin headers are not accepted");
|
|
39
|
-
if (incoming.method === "OPTIONS") {
|
|
40
|
-
c.set("status", answerPreflight(incoming, outgoing, route, browserRoute));
|
|
41
|
-
return RESPONSE_ALREADY_SENT;
|
|
42
|
-
}
|
|
43
35
|
}
|
|
36
|
+
// CORS is the operator's proxy's: an OPTIONS request gets no CORS header.
|
|
37
|
+
if (incoming.method === "OPTIONS")
|
|
38
|
+
return new Response(null, { status: 204, headers: { allow: ALLOWED_METHODS } });
|
|
44
39
|
await next();
|
|
45
40
|
});
|
|
46
41
|
app.use(async (c, next) => {
|
|
@@ -53,7 +48,7 @@ export function createHostApp(options) {
|
|
|
53
48
|
await next();
|
|
54
49
|
});
|
|
55
50
|
app.all("*", async (c) => {
|
|
56
|
-
const { incoming, outgoing
|
|
51
|
+
const { incoming, outgoing } = c.env;
|
|
57
52
|
const url = new URL(incoming.url ?? "/", "http://runtime.local");
|
|
58
53
|
const pathname = url.pathname;
|
|
59
54
|
if (pathname === "/health")
|
|
@@ -75,32 +70,20 @@ export function createHostApp(options) {
|
|
|
75
70
|
const tenant = module.ready;
|
|
76
71
|
const infra = await options.readiness?.();
|
|
77
72
|
const ready = listener && tenant && !options.closing() && (infra?.ok ?? true);
|
|
73
|
+
const harness = module.harnessStatus();
|
|
78
74
|
return jsonResponse(ready ? 200 : 503, {
|
|
79
75
|
status: ready ? "ready" : "not_ready",
|
|
80
76
|
service: "nylorun-runtime",
|
|
81
77
|
checks: { listener, tenant, ...infra?.checks },
|
|
78
|
+
...(harness ? { harness: { mode: harness.mode, connected: harness.connected } } : {}),
|
|
82
79
|
});
|
|
83
80
|
}
|
|
84
|
-
//
|
|
85
|
-
if (pathname === "/openapi.json" && incoming.method === "GET")
|
|
86
|
-
return jsonResponse(200,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (role === "public")
|
|
91
|
-
return opaqueNotFoundResponse();
|
|
92
|
-
if (!protocolAccepted(headerValue(incoming, PROTOCOL_HEADER)))
|
|
93
|
-
return protocolRejectedResponse();
|
|
94
|
-
const token = readBearer(headerValue(incoming, "authorization"));
|
|
95
|
-
if (!adminKeyMatches(token, options.adminKey))
|
|
96
|
-
return opaqueNotFoundResponse();
|
|
97
|
-
return await options.admin(c.req.raw, { incoming, outgoing });
|
|
98
|
-
}
|
|
99
|
-
// Tenant routes: key pattern → protocol → the Tenant → selection → the Tenant's routes.
|
|
100
|
-
const keyHeader = headerValue(incoming, PUBLISHABLE_KEY_HEADER);
|
|
101
|
-
const keyTenant = keyHeader === undefined ? undefined : tenantOfPublishableKey(keyHeader);
|
|
102
|
-
if (keyHeader !== undefined && keyTenant === undefined)
|
|
103
|
-
return rejectedResponse(400, "invalid_request", `${PUBLISHABLE_KEY_HEADER} header is malformed`);
|
|
81
|
+
// The two APIs' descriptions: public, as the npm package that ships them.
|
|
82
|
+
if ((pathname === "/openapi.json" || pathname === "/openapi/runtime.json") && incoming.method === "GET")
|
|
83
|
+
return jsonResponse(200, runtimeDocument(), { "cache-control": "no-cache" });
|
|
84
|
+
if (pathname === "/openapi/management.json" && incoming.method === "GET")
|
|
85
|
+
return jsonResponse(200, managementDocument(), { "cache-control": "no-cache" });
|
|
86
|
+
// Tenant routes: protocol → the Tenant → selection → the Tenant's routes.
|
|
104
87
|
const tenantHeader = headerValue(incoming, TENANT_HEADER);
|
|
105
88
|
const named = tenantHeader === undefined || tenantHeader.trim() === "" ? undefined : tenantHeader.trim();
|
|
106
89
|
const protocol = headerValue(incoming, PROTOCOL_HEADER);
|
|
@@ -119,9 +102,8 @@ export function createHostApp(options) {
|
|
|
119
102
|
}
|
|
120
103
|
const { handle } = resolution;
|
|
121
104
|
const tenantId = handle.envelope.id;
|
|
122
|
-
// A protocol 4 client names the Tenant
|
|
123
|
-
|
|
124
|
-
if ((named !== undefined && named !== tenantId) || (keyTenant !== undefined && keyTenant !== tenantId))
|
|
105
|
+
// A protocol 4 client names the Tenant: naming another reached the wrong installation.
|
|
106
|
+
if (named !== undefined && named !== tenantId)
|
|
125
107
|
return opaqueNotFoundResponse();
|
|
126
108
|
c.set("tenantId", tenantId);
|
|
127
109
|
return await handle.fetch(c.req.raw, { incoming, outgoing });
|
|
@@ -154,10 +136,8 @@ export function createHostApp(options) {
|
|
|
154
136
|
});
|
|
155
137
|
return app;
|
|
156
138
|
}
|
|
157
|
-
/**
|
|
158
|
-
|
|
159
|
-
return findTenantRoute(method, segments)?.browser === true;
|
|
160
|
-
}
|
|
139
|
+
/** The methods the Runtime serves, for an `OPTIONS` answer's `Allow`. */
|
|
140
|
+
const ALLOWED_METHODS = "GET, POST, PUT, DELETE, OPTIONS";
|
|
161
141
|
/** The Tenant route a request names, if any; a malformed path names none. */
|
|
162
142
|
function tenantRouteOf(incoming) {
|
|
163
143
|
const segments = [];
|
|
@@ -169,7 +149,7 @@ function tenantRouteOf(incoming) {
|
|
|
169
149
|
return undefined;
|
|
170
150
|
}
|
|
171
151
|
}
|
|
172
|
-
if (segments[0] !== "v1"
|
|
152
|
+
if (segments[0] !== "v1")
|
|
173
153
|
return undefined;
|
|
174
154
|
return findTenantRoute(incoming.method ?? "GET", segments);
|
|
175
155
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { HostConfigFile } from "./config.js";
|
|
2
1
|
import type { Logger, TenantConfig } from "../tenant/types.js";
|
|
3
2
|
/**
|
|
4
3
|
* Builds the TenantConfig of the Host's Tenant for `openTenantRuntime`.
|
|
@@ -7,13 +6,14 @@ import type { Logger, TenantConfig } from "../tenant/types.js";
|
|
|
7
6
|
*/
|
|
8
7
|
export declare function configForFactory(options: {
|
|
9
8
|
hostRoot: string;
|
|
10
|
-
hostConfig: HostConfigFile;
|
|
11
9
|
logger: Logger;
|
|
12
|
-
/** Allowlisted baseline from `baselineEnvironment` (built in `host/main.ts`). */
|
|
13
|
-
baseline: Readonly<Record<string, string>>;
|
|
14
10
|
mode?: TenantConfig["mode"];
|
|
15
11
|
/** Override model; default vault. Fixture/scripted require ephemeral/test mode. */
|
|
16
12
|
model?: TenantConfig["model"];
|
|
17
|
-
/** How Tenants may call
|
|
13
|
+
/** How Tenants may call MCP servers and HTTP tools (`StackConfig.delivery`). */
|
|
18
14
|
delivery?: TenantConfig["delivery"];
|
|
15
|
+
/** The trusted issuers of the identity file (`NYLORUN_IDENTITY_FILE`). */
|
|
16
|
+
issuers?: TenantConfig["issuers"];
|
|
17
|
+
/** `NYLORUN_PUBLIC_URL`: the base of the MCP OAuth callback (F9 C2). */
|
|
18
|
+
publicUrl?: string;
|
|
19
19
|
}): (id: string) => TenantConfig;
|
package/dist/host/config-for.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { tenantPaths } from "../tenant/paths.js";
|
|
2
|
-
import { tenantChildEnvironment } from "./environment.js";
|
|
3
2
|
/**
|
|
4
3
|
* Builds the TenantConfig of the Host's Tenant for `openTenantRuntime`.
|
|
5
4
|
* The sandbox backend here is the Host default; a Tenant's seeded `sandbox.backend`
|
|
6
5
|
* setting overrides it when the Tenant opens (I1, A18).
|
|
7
6
|
*/
|
|
8
7
|
export function configForFactory(options) {
|
|
9
|
-
const { baseline } = options;
|
|
10
8
|
return (id) => {
|
|
11
9
|
const tenant = tenantPaths(options.hostRoot);
|
|
12
10
|
const sandboxBackend = "auto";
|
|
@@ -17,7 +15,8 @@ export function configForFactory(options) {
|
|
|
17
15
|
sandbox: { backend: sandboxBackend },
|
|
18
16
|
model: options.model ?? { kind: "vault" },
|
|
19
17
|
...(options.delivery ? { delivery: options.delivery } : {}),
|
|
20
|
-
|
|
18
|
+
...(options.issuers ? { issuers: options.issuers } : {}),
|
|
19
|
+
...(options.publicUrl ? { publicUrl: options.publicUrl } : {}),
|
|
21
20
|
logger: {
|
|
22
21
|
info: (message, fields) => options.logger.info(message, { tenantId: id, ...fields }),
|
|
23
22
|
warn: (message, fields) => options.logger.warn(message, { tenantId: id, ...fields }),
|
package/dist/host/config.d.ts
CHANGED
|
@@ -4,17 +4,6 @@ export interface HostConfigFile {
|
|
|
4
4
|
host: string;
|
|
5
5
|
port: number;
|
|
6
6
|
allowNonLoopback?: boolean;
|
|
7
|
-
/**
|
|
8
|
-
* Whether browser requests (an `Origin` with a publishable key) may reach Tenant routes.
|
|
9
|
-
* Default off for a Host started from host.json; container mode reads
|
|
10
|
-
* `NYLORUN_BROWSER_ACCESS` instead.
|
|
11
|
-
*/
|
|
12
|
-
browserAccess?: boolean;
|
|
13
|
-
/**
|
|
14
|
-
* The operator listener's port: the Admin API moves there (on `host`, loopback only), and
|
|
15
|
-
* `port` serves the Tenant API alone. Absent: one port serves both.
|
|
16
|
-
*/
|
|
17
|
-
adminPort?: number;
|
|
18
7
|
proxy?: {
|
|
19
8
|
httpsProxy?: string;
|
|
20
9
|
noProxy?: string;
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import type { Logger, TenantModule } from "../tenant/types.js";
|
|
2
|
-
import type { HostConfigFile
|
|
2
|
+
import type { HostConfigFile } from "./config.js";
|
|
3
3
|
import type { ContainerListen } from "./stack-config.js";
|
|
4
4
|
export interface CreateHostOptions {
|
|
5
5
|
hostRoot: string;
|
|
6
6
|
module: TenantModule;
|
|
7
7
|
config: HostConfigFile;
|
|
8
|
-
credentials: HostCredentialsFile;
|
|
9
8
|
logger: Logger;
|
|
10
9
|
/** Diagnostic package version of `@nylorun/core` for `/health`. */
|
|
11
10
|
coreVersion: string;
|
|
12
|
-
/** Process id reported by `/health
|
|
11
|
+
/** Process id reported by `/health`. Defaults to `process.pid`. */
|
|
13
12
|
pid?: number;
|
|
14
13
|
/**
|
|
15
14
|
* Container mode: bind this address and port instead of host.json's, and
|
|
@@ -17,26 +16,6 @@ export interface CreateHostOptions {
|
|
|
17
16
|
* loopback-only rule). host.json then describes the client-facing address.
|
|
18
17
|
*/
|
|
19
18
|
listen?: ContainerListen;
|
|
20
|
-
/**
|
|
21
|
-
* The client-facing URL `/v1/admin/status` reports as `host.url`
|
|
22
|
-
* (`NYLORUN_PUBLIC_URL`). Defaults to the bound address, which in container
|
|
23
|
-
* mode is `http://0.0.0.0:4000`.
|
|
24
|
-
*/
|
|
25
|
-
publicUrl?: string;
|
|
26
|
-
/**
|
|
27
|
-
* Browser access (Host feature `browser-access`): requests with an `Origin` may reach Tenant
|
|
28
|
-
* routes, where the publishable key's origin allowlist decides. Off by default: every
|
|
29
|
-
* `Origin` is `403 origin_rejected`, as before. Admin routes, `/health` and `/ready` refuse
|
|
30
|
-
* `Origin` either way.
|
|
31
|
-
*/
|
|
32
|
-
browserAccess?: boolean;
|
|
33
|
-
/**
|
|
34
|
-
* The operator listener: the Admin API (and the Tenant API, never with browser access) on
|
|
35
|
-
* its own address, kept off the network that reaches the Tenant API. When set, the main
|
|
36
|
-
* listener is public and answers admin routes with the opaque 404. Absent: one listener
|
|
37
|
-
* serves everything, as before.
|
|
38
|
-
*/
|
|
39
|
-
operator?: OperatorListen;
|
|
40
19
|
/**
|
|
41
20
|
* Infrastructure readiness (`infra/readiness.ts`). `/ready` adds its checks
|
|
42
21
|
* and answers 503 while it reports not ok. Default: the listener and the
|
|
@@ -48,7 +27,7 @@ export interface CreateHostOptions {
|
|
|
48
27
|
}>;
|
|
49
28
|
/**
|
|
50
29
|
* Shutdown steps around closing the Tenant. `close()` runs them whatever asked for it
|
|
51
|
-
* (SIGTERM in `host/main.ts
|
|
30
|
+
* (SIGTERM in `host/main.ts`): the listener stops, then
|
|
52
31
|
* `beforeTenants` (stop the Worker so no advance starts on the closing Tenant), the Tenant
|
|
53
32
|
* closes, then `afterTenants` (end the infrastructure clients). A failing step is logged
|
|
54
33
|
* and shutdown goes on.
|
|
@@ -58,27 +37,11 @@ export interface CreateHostOptions {
|
|
|
58
37
|
afterTenants?(): Promise<void>;
|
|
59
38
|
};
|
|
60
39
|
}
|
|
61
|
-
/** Where the operator listener binds, and the `Host` values it accepts. */
|
|
62
|
-
export interface OperatorListen {
|
|
63
|
-
host: string;
|
|
64
|
-
port: number;
|
|
65
|
-
/** Exact `Host` values (lowercase `name:port`); absent means the loopback forms of the port. */
|
|
66
|
-
allowedHosts?: readonly string[];
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* What a listener serves. `combined`: everything (one port). `public`: the Tenant API, with
|
|
70
|
-
* browser access when enabled; admin routes are the opaque 404. `operator`: the Admin API and
|
|
71
|
-
* the Tenant API, never to browsers.
|
|
72
|
-
*/
|
|
73
|
-
export type ListenerRole = "combined" | "public" | "operator";
|
|
74
40
|
export interface HostServer {
|
|
75
41
|
listen(): Promise<void>;
|
|
76
42
|
close(): Promise<void>;
|
|
77
43
|
/** Settles once `close()` has finished, whatever called it. */
|
|
78
44
|
readonly closed: Promise<void>;
|
|
79
45
|
readonly url: string;
|
|
80
|
-
/** Where the Admin API answers: the operator listener, or `url` when there is one listener. */
|
|
81
|
-
readonly adminUrl: string;
|
|
82
46
|
}
|
|
83
|
-
export { adminKeyMatches } from "./http.js";
|
|
84
47
|
export declare function createHost(options: CreateHostOptions): HostServer;
|
package/dist/host/create-host.js
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import { createServer, } from "node:http";
|
|
2
2
|
import { getRequestListener, RequestError } from "@hono/node-server";
|
|
3
|
-
import { HOST_PROTOCOL } from "@nylorun/core/compatibility";
|
|
4
|
-
import { AdminStatusSchema } from "@nylorun/core/contracts";
|
|
5
|
-
import { adminDocument } from "../api/openapi.js";
|
|
6
|
-
import { createAdminApi } from "./admin-api.js";
|
|
7
3
|
import { createHostApp } from "./app.js";
|
|
8
4
|
import { bindListener as bind, EXIT_NON_LOOPBACK, headerValue, HostListenError, isAllowedRequestHost, isLoopbackHost, pathnameIsLogged, redactRoutePath, rejectedResponse, sendRejected, } from "./http.js";
|
|
9
|
-
import { RUNTIME_VERSION } from "../version.js";
|
|
10
|
-
export { adminKeyMatches } from "./http.js";
|
|
11
5
|
export function createHost(options) {
|
|
12
|
-
const {
|
|
6
|
+
const { module, config, logger, coreVersion } = options;
|
|
13
7
|
const pid = options.pid ?? process.pid;
|
|
14
8
|
const containerListen = options.listen;
|
|
15
9
|
const bindHost = containerListen?.host ?? config.host;
|
|
@@ -17,52 +11,20 @@ export function createHost(options) {
|
|
|
17
11
|
let server;
|
|
18
12
|
let url = "";
|
|
19
13
|
let listenPort = bindPort;
|
|
20
|
-
const operator = options.operator;
|
|
21
|
-
let operatorServer;
|
|
22
|
-
let operatorPort = operator?.port ?? 0;
|
|
23
|
-
let adminUrl = "";
|
|
24
|
-
const mainRole = operator ? "public" : "combined";
|
|
25
14
|
let closing = false;
|
|
26
15
|
let closePromise;
|
|
27
|
-
const adminStatusBody = async () => {
|
|
28
|
-
const aggregate = await module.summarize();
|
|
29
|
-
return AdminStatusSchema.parse({
|
|
30
|
-
service: "nylorun-runtime",
|
|
31
|
-
version: RUNTIME_VERSION,
|
|
32
|
-
protocol: {
|
|
33
|
-
min: HOST_PROTOCOL.min,
|
|
34
|
-
max: HOST_PROTOCOL.max,
|
|
35
|
-
features: [...HOST_PROTOCOL.features],
|
|
36
|
-
},
|
|
37
|
-
tenant: module.tenant(),
|
|
38
|
-
aggregate,
|
|
39
|
-
host: {
|
|
40
|
-
hostId: config.hostId,
|
|
41
|
-
url: options.publicUrl ?? url,
|
|
42
|
-
pid,
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
};
|
|
46
|
-
const adminApi = createAdminApi({
|
|
47
|
-
status: adminStatusBody,
|
|
48
|
-
shutdown: () => void close(),
|
|
49
|
-
document: adminDocument,
|
|
50
|
-
});
|
|
51
16
|
const app = createHostApp({
|
|
52
17
|
module,
|
|
53
18
|
logger,
|
|
54
19
|
hostId: config.hostId,
|
|
55
|
-
adminKey: credentials.adminKey,
|
|
56
20
|
coreVersion,
|
|
57
21
|
pid,
|
|
58
|
-
browserAccess: options.browserAccess === true,
|
|
59
22
|
...(options.readiness ? { readiness: options.readiness } : {}),
|
|
60
|
-
listening: () => Boolean(server?.listening)
|
|
23
|
+
listening: () => Boolean(server?.listening),
|
|
61
24
|
closing: () => closing,
|
|
62
|
-
admin: async (request, node) => await adminApi.fetch(request, node),
|
|
63
25
|
});
|
|
64
|
-
/** Where
|
|
65
|
-
const pipeline = (
|
|
26
|
+
/** Where requests go once their `Host` header checks out. */
|
|
27
|
+
const pipeline = () => getRequestListener(async (request, node) => alreadySent(await app.fetch(request, node)), {
|
|
66
28
|
// The Runtime runs inside other processes (`startEphemeralRuntime`): leave their
|
|
67
29
|
// `Request` and `Response` alone.
|
|
68
30
|
overrideGlobalObjects: false,
|
|
@@ -76,30 +38,23 @@ export function createHost(options) {
|
|
|
76
38
|
return rejectedResponse(500, "internal_error", "Internal error");
|
|
77
39
|
},
|
|
78
40
|
});
|
|
79
|
-
/** The `Host` values
|
|
80
|
-
const hostAllowed = (
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
})
|
|
87
|
-
: isAllowedRequestHost(hostHeader, {
|
|
88
|
-
port: listenPort,
|
|
89
|
-
host: config.host,
|
|
90
|
-
allowNonLoopback: config.allowNonLoopback,
|
|
91
|
-
...(containerListen ? { allowedHosts: containerListen.allowedHosts } : {}),
|
|
92
|
-
});
|
|
41
|
+
/** The `Host` values the listener accepts. */
|
|
42
|
+
const hostAllowed = (hostHeader) => isAllowedRequestHost(hostHeader, {
|
|
43
|
+
port: listenPort,
|
|
44
|
+
host: config.host,
|
|
45
|
+
allowNonLoopback: config.allowNonLoopback,
|
|
46
|
+
...(containerListen ? { allowedHosts: containerListen.allowedHosts } : {}),
|
|
47
|
+
});
|
|
93
48
|
/** Responses not yet finished; shutdown ends the streams among them. */
|
|
94
49
|
const inFlight = new Set();
|
|
95
|
-
const serve = (
|
|
96
|
-
const next = pipeline(
|
|
50
|
+
const serve = () => {
|
|
51
|
+
const next = pipeline();
|
|
97
52
|
return (req, res) => {
|
|
98
53
|
const started = Date.now();
|
|
99
54
|
inFlight.add(res);
|
|
100
55
|
res.once("close", () => inFlight.delete(res));
|
|
101
56
|
// D§11: `Host` first, before anything reads the request.
|
|
102
|
-
if (hostAllowed(
|
|
57
|
+
if (hostAllowed(headerValue(req, "host")))
|
|
103
58
|
return void next(req, res);
|
|
104
59
|
sendRejected(res, 421, "host_rejected", "Host header is not an allowed loopback or configured address");
|
|
105
60
|
if (pathnameIsLogged(req.url))
|
|
@@ -123,39 +78,15 @@ export function createHost(options) {
|
|
|
123
78
|
!isLoopbackHost(config.host)) {
|
|
124
79
|
throw new HostListenError(`Refusing to bind non-loopback host ${config.host} without allowNonLoopback`, EXIT_NON_LOOPBACK);
|
|
125
80
|
}
|
|
126
|
-
|
|
127
|
-
throw new HostListenError(`Refusing to bind the operator listener on non-loopback host ${operator.host}`, EXIT_NON_LOOPBACK);
|
|
128
|
-
server = createServer(serve(mainRole));
|
|
81
|
+
server = createServer(serve());
|
|
129
82
|
await bindListener(server, bindPort, bindHost);
|
|
130
83
|
const address = server.address();
|
|
131
84
|
listenPort =
|
|
132
85
|
typeof address === "object" && address ? address.port : bindPort;
|
|
133
86
|
url = `http://${bindHost}:${listenPort}`;
|
|
134
|
-
|
|
135
|
-
if (operator) {
|
|
136
|
-
operatorServer = createServer(serve("operator"));
|
|
137
|
-
await bindListener(operatorServer, operator.port, operator.host).catch(async (error) => {
|
|
138
|
-
// Leave nothing half-open: the main listener closes too.
|
|
139
|
-
await new Promise((resolve) => server.close(() => resolve()));
|
|
140
|
-
server = undefined;
|
|
141
|
-
throw error;
|
|
142
|
-
});
|
|
143
|
-
const operatorAddress = operatorServer.address();
|
|
144
|
-
operatorPort =
|
|
145
|
-
typeof operatorAddress === "object" && operatorAddress
|
|
146
|
-
? operatorAddress.port
|
|
147
|
-
: operator.port;
|
|
148
|
-
adminUrl = `http://${operator.host}:${operatorPort}`;
|
|
149
|
-
}
|
|
150
|
-
// The Tenant opens once the listener is bound: `/ready` and `/v1/admin/status` answer
|
|
151
|
-
// while it opens, and say why when it cannot.
|
|
87
|
+
// The Tenant opens once the listener is bound: `/ready` answers while it opens.
|
|
152
88
|
await module.start();
|
|
153
|
-
logger.info("host_listening", {
|
|
154
|
-
hostId: config.hostId,
|
|
155
|
-
url,
|
|
156
|
-
...(operator ? { adminUrl } : {}),
|
|
157
|
-
pid,
|
|
158
|
-
});
|
|
89
|
+
logger.info("host_listening", { hostId: config.hostId, url, pid });
|
|
159
90
|
}
|
|
160
91
|
const step = async (name, run) => {
|
|
161
92
|
try {
|
|
@@ -178,7 +109,7 @@ export function createHost(options) {
|
|
|
178
109
|
closePromise = (async () => {
|
|
179
110
|
closing = true;
|
|
180
111
|
logger.info("host_shutdown", { hostId: config.hostId });
|
|
181
|
-
const listeners = [server
|
|
112
|
+
const listeners = server ? [server] : [];
|
|
182
113
|
const stopped = Promise.all(listeners.map((listening) => new Promise((resolve) => {
|
|
183
114
|
listening.close(() => resolve());
|
|
184
115
|
listening.closeIdleConnections();
|
|
@@ -211,7 +142,6 @@ export function createHost(options) {
|
|
|
211
142
|
await stopped;
|
|
212
143
|
}
|
|
213
144
|
server = undefined;
|
|
214
|
-
operatorServer = undefined;
|
|
215
145
|
await step("beforeTenants", options.shutdown?.beforeTenants);
|
|
216
146
|
await step("tenants", () => module.close());
|
|
217
147
|
await step("afterTenants", options.shutdown?.afterTenants);
|
|
@@ -225,9 +155,6 @@ export function createHost(options) {
|
|
|
225
155
|
get url() {
|
|
226
156
|
return url;
|
|
227
157
|
},
|
|
228
|
-
get adminUrl() {
|
|
229
|
-
return adminUrl;
|
|
230
|
-
},
|
|
231
158
|
};
|
|
232
159
|
}
|
|
233
160
|
/**
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { HostConfigFile } from "./config.js";
|
|
2
2
|
import type { HostPaths } from "../tenant/paths.js";
|
|
3
|
-
import type { TenantPaths } from "../tenant/types.js";
|
|
4
3
|
/**
|
|
5
4
|
* Allowlisted ambient keys for Host and Tenant child processes.
|
|
6
5
|
* `NODE_OPTIONS` is never copied.
|
|
@@ -9,5 +8,3 @@ export declare function baselineEnvironment(env: NodeJS.ProcessEnv | Readonly<Re
|
|
|
9
8
|
export type HostProcessPathInputs = Pick<HostPaths, "root" | "home" | "tmp">;
|
|
10
9
|
/** Environment for the Runtime Host process itself (CLI spawn / `runtime run`). */
|
|
11
10
|
export declare function hostProcessEnvironment(baseline: Readonly<Record<string, string>>, hostConfig: HostConfigFile, paths: HostProcessPathInputs): Record<string, string>;
|
|
12
|
-
/** Environment for Tenant-owned children (MCP stdio, sandboxes). */
|
|
13
|
-
export declare function tenantChildEnvironment(baseline: Readonly<Record<string, string>>, hostConfig: HostConfigFile, tenantPaths: TenantPaths): Record<string, string>;
|
package/dist/host/environment.js
CHANGED
|
@@ -42,12 +42,3 @@ export function hostProcessEnvironment(baseline, hostConfig, paths) {
|
|
|
42
42
|
NYLORUN_HOME: paths.root,
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
|
-
/** Environment for Tenant-owned children (MCP stdio, sandboxes). */
|
|
46
|
-
export function tenantChildEnvironment(baseline, hostConfig, tenantPaths) {
|
|
47
|
-
return {
|
|
48
|
-
...baseline,
|
|
49
|
-
...proxyEnv(hostConfig),
|
|
50
|
-
HOME: tenantPaths.home,
|
|
51
|
-
TMPDIR: tenantPaths.tmp,
|
|
52
|
-
};
|
|
53
|
-
}
|
package/dist/host/gates.d.ts
CHANGED
|
@@ -40,7 +40,10 @@ export interface StartGatesOptions {
|
|
|
40
40
|
readonly drainMs?: number;
|
|
41
41
|
/** How long keyed outcomes are kept, and how many (tests). */
|
|
42
42
|
readonly inflight?: InflightCallsOptions;
|
|
43
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* How the gate may call MCP servers and HTTP tools (`NYLORUN_ENDPOINT_*`).
|
|
45
|
+
* Default: no limits.
|
|
46
|
+
*/
|
|
44
47
|
readonly delivery?: OutboundPolicy;
|
|
45
48
|
/** How long an MCP connection may sit unused. Default `GATE_MCP_IDLE_MS`. */
|
|
46
49
|
readonly mcpIdleMs?: number;
|
package/dist/host/gates.js
CHANGED
|
@@ -17,6 +17,7 @@ import { createModelCallHandler } from "../gates/handler.js";
|
|
|
17
17
|
import { createInflightCalls } from "../gates/inflight.js";
|
|
18
18
|
import { createMcpHandler, GATE_MCP_IDLE_MS } from "../gates/mcp-handler.js";
|
|
19
19
|
import { createToolCalls } from "../gates/tool-calls.js";
|
|
20
|
+
import { gateHttpTools } from "../gates/http-tool.js";
|
|
20
21
|
import { existsSync } from "node:fs";
|
|
21
22
|
import { tenantPaths } from "../tenant/paths.js";
|
|
22
23
|
import { staleRun, verifyRunToken } from "../tenant/run-token.js";
|
|
@@ -34,7 +35,12 @@ export async function startGates(options) {
|
|
|
34
35
|
if (!vaults) {
|
|
35
36
|
if (!database || options.hostRoot === undefined)
|
|
36
37
|
throw new Error("startGates needs the Postgres pool and the Host root");
|
|
37
|
-
vaults = createTenantVaults({
|
|
38
|
+
vaults = createTenantVaults({
|
|
39
|
+
sql: database,
|
|
40
|
+
hostRoot: options.hostRoot,
|
|
41
|
+
...(gates.resolver ? { resolver: gates.resolver } : {}),
|
|
42
|
+
...(options.delivery ? { delivery: options.delivery } : {}),
|
|
43
|
+
});
|
|
38
44
|
}
|
|
39
45
|
const blobs = options.blobs ??
|
|
40
46
|
(options.hostRoot !== undefined
|
|
@@ -47,10 +53,10 @@ export async function startGates(options) {
|
|
|
47
53
|
logger,
|
|
48
54
|
idleMs: mcpIdleMs,
|
|
49
55
|
...(options.openMcp ? { open: options.openMcp } : {}),
|
|
56
|
+
...(options.delivery ? { delivery: options.delivery } : {}),
|
|
50
57
|
});
|
|
51
58
|
const toolCalls = createToolCalls({
|
|
52
59
|
vaults,
|
|
53
|
-
mcp,
|
|
54
60
|
logger,
|
|
55
61
|
...(options.inflight ? { inflight: options.inflight } : {}),
|
|
56
62
|
});
|
|
@@ -93,8 +99,8 @@ export async function startGates(options) {
|
|
|
93
99
|
},
|
|
94
100
|
...(options.maxBodyBytes !== undefined ? { maxBodyBytes: options.maxBodyBytes } : {}),
|
|
95
101
|
mcp,
|
|
102
|
+
http: gateHttpTools(vaults, options.delivery ?? {}, logger),
|
|
96
103
|
toolCalls,
|
|
97
|
-
delivery: options.delivery ?? {},
|
|
98
104
|
logger,
|
|
99
105
|
...(options.keys ? { keys: async () => (await vaults.open()).keys() } : {}),
|
|
100
106
|
});
|
package/dist/host/http.d.ts
CHANGED
|
@@ -48,11 +48,10 @@ export declare function pathnameIsLogged(rawUrl: string | undefined): boolean;
|
|
|
48
48
|
* (a credential) after `/v1/artifact-links/`.
|
|
49
49
|
*/
|
|
50
50
|
export declare function redactRoutePath(pathname: string): string;
|
|
51
|
-
/** Constant-time comparison of SHA-256 digests of
|
|
51
|
+
/** Constant-time comparison of SHA-256 digests of a presented and a stored secret. */
|
|
52
52
|
export declare function adminKeyMatches(presented: string | undefined, adminKey: string): boolean;
|
|
53
53
|
/** A request header's first value. */
|
|
54
54
|
export declare function headerValue(incoming: IncomingMessage, name: string): string | undefined;
|
|
55
|
-
export declare function readBearer(authorization: string | undefined): string | undefined;
|
|
56
55
|
/** A JSON request body, capped at `limit` bytes (413); `undefined` when there is none. */
|
|
57
56
|
export declare function readJsonBody(request: Request, limit?: number): Promise<unknown>;
|
|
58
57
|
export declare function isLoopbackHost(host: string): boolean;
|
package/dist/host/http.js
CHANGED
|
@@ -149,7 +149,7 @@ export function redactRoutePath(pathname) {
|
|
|
149
149
|
return "/v1/artifact-links/:token";
|
|
150
150
|
return pathname;
|
|
151
151
|
}
|
|
152
|
-
/** Constant-time comparison of SHA-256 digests of
|
|
152
|
+
/** Constant-time comparison of SHA-256 digests of a presented and a stored secret. */
|
|
153
153
|
export function adminKeyMatches(presented, adminKey) {
|
|
154
154
|
if (presented === undefined)
|
|
155
155
|
return false;
|
|
@@ -164,12 +164,6 @@ export function headerValue(incoming, name) {
|
|
|
164
164
|
return raw[0];
|
|
165
165
|
return raw;
|
|
166
166
|
}
|
|
167
|
-
export function readBearer(authorization) {
|
|
168
|
-
if (!authorization)
|
|
169
|
-
return undefined;
|
|
170
|
-
const match = /^Bearer\s+(\S+)/i.exec(authorization.trim());
|
|
171
|
-
return match?.[1];
|
|
172
|
-
}
|
|
173
167
|
/** A JSON request body, capped at `limit` bytes (413); `undefined` when there is none. */
|
|
174
168
|
export async function readJsonBody(request, limit = 1024 * 1024) {
|
|
175
169
|
if (request.body === null)
|
package/dist/host/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { HostConfigFile, HostCredentialsFile, } from "./config.js";
|
|
2
|
-
export { baselineEnvironment, hostProcessEnvironment,
|
|
3
|
-
export { createHost,
|
|
2
|
+
export { baselineEnvironment, hostProcessEnvironment, } from "./environment.js";
|
|
3
|
+
export { createHost, type CreateHostOptions, type HostServer } from "./create-host.js";
|
|
4
4
|
export { createHostLogger } from "./logger.js";
|
|
5
5
|
export { configForFactory } from "./config-for.js";
|
|
6
6
|
export { createHostExecution, type CreateHostExecutionOptions, type HostExecution, } from "./execution.js";
|
package/dist/host/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { baselineEnvironment, hostProcessEnvironment,
|
|
2
|
-
export { createHost
|
|
1
|
+
export { baselineEnvironment, hostProcessEnvironment, } from "./environment.js";
|
|
2
|
+
export { createHost } from "./create-host.js";
|
|
3
3
|
export { createHostLogger } from "./logger.js";
|
|
4
4
|
export { configForFactory } from "./config-for.js";
|
|
5
5
|
export { createHostExecution, } from "./execution.js";
|