stitchkit 0.110.5 → 0.110.6
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 +11 -0
- package/dist/agent-runtime/branch-observations.d.ts +16 -16
- package/dist/entrypoints/agent-runtime/coding-tools.js +2 -2
- package/dist/entrypoints/agent-runtime/sandbox.js +2 -2
- package/dist/entrypoints/agent-runtime/sqlite/bun.js +4 -4
- package/dist/entrypoints/agent-runtime/sqlite/node.js +4 -4
- package/dist/entrypoints/agent-runtime/testing.js +4 -4
- package/dist/entrypoints/agent-runtime.js +4 -4
- package/dist/entrypoints/process.js +1 -1
- package/dist/entrypoints/server.d.ts +1 -0
- package/dist/entrypoints/server.d.ts.map +1 -1
- package/dist/entrypoints/server.js +55 -3
- package/dist/{index-mpg1t7nv.js → index-0z3kfphz.js} +1 -1
- package/dist/{index-5pbtbce0.js → index-7c957abz.js} +1 -1
- package/dist/{index-e1sjcjfy.js → index-7r4knwf8.js} +94 -23
- package/dist/{index-bm180f2d.js → index-ey15wx6j.js} +1 -1
- package/dist/{index-9ket8wzx.js → index-mnk5vgdr.js} +1 -1
- package/dist/process/group-diagnostics.d.ts +20 -0
- package/dist/process/group-diagnostics.d.ts.map +1 -0
- package/dist/process/group-settlement.d.ts +1 -1
- package/dist/process/group-settlement.d.ts.map +1 -1
- package/dist/process/group.d.ts.map +1 -1
- package/dist/server/bun.d.ts +9 -0
- package/dist/server/bun.d.ts.map +1 -1
- package/dist/server/proxy-origin.d.ts +12 -0
- package/dist/server/proxy-origin.d.ts.map +1 -0
- package/llms/server.2.txt +131 -0
- package/llms/server.5.txt +1 -0
- package/llms/server.txt +55 -131
- package/llms-full.txt +56 -0
- package/llms.txt +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -15,6 +15,17 @@ additive**; the first breaking change landed in 0.10.0. Grep the file for
|
|
|
15
15
|
|
|
16
16
|
## [Unreleased]
|
|
17
17
|
|
|
18
|
+
## [0.110.6] - 2026-10-15
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- `stitchkit/server`: `createServer({ proxyOrigin: { trustedPeer } })` restores the external HTTP/HTTPS scheme from a single trusted ingress before fetch composition and routing. It validates the real TCP peer and one `X-Forwarded-Proto`, rejects competing URL headers, preserves wire Host/ports and native cancellation, peer lookup and WebSocket upgrade. `trustProxy` remains client-IP-only. The server surface grows by one configuration type, `ProxyOriginConfig`, owned by this entrypoint so the trust decision is explicit and independently testable (I8, I9, I12).
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- `stitchkit/process`: bounded process-group settlement observations remain readable through nested cleanup errors in Node CI, including up to 16 actual states, the group id, sample count and elapsed time. Observation failures retain their original cause. Cleanup deadlines and the definition of a live process are unchanged; these diagnostics do not claim to repair a historical native termination failure.
|
|
27
|
+
- `stitchkit/process`: stopping a process group repeats `SIGKILL` for members still confirmed alive within the original cleanup deadline. Fresh kernel absence ends further signals; dead-only, invalid and failed process observations never trigger a blind re-signal.
|
|
28
|
+
|
|
18
29
|
## [0.110.5] - 2026-10-15
|
|
19
30
|
|
|
20
31
|
### Added
|
|
@@ -25,20 +25,8 @@ export declare function branchObservation(ids: BranchIdentities, kind: string, r
|
|
|
25
25
|
delayMs?: number | undefined;
|
|
26
26
|
reason?: string | undefined;
|
|
27
27
|
} | {
|
|
28
|
-
|
|
29
|
-
phase: "intent";
|
|
30
|
-
runId: string;
|
|
31
|
-
id?: string | undefined;
|
|
32
|
-
} | {
|
|
33
|
-
effectName: string;
|
|
34
|
-
phase: "accepted";
|
|
28
|
+
stepName: string;
|
|
35
29
|
encoded: string;
|
|
36
|
-
via: "reconcile" | "run";
|
|
37
|
-
runId: string;
|
|
38
|
-
id?: string | undefined;
|
|
39
|
-
} | {
|
|
40
|
-
effectName: string;
|
|
41
|
-
phase: "uncertain";
|
|
42
30
|
runId: string;
|
|
43
31
|
id?: string | undefined;
|
|
44
32
|
} | {
|
|
@@ -53,15 +41,27 @@ export declare function branchObservation(ids: BranchIdentities, kind: string, r
|
|
|
53
41
|
id: string;
|
|
54
42
|
runId: string;
|
|
55
43
|
} | {
|
|
56
|
-
|
|
44
|
+
event: string;
|
|
45
|
+
id: string;
|
|
57
46
|
encoded: string;
|
|
58
47
|
runId: string;
|
|
48
|
+
} | {
|
|
49
|
+
effectName: string;
|
|
50
|
+
phase: "intent";
|
|
51
|
+
runId: string;
|
|
59
52
|
id?: string | undefined;
|
|
60
53
|
} | {
|
|
61
|
-
|
|
62
|
-
|
|
54
|
+
effectName: string;
|
|
55
|
+
phase: "accepted";
|
|
63
56
|
encoded: string;
|
|
57
|
+
via: "reconcile" | "run";
|
|
58
|
+
runId: string;
|
|
59
|
+
id?: string | undefined;
|
|
60
|
+
} | {
|
|
61
|
+
effectName: string;
|
|
62
|
+
phase: "uncertain";
|
|
64
63
|
runId: string;
|
|
64
|
+
id?: string | undefined;
|
|
65
65
|
} | {
|
|
66
66
|
bytes: number;
|
|
67
67
|
sha256?: string | undefined;
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
AgentCodingToolAuthorizationSchema2,
|
|
7
7
|
AgentCodingToolPathAuthorizationSchema2,
|
|
8
8
|
createAgentCodingTools2
|
|
9
|
-
} from "../../index-
|
|
9
|
+
} from "../../index-ey15wx6j.js";
|
|
10
10
|
import"../../index-2kbysk9s.js";
|
|
11
11
|
import"../../index-84bf5spd.js";
|
|
12
|
-
import"../../index-
|
|
12
|
+
import"../../index-7r4knwf8.js";
|
|
13
13
|
import"../../index-zrtrjkbf.js";
|
|
14
14
|
import"../../index-636mggad.js";
|
|
15
15
|
export {
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
missingSandboxRestrictions2,
|
|
4
4
|
codingRefusal,
|
|
5
5
|
createAgentCodingTools2
|
|
6
|
-
} from "../../index-
|
|
6
|
+
} from "../../index-ey15wx6j.js";
|
|
7
7
|
import"../../index-ct75c3at.js";
|
|
8
8
|
import"../../index-q6crhe1n.js";
|
|
9
9
|
import"../../index-fynr93w4.js";
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
nativeCommandOwner,
|
|
18
18
|
terminateOwnedGroup,
|
|
19
19
|
startNativeCommand
|
|
20
|
-
} from "../../index-
|
|
20
|
+
} from "../../index-7r4knwf8.js";
|
|
21
21
|
import"../../index-zrtrjkbf.js";
|
|
22
22
|
import {
|
|
23
23
|
MAX_TIMER_MS
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import"../../../index-jna0ejsa.js";
|
|
2
|
-
import"../../../index-
|
|
2
|
+
import"../../../index-0z3kfphz.js";
|
|
3
3
|
import"../../../index-8kzct1d6.js";
|
|
4
4
|
import {
|
|
5
5
|
initializeAgentRuntimeSqlite2,
|
|
6
6
|
createSqliteAgentRuntimeStore2
|
|
7
|
-
} from "../../../index-
|
|
7
|
+
} from "../../../index-7c957abz.js";
|
|
8
8
|
import"../../../index-kqnd6a85.js";
|
|
9
9
|
import"../../../index-5w6t91ze.js";
|
|
10
|
-
import"../../../index-
|
|
10
|
+
import"../../../index-ey15wx6j.js";
|
|
11
11
|
import"../../../index-ct75c3at.js";
|
|
12
12
|
import"../../../index-q6crhe1n.js";
|
|
13
13
|
import"../../../index-fynr93w4.js";
|
|
14
14
|
import"../../../index-2kbysk9s.js";
|
|
15
15
|
import"../../../index-84bf5spd.js";
|
|
16
|
+
import"../../../index-7r4knwf8.js";
|
|
16
17
|
import"../../../index-snef22zr.js";
|
|
17
|
-
import"../../../index-e1sjcjfy.js";
|
|
18
18
|
import"../../../index-zrtrjkbf.js";
|
|
19
19
|
import"../../../index-636mggad.js";
|
|
20
20
|
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import"../../../index-jna0ejsa.js";
|
|
2
|
-
import"../../../index-
|
|
2
|
+
import"../../../index-0z3kfphz.js";
|
|
3
3
|
import"../../../index-8kzct1d6.js";
|
|
4
4
|
import {
|
|
5
5
|
initializeAgentRuntimeSqlite2,
|
|
6
6
|
createSqliteAgentRuntimeStore2
|
|
7
|
-
} from "../../../index-
|
|
7
|
+
} from "../../../index-7c957abz.js";
|
|
8
8
|
import"../../../index-kqnd6a85.js";
|
|
9
9
|
import"../../../index-5w6t91ze.js";
|
|
10
|
-
import"../../../index-
|
|
10
|
+
import"../../../index-ey15wx6j.js";
|
|
11
11
|
import"../../../index-ct75c3at.js";
|
|
12
12
|
import"../../../index-q6crhe1n.js";
|
|
13
13
|
import"../../../index-fynr93w4.js";
|
|
14
14
|
import"../../../index-2kbysk9s.js";
|
|
15
15
|
import"../../../index-84bf5spd.js";
|
|
16
|
+
import"../../../index-7r4knwf8.js";
|
|
16
17
|
import"../../../index-snef22zr.js";
|
|
17
|
-
import"../../../index-e1sjcjfy.js";
|
|
18
18
|
import"../../../index-zrtrjkbf.js";
|
|
19
19
|
import"../../../index-636mggad.js";
|
|
20
20
|
|
|
@@ -10,18 +10,18 @@ import {
|
|
|
10
10
|
advanceToolChronology
|
|
11
11
|
} from "../../index-jna0ejsa.js";
|
|
12
12
|
import"../../index-5w6t91ze.js";
|
|
13
|
-
import"../../index-
|
|
14
|
-
import"../../index-
|
|
13
|
+
import"../../index-ey15wx6j.js";
|
|
14
|
+
import"../../index-0z3kfphz.js";
|
|
15
15
|
import"../../index-ct75c3at.js";
|
|
16
16
|
import"../../index-q6crhe1n.js";
|
|
17
17
|
import"../../index-fynr93w4.js";
|
|
18
18
|
import"../../index-2kbysk9s.js";
|
|
19
19
|
import"../../index-84bf5spd.js";
|
|
20
|
+
import"../../index-7r4knwf8.js";
|
|
20
21
|
import"../../index-snef22zr.js";
|
|
21
22
|
import {
|
|
22
23
|
createMemoryAgentRuntimeStore2
|
|
23
|
-
} from "../../index-
|
|
24
|
-
import"../../index-e1sjcjfy.js";
|
|
24
|
+
} from "../../index-mnk5vgdr.js";
|
|
25
25
|
import"../../index-zrtrjkbf.js";
|
|
26
26
|
import {
|
|
27
27
|
assertPositiveSafeInteger
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
missingSandboxRestrictions2,
|
|
6
6
|
recordAgentSandboxProbe2,
|
|
7
7
|
refuseUnknownSpillReference
|
|
8
|
-
} from "../index-
|
|
8
|
+
} from "../index-ey15wx6j.js";
|
|
9
9
|
import {
|
|
10
10
|
AgentRecordIdSchema2,
|
|
11
11
|
AgentRecordVersionSchema2,
|
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
AgentHistoryMutationSchema2,
|
|
59
59
|
ACTIVE_AGENT_RUN_STATES2,
|
|
60
60
|
createAgentRuntimeStore2
|
|
61
|
-
} from "../index-
|
|
61
|
+
} from "../index-0z3kfphz.js";
|
|
62
62
|
import {
|
|
63
63
|
AgentStoreEventKindSchema2,
|
|
64
64
|
AgentStoreEventEnvelopeSchema2,
|
|
@@ -188,13 +188,13 @@ import {
|
|
|
188
188
|
import"../index-56yx8dxp.js";
|
|
189
189
|
import"../index-2kbysk9s.js";
|
|
190
190
|
import"../index-84bf5spd.js";
|
|
191
|
+
import"../index-7r4knwf8.js";
|
|
191
192
|
import {
|
|
192
193
|
createMemoryAgentRuntimeStore2
|
|
193
|
-
} from "../index-
|
|
194
|
+
} from "../index-mnk5vgdr.js";
|
|
194
195
|
import {
|
|
195
196
|
createAgentRuntimeEventSink2
|
|
196
197
|
} from "../index-616xh7f2.js";
|
|
197
|
-
import"../index-e1sjcjfy.js";
|
|
198
198
|
import"../index-zrtrjkbf.js";
|
|
199
199
|
import {
|
|
200
200
|
MAX_TIMER_MS
|
|
@@ -23,6 +23,7 @@ export { createTrustFence, isLoopbackAddress, type TrustFence, type TrustFenceCo
|
|
|
23
23
|
export { type MultipartLifecycle, type MultipartResult, parseMultipart, } from '../server/multipart.js';
|
|
24
24
|
export { generateOpenApiDocument, type OpenApiConfig, type OpenApiDocument, type OpenApiInfo, type OpenApiServer, openApiRoute, } from '../server/openapi.js';
|
|
25
25
|
export { bindProcessSignals, type ProcessSignalName, type ProcessSignalsBinding, type ProcessSignalsErrorPhase, type ProcessSignalsOptions, type ShutdownTarget, type SignalSource, } from '../server/process-signals.js';
|
|
26
|
+
export type { ProxyOriginConfig } from '../server/proxy-origin.js';
|
|
26
27
|
export { createRateLimiter, type RateLimitConfig } from '../server/rate-limit.js';
|
|
27
28
|
export { errorResponse, parseBody, respondJson } from '../server/raw.js';
|
|
28
29
|
export { bindRealtimeServer, type RealtimeServer, type RealtimeServerConnection, type RealtimeServerHandle, } from '../server/realtime.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/entrypoints/server.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/entrypoints/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -335,6 +335,53 @@ function bindSocketRegistry(server, options) {
|
|
|
335
335
|
}
|
|
336
336
|
// src/server/bun.ts
|
|
337
337
|
import { chmodSync, statSync, unlinkSync } from "node:fs";
|
|
338
|
+
|
|
339
|
+
// src/server/proxy-origin.ts
|
|
340
|
+
import { z } from "zod";
|
|
341
|
+
var ProtocolSchema = z.enum(["http", "https"]);
|
|
342
|
+
var AuthoritySchema = z.string().min(1).max(1024).regex(/^[^\s/\\?#@,;]+$/);
|
|
343
|
+
var conflictingHeaders = ["forwarded", "x-forwarded-host", "x-forwarded-port"];
|
|
344
|
+
function createProxyOrigin(policy) {
|
|
345
|
+
const originals = new WeakMap;
|
|
346
|
+
const original = (request) => originals.get(request) ?? request;
|
|
347
|
+
return {
|
|
348
|
+
bind(server) {
|
|
349
|
+
const requestIP = server.requestIP.bind(server);
|
|
350
|
+
const timeout = server.timeout.bind(server);
|
|
351
|
+
const upgrade = server.upgrade.bind(server);
|
|
352
|
+
server.requestIP = (request) => requestIP(original(request));
|
|
353
|
+
server.timeout = (request, seconds) => timeout(original(request), seconds);
|
|
354
|
+
server.upgrade = (request, options) => upgrade(original(request), options);
|
|
355
|
+
},
|
|
356
|
+
normalize(request, server) {
|
|
357
|
+
const peer = server.requestIP(request)?.address;
|
|
358
|
+
if (!peer || !policy.trustedPeer(peer))
|
|
359
|
+
return request;
|
|
360
|
+
const protocol = ProtocolSchema.safeParse(request.headers.get("x-forwarded-proto"));
|
|
361
|
+
const authority = AuthoritySchema.safeParse(request.headers.get("host"));
|
|
362
|
+
if (!protocol.success || !authority.success || conflictingHeaders.some((name) => request.headers.has(name))) {
|
|
363
|
+
return new Response("Invalid proxy origin", { status: 400 });
|
|
364
|
+
}
|
|
365
|
+
let origin;
|
|
366
|
+
try {
|
|
367
|
+
origin = new URL(`${protocol.data}://${authority.data}`);
|
|
368
|
+
} catch {
|
|
369
|
+
return new Response("Invalid proxy origin", { status: 400 });
|
|
370
|
+
}
|
|
371
|
+
const url = new URL(request.url);
|
|
372
|
+
url.protocol = origin.protocol;
|
|
373
|
+
url.host = origin.host;
|
|
374
|
+
url.port = origin.port;
|
|
375
|
+
if (url.href === request.url)
|
|
376
|
+
return request;
|
|
377
|
+
const normalized = new Request(url, request);
|
|
378
|
+
originals.set(normalized, request);
|
|
379
|
+
return normalized;
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// src/server/bun.ts
|
|
338
385
|
function reclaimStaleUnixSocket(path) {
|
|
339
386
|
const stats = statSync(path, { throwIfNoEntry: false });
|
|
340
387
|
if (stats === undefined)
|
|
@@ -492,17 +539,21 @@ function createServer(config) {
|
|
|
492
539
|
const handler = createHandler2(config);
|
|
493
540
|
const consumerFetch = config.wrapFetch ? config.wrapFetch(handler) : handler;
|
|
494
541
|
const admittedFetch = lifecycle.wrapFetch(consumerFetch);
|
|
542
|
+
const proxyOrigin = config.proxyOrigin && createProxyOrigin(config.proxyOrigin);
|
|
495
543
|
const fetch = async (request, server) => {
|
|
544
|
+
const normalized = proxyOrigin && server ? proxyOrigin.normalize(request, server) : request;
|
|
545
|
+
if (normalized instanceof Response)
|
|
546
|
+
return normalized;
|
|
496
547
|
if (socket && socketRoutePrefix) {
|
|
497
|
-
const pathname = new URL(
|
|
548
|
+
const pathname = new URL(normalized.url).pathname;
|
|
498
549
|
if (pathname.startsWith(socketRoutePrefix)) {
|
|
499
|
-
return await socket.route.handler(
|
|
550
|
+
return await socket.route.handler(normalized, {
|
|
500
551
|
params: { socketPath: pathname.slice(socketRoutePrefix.length) },
|
|
501
552
|
server
|
|
502
553
|
});
|
|
503
554
|
}
|
|
504
555
|
}
|
|
505
|
-
return admittedFetch(
|
|
556
|
+
return admittedFetch(normalized, server);
|
|
506
557
|
};
|
|
507
558
|
if (unixPath !== undefined) {
|
|
508
559
|
reclaimStaleUnixSocket(unixPath);
|
|
@@ -538,6 +589,7 @@ function createServer(config) {
|
|
|
538
589
|
});
|
|
539
590
|
}
|
|
540
591
|
const server = runtime;
|
|
592
|
+
proxyOrigin?.bind(server);
|
|
541
593
|
return {
|
|
542
594
|
url: server.url.toString().replace(/\/$/, ""),
|
|
543
595
|
port: server.port ?? (unixPath !== undefined ? 0 : port),
|
|
@@ -23,6 +23,62 @@ import {
|
|
|
23
23
|
assertPositiveSafeInteger
|
|
24
24
|
} from "./index-0s4xebbg.js";
|
|
25
25
|
|
|
26
|
+
// src/process/group-diagnostics.ts
|
|
27
|
+
import { z } from "zod";
|
|
28
|
+
var ObservationSchema = z.object({
|
|
29
|
+
failure: z.enum(["deadline", "observation"]),
|
|
30
|
+
groupId: z.number().int().positive(),
|
|
31
|
+
observations: z.number().int().nonnegative(),
|
|
32
|
+
lastStates: z.array(z.string().max(32)).max(16),
|
|
33
|
+
elapsedMs: z.number().int().nonnegative()
|
|
34
|
+
});
|
|
35
|
+
var observations = new WeakMap;
|
|
36
|
+
|
|
37
|
+
class GroupSettlementError extends Error {
|
|
38
|
+
constructor(message, observation, cause = observation) {
|
|
39
|
+
super(`${message}: ${JSON.stringify(observation)}`, { cause });
|
|
40
|
+
observations.set(this, { ...observation, lastStates: [...observation.lastStates] });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function ownData(value, key) {
|
|
44
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
45
|
+
return descriptor && "value" in descriptor ? descriptor.value : undefined;
|
|
46
|
+
}
|
|
47
|
+
function groupSettlementDiagnostics(cause) {
|
|
48
|
+
const pending = [{ value: cause, depth: 0 }];
|
|
49
|
+
const seen = new Set;
|
|
50
|
+
const found = [];
|
|
51
|
+
for (let visited = 0;pending.length && visited < 32 && found.length < 4; visited++) {
|
|
52
|
+
const entry = pending.pop();
|
|
53
|
+
if (!entry || seen.has(entry.value))
|
|
54
|
+
continue;
|
|
55
|
+
seen.add(entry.value);
|
|
56
|
+
try {
|
|
57
|
+
if (entry.value instanceof Error) {
|
|
58
|
+
const observation = observations.get(entry.value);
|
|
59
|
+
if (observation)
|
|
60
|
+
found.push(observation);
|
|
61
|
+
}
|
|
62
|
+
if (!(entry.value instanceof Error) || entry.depth >= 8)
|
|
63
|
+
continue;
|
|
64
|
+
if (entry.value instanceof AggregateError) {
|
|
65
|
+
const errors = ownData(entry.value, "errors");
|
|
66
|
+
if (Array.isArray(errors)) {
|
|
67
|
+
for (let index = 0;index < 16; index++) {
|
|
68
|
+
const value = ownData(errors, String(index));
|
|
69
|
+
if (value !== undefined)
|
|
70
|
+
pending.push({ value, depth: entry.depth + 1 });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const nested = ownData(entry.value, "cause");
|
|
75
|
+
if (nested !== undefined)
|
|
76
|
+
pending.push({ value: nested, depth: entry.depth + 1 });
|
|
77
|
+
} catch {}
|
|
78
|
+
}
|
|
79
|
+
return found;
|
|
80
|
+
}
|
|
81
|
+
|
|
26
82
|
// src/process/group-presence.ts
|
|
27
83
|
function processGroupExists(pid) {
|
|
28
84
|
try {
|
|
@@ -57,36 +113,49 @@ function processGroups(timeoutMs) {
|
|
|
57
113
|
return new Promise((resolve, reject) => {
|
|
58
114
|
execFile("ps", ["-axo", "pgid=,stat="], { encoding: "utf8", timeout: timeoutMs, killSignal: "SIGKILL", maxBuffer: 1024 * 1024 }, (error, stdout) => {
|
|
59
115
|
if (error)
|
|
60
|
-
reject(
|
|
116
|
+
reject(error);
|
|
61
117
|
else
|
|
62
118
|
resolve(stdout);
|
|
63
119
|
});
|
|
64
120
|
});
|
|
65
121
|
}
|
|
66
|
-
async function waitForProcessGroupExit(pid, deadline) {
|
|
122
|
+
async function waitForProcessGroupExit(pid, deadline, killLiveMembers) {
|
|
67
123
|
if (pid === undefined)
|
|
68
124
|
return;
|
|
69
125
|
let observations = 0;
|
|
70
126
|
let lastStates = [];
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
127
|
+
const startedAt = performance.now();
|
|
128
|
+
const observation = () => ({
|
|
129
|
+
groupId: pid,
|
|
130
|
+
observations,
|
|
131
|
+
lastStates,
|
|
132
|
+
elapsedMs: Math.max(0, Math.ceil(performance.now() - startedAt))
|
|
133
|
+
});
|
|
134
|
+
try {
|
|
135
|
+
for (;; ) {
|
|
136
|
+
const remaining = Math.ceil(deadline - performance.now());
|
|
137
|
+
if (remaining <= 0)
|
|
138
|
+
throw new GroupSettlementError("Command process group settlement was not confirmed after SIGKILL", { ...observation(), failure: "deadline" });
|
|
139
|
+
if (!processGroupExists(pid))
|
|
140
|
+
return;
|
|
141
|
+
const table = await processGroups(remaining);
|
|
142
|
+
observations++;
|
|
143
|
+
if (!hasLiveGroupMember(table, pid))
|
|
144
|
+
return;
|
|
145
|
+
lastStates = table.split(/\r?\n/).flatMap((row) => {
|
|
146
|
+
const fields = /^\s*(\d+)\s+(\S+)\s*$/.exec(row);
|
|
147
|
+
return Number(fields?.[1]) === pid ? [(fields?.[2] ?? "unknown").slice(0, 32)] : [];
|
|
148
|
+
}).slice(0, 16);
|
|
149
|
+
if (!processGroupExists(pid))
|
|
150
|
+
return;
|
|
151
|
+
if (killLiveMembers && performance.now() < deadline && !await killLiveMembers())
|
|
152
|
+
return;
|
|
153
|
+
await sleep(Math.min(5, Math.max(0, deadline - performance.now())));
|
|
154
|
+
}
|
|
155
|
+
} catch (cause) {
|
|
156
|
+
if (cause instanceof GroupSettlementError)
|
|
157
|
+
throw cause;
|
|
158
|
+
throw new GroupSettlementError("Could not observe command process group settlement", { ...observation(), failure: "observation" }, cause);
|
|
90
159
|
}
|
|
91
160
|
}
|
|
92
161
|
|
|
@@ -151,7 +220,7 @@ async function killAndSettleGroup(pid, deadline, cleanupTimeoutMs) {
|
|
|
151
220
|
const cleanupDeadline = Math.min(deadline, performance.now() + cleanupTimeoutMs);
|
|
152
221
|
const signalled = await signalUntilSettled(pid, "SIGKILL", cleanupDeadline);
|
|
153
222
|
if (signalled)
|
|
154
|
-
await waitForProcessGroupExit(pid, cleanupDeadline);
|
|
223
|
+
await waitForProcessGroupExit(pid, cleanupDeadline, () => signalUntilSettled(pid, "SIGKILL", cleanupDeadline));
|
|
155
224
|
return signalled;
|
|
156
225
|
}
|
|
157
226
|
async function stopCommandGroup(stop) {
|
|
@@ -235,7 +304,9 @@ async function stopLeaderAlone(stop) {
|
|
|
235
304
|
return send("SIGKILL") || signalled;
|
|
236
305
|
}
|
|
237
306
|
function commandCleanupError(cause) {
|
|
238
|
-
|
|
307
|
+
const observations = groupSettlementDiagnostics(cause);
|
|
308
|
+
const message = observations.length ? `Command cleanup did not complete: ${JSON.stringify(observations)}` : "Command cleanup did not complete";
|
|
309
|
+
return new NativeCommandError2("COMMAND_CLEANUP", message, {
|
|
239
310
|
cause
|
|
240
311
|
});
|
|
241
312
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
declare const ObservationSchema: z.ZodObject<{
|
|
3
|
+
failure: z.ZodEnum<{
|
|
4
|
+
deadline: "deadline";
|
|
5
|
+
observation: "observation";
|
|
6
|
+
}>;
|
|
7
|
+
groupId: z.ZodNumber;
|
|
8
|
+
observations: z.ZodNumber;
|
|
9
|
+
lastStates: z.ZodArray<z.ZodString>;
|
|
10
|
+
elapsedMs: z.ZodNumber;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
type Observation = z.infer<typeof ObservationSchema>;
|
|
13
|
+
/** Only this internal error carries process-state diagnostics safe to promote. */
|
|
14
|
+
export declare class GroupSettlementError extends Error {
|
|
15
|
+
constructor(message: string, observation: Observation, cause?: unknown);
|
|
16
|
+
}
|
|
17
|
+
/** Bounded cause traversal; arbitrary caller messages never become cleanup diagnostics. */
|
|
18
|
+
export declare function groupSettlementDiagnostics(cause: unknown): Observation[];
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=group-diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group-diagnostics.d.ts","sourceRoot":"","sources":["../../src/process/group-diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,iBAAiB;;;;;;;;;iBAMrB,CAAC;AACH,KAAK,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAGrD,kFAAkF;AAClF,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,GAAE,OAAqB,EAKlF;CACF;AAQD,2FAA2F;AAC3F,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,EAAE,CA+BxE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** `killpg(..., 0)` also sees Linux zombies; only live members can still perform work. */
|
|
2
2
|
export declare function hasLiveGroupMember(table: string, group: number): boolean;
|
|
3
3
|
/** A delivered SIGKILL is asynchronous; do not report cleanup until every group member is dead. */
|
|
4
|
-
export declare function waitForProcessGroupExit(pid: number | undefined, deadline: number): Promise<void>;
|
|
4
|
+
export declare function waitForProcessGroupExit(pid: number | undefined, deadline: number, killLiveMembers?: () => Promise<boolean>): Promise<void>;
|
|
5
5
|
//# sourceMappingURL=group-settlement.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group-settlement.d.ts","sourceRoot":"","sources":["../../src/process/group-settlement.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"group-settlement.d.ts","sourceRoot":"","sources":["../../src/process/group-settlement.ts"],"names":[],"mappings":"AAKA,0FAA0F;AAC1F,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAQxE;AAgBD,mGAAmG;AACnG,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,QAAQ,EAAE,MAAM,EAChB,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GACvC,OAAO,CAAC,IAAI,CAAC,CAmDf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../../src/process/group.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,KAAK,6BAA6B,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../../src/process/group.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,KAAK,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAKpF,+FAA+F;AAC/F,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IAYpE,MAAM;IACN,MAAM;EAIT;AAeD,gGAAgG;AAChG,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CASpF;AAyCD,sGAAsG;AACtG,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,6BAA6B,CAAC;IAC/C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,gEAAgE;IAChE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAmB/E;AAED,gGAAgG;AAChG,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,gBAAgB,GAAG;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,GAC/E,OAAO,CAAC,OAAO,CAAC,CAsBlB;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,6BAA6B,CAAC;IACtC,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,OAAO,CAAC,CAyBnB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAQtE;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAMxF"}
|
package/dist/server/bun.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ProxyOriginConfig } from './proxy-origin.js';
|
|
1
2
|
import { type ManagedServerHandle } from './shutdown.js';
|
|
2
3
|
import type { SocketIOServerLifecycle } from './socket-io.js';
|
|
3
4
|
import type { FetchComposition, FetchHandler, HandlerConfig, RawRoute, RawRouteContext } from './types.js';
|
|
@@ -26,6 +27,14 @@ export type UnixListenConfig = string | {
|
|
|
26
27
|
};
|
|
27
28
|
/** Bun-specific server config layered over the Fetch-clean handler config. */
|
|
28
29
|
export interface BunServerConfig extends BunHandlerConfig, BunFetchComposition {
|
|
30
|
+
/**
|
|
31
|
+
* Restore the external scheme behind one trusted TCP ingress, before composition.
|
|
32
|
+
* The ingress must overwrite Host and X-Forwarded-Proto and remove Forwarded,
|
|
33
|
+
* X-Forwarded-Host and X-Forwarded-Port. Trusted requests require exactly one
|
|
34
|
+
* `http` or `https` proto; malformed/conflicting headers receive 400.
|
|
35
|
+
* Host/tenant authorization remains application-owned. Independent of trustProxy.
|
|
36
|
+
*/
|
|
37
|
+
proxyOrigin?: ProxyOriginConfig;
|
|
29
38
|
port?: number;
|
|
30
39
|
hostname?: string;
|
|
31
40
|
/**
|
package/dist/server/bun.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bun.d.ts","sourceRoot":"","sources":["../../src/server/bun.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,mBAAmB,EAEzB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,eAAe,EAChB,MAAM,SAAS,CAAC;AAEjB,yEAAyE;AACzE,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC;AACrD,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;AAC9C,MAAM,MAAM,kBAAkB,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;AAC5D,MAAM,MAAM,eAAe,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;AACtD,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;AAC9D,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;AAExD,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,KAAK,oBAAoB,GAAG,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1D,KAAK,qBAAqB,GAAG,eAAe,SAAS;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,CAAC,GAAG,KAAK,CAAC;AAE3F,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAClC,eAAe,EACf,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,aAAa,CAChF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAExE,8EAA8E;AAC9E,MAAM,WAAW,eAAgB,SAAQ,gBAAgB,EAAE,mBAAmB;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC,iGAAiG;IACjG,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,GAAG,CAAC,EAAE,iBAAiB,CAAC;CACzB;AAED,MAAM,MAAM,eAAe,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;AA+F7D,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,eAAe,
|
|
1
|
+
{"version":3,"file":"bun.d.ts","sourceRoot":"","sources":["../../src/server/bun.ts"],"names":[],"mappings":"AAGA,OAAO,EAAqB,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAEL,KAAK,mBAAmB,EAEzB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,eAAe,EAChB,MAAM,SAAS,CAAC;AAEjB,yEAAyE;AACzE,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC;AACrD,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;AAC9C,MAAM,MAAM,kBAAkB,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;AAC5D,MAAM,MAAM,eAAe,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;AACtD,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;AAC9D,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;AAExD,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,KAAK,oBAAoB,GAAG,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1D,KAAK,qBAAqB,GAAG,eAAe,SAAS;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,CAAC,GAAG,KAAK,CAAC;AAE3F,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAClC,eAAe,EACf,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,aAAa,CAChF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAExE,8EAA8E;AAC9E,MAAM,WAAW,eAAgB,SAAQ,gBAAgB,EAAE,mBAAmB;IAC5E;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC,iGAAiG;IACjG,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,GAAG,CAAC,EAAE,iBAAiB,CAAC;CACzB;AAED,MAAM,MAAM,eAAe,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;AA+F7D,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,eAAe,CAqMrE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { BunServer } from './bun.js';
|
|
2
|
+
/** One TCP ingress that overwrites Host/proto and strips competing URL headers. */
|
|
3
|
+
export interface ProxyOriginConfig {
|
|
4
|
+
/** Match the real socket peer, never a forwarded client IP. */
|
|
5
|
+
trustedPeer: (socketIp: string) => boolean;
|
|
6
|
+
}
|
|
7
|
+
/** Bun associates requestIP, timeout and upgrade with the original native request. */
|
|
8
|
+
export declare function createProxyOrigin(policy: ProxyOriginConfig): {
|
|
9
|
+
bind(server: BunServer): void;
|
|
10
|
+
normalize(request: Request, server: BunServer): Request | Response;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=proxy-origin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-origin.d.ts","sourceRoot":"","sources":["../../src/server/proxy-origin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,mFAAmF;AACnF,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;CAC5C;AAUD,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB;IAKvD,IAAI,SAAS,SAAS,GAAG,IAAI;IAQ7B,SAAS,UAAU,OAAO,UAAU,SAAS,GAAG,OAAO,GAAG,QAAQ;EAgCrE"}
|
package/llms/server.2.txt
CHANGED
|
@@ -18,6 +18,137 @@ Also read:
|
|
|
18
18
|
# Guide: HTTP server (docs/guide/server.md) (continued)
|
|
19
19
|
==============================================================================
|
|
20
20
|
|
|
21
|
+
## Raw routes
|
|
22
|
+
|
|
23
|
+
Some routes cannot be a clean JSON contract — an OAuth redirect, a webhook with
|
|
24
|
+
signature verification, static files, the Socket.IO endpoint. `rawRoutes` are
|
|
25
|
+
plain `Request → Response` handlers, matched by the same router (shared CORS and
|
|
26
|
+
`onRequest`) but with no schema parsing and no `beforeHandle` gate — a raw route
|
|
27
|
+
authorises itself.
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
createServer({
|
|
31
|
+
services,
|
|
32
|
+
rawRoutes: [
|
|
33
|
+
{
|
|
34
|
+
method: 'GET',
|
|
35
|
+
path: '/health',
|
|
36
|
+
handler: () => Response.json({ status: 'ok' }),
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
method: 'POST',
|
|
40
|
+
path: '/webhooks/:provider',
|
|
41
|
+
serviceName: 'webhooks',
|
|
42
|
+
action: 'receive',
|
|
43
|
+
handler: (req, ctx) => handleWebhook(ctx.params.provider, req),
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
})
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`serviceName` and `action` are optional observability identity. Declare
|
|
50
|
+
`serviceName` when audit, logging, sampling or another cross-cutting policy
|
|
51
|
+
groups this raw route with a service; add `action` when the policy needs an
|
|
52
|
+
operation within that service. Stitchkit never derives either from `path`.
|
|
53
|
+
`action` without `serviceName`, and empty identity strings, fail at startup.
|
|
54
|
+
|
|
55
|
+
A path may be exact, carry `:param` segments, or end in `/*filePath` for a prefix
|
|
56
|
+
wildcard — and the two combine: `/app/:slug/*filePath` matches `/app/x/a/b` with
|
|
57
|
+
`ctx.params.slug === 'x'` and the remainder in `ctx.params.filePath` (a SPA
|
|
58
|
+
deep-link fallback). List more specific routes before the wildcard — the first
|
|
59
|
+
match wins. `staticRoute()` builds a raw route that serves a directory.
|
|
60
|
+
|
|
61
|
+
At startup Stitchkit rejects exact duplicates, equivalent parameter shapes
|
|
62
|
+
(`/users/:id` vs `/users/:userId`) and any later raw route completely hidden by
|
|
63
|
+
an earlier raw route. Partial overlap stays legal, including the recommended
|
|
64
|
+
specific-before-wildcard order. `GET` and `HEAD` remain independent because that
|
|
65
|
+
is how the actual raw matcher dispatches them. Raw-vs-contract overlap remains a
|
|
66
|
+
startup diagnostic naming the bypassed contract identity and scope.
|
|
67
|
+
|
|
68
|
+
### Raw-route helpers
|
|
69
|
+
|
|
70
|
+
A raw route gives up the contract pipeline, so three things get re-implemented in
|
|
71
|
+
every one. `stitchkit/server` ships them — conveniences, not a second pipeline
|
|
72
|
+
(no auth, no schema gate beyond `parseBody`):
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
import { respondJson, errorResponse, parseBody, badRequest } from 'stitchkit/server'
|
|
76
|
+
|
|
77
|
+
handler: async (req) => {
|
|
78
|
+
try {
|
|
79
|
+
const body = await parseBody(req, MySchema) // typed value, or null (no throw)
|
|
80
|
+
if (!body) throw badRequest('invalid body') // helpers THROW an AppError
|
|
81
|
+
return respondJson(await myService(body)) // JSON; 204 when null/undefined
|
|
82
|
+
} catch (err) {
|
|
83
|
+
return errorResponse(err) // same envelope as a contract route
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The error helpers (`badRequest`, `notFound`, …) **throw** an `AppError`, so raise
|
|
89
|
+
them inside the `try` and let `errorResponse(err)` render it — that runs any
|
|
90
|
+
thrown value through the framework's `normalizeError`, so a raw route returns the
|
|
91
|
+
**identical** `{ error: { code, message, … } }` shape (and `x-request-id`) a
|
|
92
|
+
contract route does.
|
|
93
|
+
|
|
94
|
+
### Serving files & Range requests
|
|
95
|
+
|
|
96
|
+
`staticRoute` is basic on purpose — it reads the whole file into memory and has
|
|
97
|
+
no `Range` or conditional support; put a CDN in front, or use it for small web
|
|
98
|
+
assets. To serve **media** (video / audio / large downloads) that a browser must
|
|
99
|
+
seek and cache, use **`serveFile`** (Bun) — it streams the requested byte range
|
|
100
|
+
and speaks the conditional-request half of RFC 7233 / 9110:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { defineContract } from 'stitchkit/contract'
|
|
104
|
+
import { implement, serveFile } from 'stitchkit/server'
|
|
105
|
+
import { z } from 'zod'
|
|
106
|
+
|
|
107
|
+
const MediaParams = z.object({ id: z.string() })
|
|
108
|
+
const media = defineContract({ prefix: 'media' }, {
|
|
109
|
+
download: {
|
|
110
|
+
method: 'GET', path: '/:id', desc: 'Download media',
|
|
111
|
+
params: MediaParams, rawResponse: true, contentType: 'video/mp4',
|
|
112
|
+
},
|
|
113
|
+
inspect: {
|
|
114
|
+
method: 'HEAD', path: '/:id', desc: 'Inspect media',
|
|
115
|
+
params: MediaParams, rawResponse: true, contentType: 'video/mp4',
|
|
116
|
+
},
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
const mediaService = implement(media, {
|
|
120
|
+
download: ({ req, params }) =>
|
|
121
|
+
serveFile(req, { path: pathForId(params.id), filename: 'clip.mp4' }),
|
|
122
|
+
inspect: ({ req, params }) =>
|
|
123
|
+
serveFile(req, { path: pathForId(params.id), filename: 'clip.mp4' }),
|
|
124
|
+
})
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
GET and HEAD are separate operations deliberately: declaring GET never creates
|
|
128
|
+
a hidden HEAD alias. Both travel through the normal contract router, params,
|
|
129
|
+
lifecycle/RBAC and request logging. A HEAD handler may inspect the raw query via
|
|
130
|
+
`ctx.req.url`, but cannot declare a request input schema or body.
|
|
131
|
+
|
|
132
|
+
`serveFile` returns `206` (range, with `Content-Range` + `Content-Length`), `200`
|
|
133
|
+
(full), `416` (unsatisfiable, `Content-Range: bytes */size`), `304`
|
|
134
|
+
(`If-None-Match` / `If-Modified-Since`), `404` (missing) or `405` (non GET/HEAD).
|
|
135
|
+
It always sets `Accept-Ranges: bytes`, a weak `ETag` and `Last-Modified` (so
|
|
136
|
+
`If-Range` keeps a changing file from being stitched from stale + fresh bytes),
|
|
137
|
+
and `nosniff`. `Content-Type` is auto-detected from the path — override it, or
|
|
138
|
+
pass `disposition` / `cacheControl` / `etag: false`, via the options.
|
|
139
|
+
|
|
140
|
+
Cross-origin, the browser lets JavaScript read only the CORS-safelisted response
|
|
141
|
+
headers. stitchkit therefore exposes the download-relevant ones by default
|
|
142
|
+
(`Content-Disposition`, `Content-Range`, `ETag`, …) — without that a `fetch`-based
|
|
143
|
+
download cannot recover the file's name. Override with `cors.exposeHeaders`
|
|
144
|
+
(extend `DEFAULT_CORS_EXPOSE_HEADERS` rather than replacing it), or pass `[]` to
|
|
145
|
+
emit none.
|
|
146
|
+
|
|
147
|
+
`serveFile` takes an explicit `path` and trusts it — **the caller owns
|
|
148
|
+
containment**. For a URL-derived path use `staticRoute` (which enforces it) or
|
|
149
|
+
`isWithinDir` first. The byte-range parser is exported on its own as
|
|
150
|
+
`parseByteRange(header, size)` for direct use and testing. → ADR 0023.
|
|
151
|
+
|
|
21
152
|
## Server primitives
|
|
22
153
|
|
|
23
154
|
`stitchkit/server` also exports the primitives most APIs need. Each is a small,
|
package/llms/server.5.txt
CHANGED
|
@@ -65,6 +65,7 @@ Also re-exports the error helpers from `stitchkit/contract`.
|
|
|
65
65
|
| `parseBody` | function | parse + Zod-validate a JSON body → `data` or `null` (no throw) |
|
|
66
66
|
| `HandlerConfig` | _type_ | config for `createHandler`, including optional `maxJsonBodyBytes`; bound to `BunServer` on this entrypoint |
|
|
67
67
|
| `BunServerConfig` | _type_ | config for `createServer` (Bun); `unix` listens on a unix domain socket (mutually exclusive with `port`/`hostname`) — [details](../guide/server.md#local-daemon-over-a-unix-socket) |
|
|
68
|
+
| `ProxyOriginConfig` | _type_ | explicit real-peer trust for Bun `createServer({ proxyOrigin })`; strict external-scheme normalization before composition — [details](../guide/server.md#external-origin-behind-a-trusted-proxy) |
|
|
68
69
|
| `UnixListenConfig` | _type_ | unix listener — a socket path, or `{ path, mode }` to tighten the file mode after listen |
|
|
69
70
|
| `BunServerHandle` | _type_ | managed Bun handle (`url`, `port`, `runtime`, `status`, `shutdown`) |
|
|
70
71
|
| `ManagedServerHandle` | _type_ | shared lifecycle shape generic over the runtime escape hatch |
|
package/llms/server.txt
CHANGED
|
@@ -268,6 +268,7 @@ server. See [Testing & deployment](./testing-and-deployment.md).
|
|
|
268
268
|
| `logging` | `true` for built-in request logs, or a `LoggingConfig` (see below) |
|
|
269
269
|
| `traceId` | override per-request trace-id resolution — may return `undefined` to fall back |
|
|
270
270
|
| `wrapFetch` | compose wrappers around the finished handler (request context, audit) |
|
|
271
|
+
| `proxyOrigin` | Bun TCP ingress policy: `{ trustedPeer(socketIp) }` restores the external scheme before all composition; independent of client-IP `trustProxy` |
|
|
271
272
|
| `socket` | full Stitchkit Socket.IO handle; route, default WebSocket handler and shutdown are mounted once |
|
|
272
273
|
| `websocket` | custom Bun WebSocket handler; with `socket`, this is the explicit composed handler |
|
|
273
274
|
| `development` / `bun` | passthrough to `Bun.serve` |
|
|
@@ -276,6 +277,60 @@ Native Bun `routes` are intentionally not accepted: Bun matches them before
|
|
|
276
277
|
`fetch`, so they could bypass shutdown admission. Use `rawRoutes`; they retain
|
|
277
278
|
the Fetch `Request → Response` model and participate in lifecycle tracking.
|
|
278
279
|
|
|
280
|
+
### External origin behind a trusted proxy
|
|
281
|
+
|
|
282
|
+
An HTTPS ingress often forwards plain HTTP to Bun. `trustProxy` trusts client-IP
|
|
283
|
+
headers only; it does not change `Request.url`. Opt into the separate URL policy:
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
import { createServer, isLoopbackAddress } from 'stitchkit/server'
|
|
287
|
+
|
|
288
|
+
const server = createServer({
|
|
289
|
+
hostname: '127.0.0.1',
|
|
290
|
+
port: 3000,
|
|
291
|
+
proxyOrigin: { trustedPeer: isLoopbackAddress },
|
|
292
|
+
services,
|
|
293
|
+
})
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
The predicate receives the **real TCP peer**, never `X-Forwarded-For` or
|
|
297
|
+
`X-Real-IP`. Match only the ingress you control. Loopback is appropriate only
|
|
298
|
+
when other local processes are trusted. Unmatched peers, missing peer metadata
|
|
299
|
+
and the default configuration ignore URL forwarding headers. Unix listeners have
|
|
300
|
+
no TCP peer and do not use this policy. This option belongs to Bun `createServer`,
|
|
301
|
+
not the Fetch-clean `createHandler` or Node `serveNode`.
|
|
302
|
+
|
|
303
|
+
The trusted ingress must overwrite `Host` with the external authority and
|
|
304
|
+
`X-Forwarded-Proto` with exactly `http` or `https`. It must remove `Forwarded`,
|
|
305
|
+
`X-Forwarded-Host` and `X-Forwarded-Port`; their presence, a missing/invalid
|
|
306
|
+
proto, a list of values or a malformed Host returns HTTP 400 before application
|
|
307
|
+
code. Header names are case-insensitive; proto values are lowercase. Multiple
|
|
308
|
+
ingress chains require a single sanitizing ingress at this boundary.
|
|
309
|
+
|
|
310
|
+
For an nginx HTTPS terminator, the relevant forwarding settings are:
|
|
311
|
+
|
|
312
|
+
```nginx
|
|
313
|
+
proxy_set_header Host $http_host;
|
|
314
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
315
|
+
proxy_set_header Forwarded "";
|
|
316
|
+
proxy_set_header X-Forwarded-Host "";
|
|
317
|
+
proxy_set_header X-Forwarded-Port "";
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
The normalized `Request.url` reaches `wrapFetch`, hooks, contracts, raw routes,
|
|
321
|
+
and the managed Socket.IO route. It preserves the path/query, wire authority
|
|
322
|
+
(including explicit ports), method, body, headers and linked cancellation signal.
|
|
323
|
+
Request cloning uses the normalized URL. The same runtime handle resolves
|
|
324
|
+
`requestIP`, `timeout` and `upgrade` against the original native request, retaining
|
|
325
|
+
WebSocket and shutdown behavior.
|
|
326
|
+
|
|
327
|
+
This is a scheme normalization policy, **not host authorization**. Applications
|
|
328
|
+
must retain their hostname/tenant allowlist and exact same-origin checks for
|
|
329
|
+
Origin and Referer. The TLS terminator must reject SNI/Host mismatches before
|
|
330
|
+
forwarding; a plain-HTTP Bun listener cannot observe the TLS SNI. The normalizer
|
|
331
|
+
does not accept `X-Forwarded-Host`, authorize a foreign Host, or treat HTTP and
|
|
332
|
+
HTTPS as aliases.
|
|
333
|
+
|
|
279
334
|
### Local daemon over a unix socket
|
|
280
335
|
|
|
281
336
|
A local daemon whose door is a socket file needs no TCP port at all:
|
|
@@ -863,134 +918,3 @@ file: (ctx) => {
|
|
|
863
918
|
`Response` is forwarded verbatim. Request headers are not relayed, so a `Range`
|
|
864
919
|
sent to the proxy does not reach the origin and the full body comes back.
|
|
865
920
|
→ ADR 0038.
|
|
866
|
-
|
|
867
|
-
## Raw routes
|
|
868
|
-
|
|
869
|
-
Some routes cannot be a clean JSON contract — an OAuth redirect, a webhook with
|
|
870
|
-
signature verification, static files, the Socket.IO endpoint. `rawRoutes` are
|
|
871
|
-
plain `Request → Response` handlers, matched by the same router (shared CORS and
|
|
872
|
-
`onRequest`) but with no schema parsing and no `beforeHandle` gate — a raw route
|
|
873
|
-
authorises itself.
|
|
874
|
-
|
|
875
|
-
```ts
|
|
876
|
-
createServer({
|
|
877
|
-
services,
|
|
878
|
-
rawRoutes: [
|
|
879
|
-
{
|
|
880
|
-
method: 'GET',
|
|
881
|
-
path: '/health',
|
|
882
|
-
handler: () => Response.json({ status: 'ok' }),
|
|
883
|
-
},
|
|
884
|
-
{
|
|
885
|
-
method: 'POST',
|
|
886
|
-
path: '/webhooks/:provider',
|
|
887
|
-
serviceName: 'webhooks',
|
|
888
|
-
action: 'receive',
|
|
889
|
-
handler: (req, ctx) => handleWebhook(ctx.params.provider, req),
|
|
890
|
-
},
|
|
891
|
-
],
|
|
892
|
-
})
|
|
893
|
-
```
|
|
894
|
-
|
|
895
|
-
`serviceName` and `action` are optional observability identity. Declare
|
|
896
|
-
`serviceName` when audit, logging, sampling or another cross-cutting policy
|
|
897
|
-
groups this raw route with a service; add `action` when the policy needs an
|
|
898
|
-
operation within that service. Stitchkit never derives either from `path`.
|
|
899
|
-
`action` without `serviceName`, and empty identity strings, fail at startup.
|
|
900
|
-
|
|
901
|
-
A path may be exact, carry `:param` segments, or end in `/*filePath` for a prefix
|
|
902
|
-
wildcard — and the two combine: `/app/:slug/*filePath` matches `/app/x/a/b` with
|
|
903
|
-
`ctx.params.slug === 'x'` and the remainder in `ctx.params.filePath` (a SPA
|
|
904
|
-
deep-link fallback). List more specific routes before the wildcard — the first
|
|
905
|
-
match wins. `staticRoute()` builds a raw route that serves a directory.
|
|
906
|
-
|
|
907
|
-
At startup Stitchkit rejects exact duplicates, equivalent parameter shapes
|
|
908
|
-
(`/users/:id` vs `/users/:userId`) and any later raw route completely hidden by
|
|
909
|
-
an earlier raw route. Partial overlap stays legal, including the recommended
|
|
910
|
-
specific-before-wildcard order. `GET` and `HEAD` remain independent because that
|
|
911
|
-
is how the actual raw matcher dispatches them. Raw-vs-contract overlap remains a
|
|
912
|
-
startup diagnostic naming the bypassed contract identity and scope.
|
|
913
|
-
|
|
914
|
-
### Raw-route helpers
|
|
915
|
-
|
|
916
|
-
A raw route gives up the contract pipeline, so three things get re-implemented in
|
|
917
|
-
every one. `stitchkit/server` ships them — conveniences, not a second pipeline
|
|
918
|
-
(no auth, no schema gate beyond `parseBody`):
|
|
919
|
-
|
|
920
|
-
```ts
|
|
921
|
-
import { respondJson, errorResponse, parseBody, badRequest } from 'stitchkit/server'
|
|
922
|
-
|
|
923
|
-
handler: async (req) => {
|
|
924
|
-
try {
|
|
925
|
-
const body = await parseBody(req, MySchema) // typed value, or null (no throw)
|
|
926
|
-
if (!body) throw badRequest('invalid body') // helpers THROW an AppError
|
|
927
|
-
return respondJson(await myService(body)) // JSON; 204 when null/undefined
|
|
928
|
-
} catch (err) {
|
|
929
|
-
return errorResponse(err) // same envelope as a contract route
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
```
|
|
933
|
-
|
|
934
|
-
The error helpers (`badRequest`, `notFound`, …) **throw** an `AppError`, so raise
|
|
935
|
-
them inside the `try` and let `errorResponse(err)` render it — that runs any
|
|
936
|
-
thrown value through the framework's `normalizeError`, so a raw route returns the
|
|
937
|
-
**identical** `{ error: { code, message, … } }` shape (and `x-request-id`) a
|
|
938
|
-
contract route does.
|
|
939
|
-
|
|
940
|
-
### Serving files & Range requests
|
|
941
|
-
|
|
942
|
-
`staticRoute` is basic on purpose — it reads the whole file into memory and has
|
|
943
|
-
no `Range` or conditional support; put a CDN in front, or use it for small web
|
|
944
|
-
assets. To serve **media** (video / audio / large downloads) that a browser must
|
|
945
|
-
seek and cache, use **`serveFile`** (Bun) — it streams the requested byte range
|
|
946
|
-
and speaks the conditional-request half of RFC 7233 / 9110:
|
|
947
|
-
|
|
948
|
-
```ts
|
|
949
|
-
import { defineContract } from 'stitchkit/contract'
|
|
950
|
-
import { implement, serveFile } from 'stitchkit/server'
|
|
951
|
-
import { z } from 'zod'
|
|
952
|
-
|
|
953
|
-
const MediaParams = z.object({ id: z.string() })
|
|
954
|
-
const media = defineContract({ prefix: 'media' }, {
|
|
955
|
-
download: {
|
|
956
|
-
method: 'GET', path: '/:id', desc: 'Download media',
|
|
957
|
-
params: MediaParams, rawResponse: true, contentType: 'video/mp4',
|
|
958
|
-
},
|
|
959
|
-
inspect: {
|
|
960
|
-
method: 'HEAD', path: '/:id', desc: 'Inspect media',
|
|
961
|
-
params: MediaParams, rawResponse: true, contentType: 'video/mp4',
|
|
962
|
-
},
|
|
963
|
-
})
|
|
964
|
-
|
|
965
|
-
const mediaService = implement(media, {
|
|
966
|
-
download: ({ req, params }) =>
|
|
967
|
-
serveFile(req, { path: pathForId(params.id), filename: 'clip.mp4' }),
|
|
968
|
-
inspect: ({ req, params }) =>
|
|
969
|
-
serveFile(req, { path: pathForId(params.id), filename: 'clip.mp4' }),
|
|
970
|
-
})
|
|
971
|
-
```
|
|
972
|
-
|
|
973
|
-
GET and HEAD are separate operations deliberately: declaring GET never creates
|
|
974
|
-
a hidden HEAD alias. Both travel through the normal contract router, params,
|
|
975
|
-
lifecycle/RBAC and request logging. A HEAD handler may inspect the raw query via
|
|
976
|
-
`ctx.req.url`, but cannot declare a request input schema or body.
|
|
977
|
-
|
|
978
|
-
`serveFile` returns `206` (range, with `Content-Range` + `Content-Length`), `200`
|
|
979
|
-
(full), `416` (unsatisfiable, `Content-Range: bytes */size`), `304`
|
|
980
|
-
(`If-None-Match` / `If-Modified-Since`), `404` (missing) or `405` (non GET/HEAD).
|
|
981
|
-
It always sets `Accept-Ranges: bytes`, a weak `ETag` and `Last-Modified` (so
|
|
982
|
-
`If-Range` keeps a changing file from being stitched from stale + fresh bytes),
|
|
983
|
-
and `nosniff`. `Content-Type` is auto-detected from the path — override it, or
|
|
984
|
-
pass `disposition` / `cacheControl` / `etag: false`, via the options.
|
|
985
|
-
|
|
986
|
-
Cross-origin, the browser lets JavaScript read only the CORS-safelisted response
|
|
987
|
-
headers. stitchkit therefore exposes the download-relevant ones by default
|
|
988
|
-
(`Content-Disposition`, `Content-Range`, `ETag`, …) — without that a `fetch`-based
|
|
989
|
-
download cannot recover the file's name. Override with `cors.exposeHeaders`
|
|
990
|
-
(extend `DEFAULT_CORS_EXPOSE_HEADERS` rather than replacing it), or pass `[]` to
|
|
991
|
-
emit none.
|
|
992
|
-
|
|
993
|
-
`serveFile` takes an explicit `path` and trusts it — **the caller owns
|
|
994
|
-
containment**. For a URL-derived path use `staticRoute` (which enforces it) or
|
|
995
|
-
`isWithinDir` first. The byte-range parser is exported on its own as
|
|
996
|
-
`parseByteRange(header, size)` for direct use and testing. → ADR 0023.
|
package/llms-full.txt
CHANGED
|
@@ -1369,6 +1369,7 @@ server. See [Testing & deployment](./testing-and-deployment.md).
|
|
|
1369
1369
|
| `logging` | `true` for built-in request logs, or a `LoggingConfig` (see below) |
|
|
1370
1370
|
| `traceId` | override per-request trace-id resolution — may return `undefined` to fall back |
|
|
1371
1371
|
| `wrapFetch` | compose wrappers around the finished handler (request context, audit) |
|
|
1372
|
+
| `proxyOrigin` | Bun TCP ingress policy: `{ trustedPeer(socketIp) }` restores the external scheme before all composition; independent of client-IP `trustProxy` |
|
|
1372
1373
|
| `socket` | full Stitchkit Socket.IO handle; route, default WebSocket handler and shutdown are mounted once |
|
|
1373
1374
|
| `websocket` | custom Bun WebSocket handler; with `socket`, this is the explicit composed handler |
|
|
1374
1375
|
| `development` / `bun` | passthrough to `Bun.serve` |
|
|
@@ -1377,6 +1378,60 @@ Native Bun `routes` are intentionally not accepted: Bun matches them before
|
|
|
1377
1378
|
`fetch`, so they could bypass shutdown admission. Use `rawRoutes`; they retain
|
|
1378
1379
|
the Fetch `Request → Response` model and participate in lifecycle tracking.
|
|
1379
1380
|
|
|
1381
|
+
### External origin behind a trusted proxy
|
|
1382
|
+
|
|
1383
|
+
An HTTPS ingress often forwards plain HTTP to Bun. `trustProxy` trusts client-IP
|
|
1384
|
+
headers only; it does not change `Request.url`. Opt into the separate URL policy:
|
|
1385
|
+
|
|
1386
|
+
```ts
|
|
1387
|
+
import { createServer, isLoopbackAddress } from 'stitchkit/server'
|
|
1388
|
+
|
|
1389
|
+
const server = createServer({
|
|
1390
|
+
hostname: '127.0.0.1',
|
|
1391
|
+
port: 3000,
|
|
1392
|
+
proxyOrigin: { trustedPeer: isLoopbackAddress },
|
|
1393
|
+
services,
|
|
1394
|
+
})
|
|
1395
|
+
```
|
|
1396
|
+
|
|
1397
|
+
The predicate receives the **real TCP peer**, never `X-Forwarded-For` or
|
|
1398
|
+
`X-Real-IP`. Match only the ingress you control. Loopback is appropriate only
|
|
1399
|
+
when other local processes are trusted. Unmatched peers, missing peer metadata
|
|
1400
|
+
and the default configuration ignore URL forwarding headers. Unix listeners have
|
|
1401
|
+
no TCP peer and do not use this policy. This option belongs to Bun `createServer`,
|
|
1402
|
+
not the Fetch-clean `createHandler` or Node `serveNode`.
|
|
1403
|
+
|
|
1404
|
+
The trusted ingress must overwrite `Host` with the external authority and
|
|
1405
|
+
`X-Forwarded-Proto` with exactly `http` or `https`. It must remove `Forwarded`,
|
|
1406
|
+
`X-Forwarded-Host` and `X-Forwarded-Port`; their presence, a missing/invalid
|
|
1407
|
+
proto, a list of values or a malformed Host returns HTTP 400 before application
|
|
1408
|
+
code. Header names are case-insensitive; proto values are lowercase. Multiple
|
|
1409
|
+
ingress chains require a single sanitizing ingress at this boundary.
|
|
1410
|
+
|
|
1411
|
+
For an nginx HTTPS terminator, the relevant forwarding settings are:
|
|
1412
|
+
|
|
1413
|
+
```nginx
|
|
1414
|
+
proxy_set_header Host $http_host;
|
|
1415
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
1416
|
+
proxy_set_header Forwarded "";
|
|
1417
|
+
proxy_set_header X-Forwarded-Host "";
|
|
1418
|
+
proxy_set_header X-Forwarded-Port "";
|
|
1419
|
+
```
|
|
1420
|
+
|
|
1421
|
+
The normalized `Request.url` reaches `wrapFetch`, hooks, contracts, raw routes,
|
|
1422
|
+
and the managed Socket.IO route. It preserves the path/query, wire authority
|
|
1423
|
+
(including explicit ports), method, body, headers and linked cancellation signal.
|
|
1424
|
+
Request cloning uses the normalized URL. The same runtime handle resolves
|
|
1425
|
+
`requestIP`, `timeout` and `upgrade` against the original native request, retaining
|
|
1426
|
+
WebSocket and shutdown behavior.
|
|
1427
|
+
|
|
1428
|
+
This is a scheme normalization policy, **not host authorization**. Applications
|
|
1429
|
+
must retain their hostname/tenant allowlist and exact same-origin checks for
|
|
1430
|
+
Origin and Referer. The TLS terminator must reject SNI/Host mismatches before
|
|
1431
|
+
forwarding; a plain-HTTP Bun listener cannot observe the TLS SNI. The normalizer
|
|
1432
|
+
does not accept `X-Forwarded-Host`, authorize a foreign Host, or treat HTTP and
|
|
1433
|
+
HTTPS as aliases.
|
|
1434
|
+
|
|
1380
1435
|
### Local daemon over a unix socket
|
|
1381
1436
|
|
|
1382
1437
|
A local daemon whose door is a socket file needs no TCP port at all:
|
|
@@ -21245,6 +21300,7 @@ Also re-exports the error helpers from `stitchkit/contract`.
|
|
|
21245
21300
|
| `parseBody` | function | parse + Zod-validate a JSON body → `data` or `null` (no throw) |
|
|
21246
21301
|
| `HandlerConfig` | _type_ | config for `createHandler`, including optional `maxJsonBodyBytes`; bound to `BunServer` on this entrypoint |
|
|
21247
21302
|
| `BunServerConfig` | _type_ | config for `createServer` (Bun); `unix` listens on a unix domain socket (mutually exclusive with `port`/`hostname`) — [details](../guide/server.md#local-daemon-over-a-unix-socket) |
|
|
21303
|
+
| `ProxyOriginConfig` | _type_ | explicit real-peer trust for Bun `createServer({ proxyOrigin })`; strict external-scheme normalization before composition — [details](../guide/server.md#external-origin-behind-a-trusted-proxy) |
|
|
21248
21304
|
| `UnixListenConfig` | _type_ | unix listener — a socket path, or `{ path, mode }` to tighten the file mode after listen |
|
|
21249
21305
|
| `BunServerHandle` | _type_ | managed Bun handle (`url`, `port`, `runtime`, `status`, `shutdown`) |
|
|
21250
21306
|
| `ManagedServerHandle` | _type_ | shared lifecycle shape generic over the runtime escape hatch |
|
package/llms.txt
CHANGED
|
@@ -23,7 +23,7 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
|
|
|
23
23
|
- **stitchkit/remote**: [llms/remote.txt](llms/remote.txt) 1.0 KB
|
|
24
24
|
- **stitchkit/contract**: [llms/contract.txt](llms/contract.txt) 31.9 KB
|
|
25
25
|
- **stitchkit/primitives**: [llms/primitives.txt](llms/primitives.txt) 11.7 KB
|
|
26
|
-
- **stitchkit/server**: [llms/server.txt](llms/server.txt)
|
|
26
|
+
- **stitchkit/server**: [llms/server.txt](llms/server.txt) 42.2 KB → [llms/server.2.txt](llms/server.2.txt) 20.3 KB → [llms/server.3.txt](llms/server.3.txt) 45.6 KB → [llms/server.4.txt](llms/server.4.txt) 38.3 KB → [llms/server.5.txt](llms/server.5.txt) 22.3 KB
|
|
27
27
|
- **stitchkit/observability**: [llms/observability.txt](llms/observability.txt) 45.9 KB
|
|
28
28
|
- **stitchkit/agent-runtime**: [llms/agent-runtime.txt](llms/agent-runtime.txt) 42.7 KB → [llms/agent-runtime.2.txt](llms/agent-runtime.2.txt) 46.7 KB → [llms/agent-runtime.3.txt](llms/agent-runtime.3.txt) 35.6 KB
|
|
29
29
|
- **stitchkit/agent-runtime/testing**: [llms/agent-runtime-testing.txt](llms/agent-runtime-testing.txt) 2.6 KB
|
package/package.json
CHANGED