stitchkit 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -10
- package/dist/browser/client.d.ts.map +1 -1
- package/dist/browser/http.d.ts +5 -0
- package/dist/browser/http.d.ts.map +1 -1
- package/dist/browser/socket-io.d.ts +17 -0
- package/dist/browser/socket-io.d.ts.map +1 -1
- package/dist/cli.d.ts +23 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +21 -0
- package/dist/contract/define.d.ts +35 -2
- package/dist/contract/define.d.ts.map +1 -1
- package/dist/contract/index.d.ts +1 -1
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +2 -1
- package/dist/index-0ed3bx43.js +33 -0
- package/dist/index-0ma1eqv4.js +1007 -0
- package/dist/index-1cf8jkhf.js +219 -0
- package/dist/index-37x76zdn.js +4 -0
- package/dist/{index-v2z2v3mq.js → index-3qmtdfpa.js} +304 -62
- package/dist/index-48ffdxgk.js +6 -0
- package/dist/{index-5sxnvwb1.js → index-78q1qm7v.js} +6 -3
- package/dist/{index-kckky6zw.js → index-afzt3nmx.js} +1 -1
- package/dist/{index-n7bmdwmz.js → index-d4rwrjbc.js} +8 -4
- package/dist/index-kzfs85xp.js +9 -0
- package/dist/index-mwmpw6j1.js +60 -0
- package/dist/{index-a35v22fh.js → index-vhdvv00d.js} +13 -5
- package/dist/index-x3fcszf8.js +8 -0
- package/dist/index.js +17 -4
- package/dist/internal/errors.d.ts +13 -1
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/http-input.d.ts +13 -0
- package/dist/internal/http-input.d.ts.map +1 -0
- package/dist/internal/safe-json.d.ts +19 -0
- package/dist/internal/safe-json.d.ts.map +1 -0
- package/dist/internal/secure-fetch.d.ts +27 -0
- package/dist/internal/secure-fetch.d.ts.map +1 -0
- package/dist/internal/within-dir.d.ts +7 -0
- package/dist/internal/within-dir.d.ts.map +1 -0
- package/dist/node.d.ts +10 -1
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +41 -7
- package/dist/observability/audit.d.ts.map +1 -1
- package/dist/observability/context.d.ts +9 -1
- package/dist/observability/context.d.ts.map +1 -1
- package/dist/observability/event.d.ts +4 -0
- package/dist/observability/event.d.ts.map +1 -1
- package/dist/observability/index.js +38 -15
- package/dist/observability/sanitize.d.ts.map +1 -1
- package/dist/react.js +2 -0
- package/dist/server/context.d.ts +3 -2
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/create.d.ts.map +1 -1
- package/dist/server/event-bus.d.ts +10 -1
- package/dist/server/event-bus.d.ts.map +1 -1
- package/dist/server/implement.d.ts.map +1 -1
- package/dist/server/index.d.ts +6 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +203 -193
- package/dist/server/logger.d.ts +5 -4
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/middleware/auth.d.ts +41 -1
- package/dist/server/middleware/auth.d.ts.map +1 -1
- package/dist/server/middleware/cookies.d.ts.map +1 -1
- package/dist/server/middleware/cors.d.ts +7 -0
- package/dist/server/middleware/cors.d.ts.map +1 -1
- package/dist/server/middleware/pkce.d.ts +17 -0
- package/dist/server/middleware/pkce.d.ts.map +1 -0
- package/dist/server/multipart.d.ts +2 -1
- package/dist/server/multipart.d.ts.map +1 -1
- package/dist/server/node.d.ts +9 -0
- package/dist/server/node.d.ts.map +1 -1
- package/dist/server/openapi.d.ts +52 -0
- package/dist/server/openapi.d.ts.map +1 -0
- package/dist/server/rate-limit.d.ts +7 -2
- package/dist/server/rate-limit.d.ts.map +1 -1
- package/dist/server/request.d.ts +27 -4
- package/dist/server/request.d.ts.map +1 -1
- package/dist/server/router.d.ts +4 -2
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/socket-io.d.ts +60 -15
- package/dist/server/socket-io.d.ts.map +1 -1
- package/dist/server/stream.d.ts +3 -1
- package/dist/server/stream.d.ts.map +1 -1
- package/dist/server/types.d.ts +17 -1
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/websocket.d.ts +73 -0
- package/dist/server/websocket.d.ts.map +1 -0
- package/dist/tools/cli-args.d.ts +68 -0
- package/dist/tools/cli-args.d.ts.map +1 -0
- package/dist/tools/cli-format.d.ts +39 -0
- package/dist/tools/cli-format.d.ts.map +1 -0
- package/dist/tools/cli-wait.d.ts +45 -0
- package/dist/tools/cli-wait.d.ts.map +1 -0
- package/dist/tools/cli.d.ts +77 -0
- package/dist/tools/cli.d.ts.map +1 -0
- package/dist/tools/coerce.d.ts +8 -4
- package/dist/tools/coerce.d.ts.map +1 -1
- package/dist/tools/execute.d.ts +1 -1
- package/dist/tools/execute.d.ts.map +1 -1
- package/dist/tools/json-schema.d.ts +29 -4
- package/dist/tools/json-schema.d.ts.map +1 -1
- package/dist/tools/manifest.d.ts +4 -0
- package/dist/tools/manifest.d.ts.map +1 -1
- package/dist/tools/mcp-app.d.ts +59 -0
- package/dist/tools/mcp-app.d.ts.map +1 -0
- package/dist/tools/mcp-handler.d.ts +18 -0
- package/dist/tools/mcp-handler.d.ts.map +1 -1
- package/dist/tools/mcp.d.ts +9 -0
- package/dist/tools/mcp.d.ts.map +1 -1
- package/dist/tools/mount-download.d.ts +30 -0
- package/dist/tools/mount-download.d.ts.map +1 -0
- package/dist/tools/mount-upload.d.ts +19 -0
- package/dist/tools/mount-upload.d.ts.map +1 -0
- package/dist/tools/mount-wait.d.ts +36 -0
- package/dist/tools/mount-wait.d.ts.map +1 -0
- package/dist/tools/mount.d.ts +8 -4
- package/dist/tools/mount.d.ts.map +1 -1
- package/dist/tools/native-result.d.ts +17 -0
- package/dist/tools/native-result.d.ts.map +1 -0
- package/dist/tools/oauth-metadata.d.ts +28 -0
- package/dist/tools/oauth-metadata.d.ts.map +1 -0
- package/dist/tools/oauth-provider.d.ts +85 -0
- package/dist/tools/oauth-provider.d.ts.map +1 -0
- package/dist/tools/remote.d.ts +2 -2
- package/dist/tools/remote.d.ts.map +1 -1
- package/dist/tools/toolkit.d.ts +51 -0
- package/dist/tools/toolkit.d.ts.map +1 -0
- package/dist/tools/view-file.d.ts +12 -0
- package/dist/tools/view-file.d.ts.map +1 -1
- package/dist/tools/wait-core.d.ts +33 -0
- package/dist/tools/wait-core.d.ts.map +1 -0
- package/dist/tools.d.ts +13 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +637 -424
- package/package.json +22 -9
- package/dist/index-ke4mx4ea.js +0 -38
|
@@ -2,7 +2,8 @@ import type { ZodType } from 'zod';
|
|
|
2
2
|
/** A parsed multipart request — the uploaded `file` and the validated `fields`. */
|
|
3
3
|
export interface MultipartResult {
|
|
4
4
|
file: File;
|
|
5
|
-
|
|
5
|
+
/** Validated when a `fieldsSchema` was given, else the raw decoded fields. */
|
|
6
|
+
fields: unknown;
|
|
6
7
|
}
|
|
7
8
|
/**
|
|
8
9
|
* Parse a `multipart/form-data` request — extract the file at `fileField` and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multipart.d.ts","sourceRoot":"","sources":["../../src/server/multipart.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"multipart.d.ts","sourceRoot":"","sources":["../../src/server/multipart.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAInC,mFAAmF;AACnF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,IAAI,CAAC;IACX,8EAA8E;IAC9E,MAAM,EAAE,OAAO,CAAC;CACjB;AA0CD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,EAC/B,QAAQ,SAA2B,GAClC,OAAO,CAAC,eAAe,CAAC,CA6B1B"}
|
package/dist/server/node.d.ts
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
|
+
import type { Server as HttpServer } from 'node:http';
|
|
1
2
|
import type { HandlerConfig } from './types';
|
|
2
3
|
export interface NodeServerConfig extends HandlerConfig {
|
|
3
4
|
port?: number;
|
|
4
5
|
hostname?: string;
|
|
6
|
+
/**
|
|
7
|
+
* A Socket.IO handle from `createSocketIOServer` — attached to the underlying
|
|
8
|
+
* `node:http.Server` (srvx `server.node.server`) once it is listening, so
|
|
9
|
+
* Socket.IO owns the HTTP `upgrade` event on the same port.
|
|
10
|
+
*/
|
|
11
|
+
socket?: {
|
|
12
|
+
attach(server: HttpServer): void;
|
|
13
|
+
};
|
|
5
14
|
}
|
|
6
15
|
export interface NodeServerHandle {
|
|
7
16
|
url: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/server/node.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/server/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC;AAGtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE;QAAE,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAAA;KAAE,CAAC;CAC/C;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA6BnF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI 3.1 generation from contracts. A `defineContract` already carries the
|
|
3
|
+
* full type information — Zod `params` / `input` / `output`, `desc`, `method`,
|
|
4
|
+
* `path`, `scope` — so the spec is generated, not hand-maintained: the contract
|
|
5
|
+
* IS the spec. No decorators, no duplicated annotations. → ADR 0018.
|
|
6
|
+
*
|
|
7
|
+
* Schemas are converted through the same single `toJsonSchema` point the tool
|
|
8
|
+
* layer uses (and `jsonSchemaFields`, shared with the CLI `--help` walker), so
|
|
9
|
+
* the JSON Schema in the spec is the JSON Schema the rest of the framework
|
|
10
|
+
* emits — not a divergent code path. Schemas are inlined (valid OpenAPI);
|
|
11
|
+
* `$ref` de-duplication can come later if a spec grows unwieldy.
|
|
12
|
+
*/
|
|
13
|
+
import type { RawRoute, ServiceDef } from './types';
|
|
14
|
+
export interface OpenApiInfo {
|
|
15
|
+
title: string;
|
|
16
|
+
version: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface OpenApiServer {
|
|
20
|
+
url: string;
|
|
21
|
+
description?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface OpenApiConfig {
|
|
24
|
+
info: OpenApiInfo;
|
|
25
|
+
/** Flat services, mounted at their own prefix. */
|
|
26
|
+
services?: ServiceDef[];
|
|
27
|
+
/** Grouped services, each mounted under a path prefix (mirrors `RouteGroup`). */
|
|
28
|
+
groups?: Array<{
|
|
29
|
+
pathPrefix?: string;
|
|
30
|
+
services: ServiceDef[];
|
|
31
|
+
}>;
|
|
32
|
+
/** `servers` block for the spec. */
|
|
33
|
+
servers?: OpenApiServer[];
|
|
34
|
+
}
|
|
35
|
+
export interface OpenApiDocument {
|
|
36
|
+
openapi: '3.1.0';
|
|
37
|
+
info: OpenApiInfo;
|
|
38
|
+
servers?: OpenApiServer[];
|
|
39
|
+
paths: Record<string, Record<string, unknown>>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Generate an OpenAPI 3.1 document from contract services. Only methods exposed
|
|
43
|
+
* on HTTP are included — a method whose `expose` omits `'HTTP'` (an MCP/agent
|
|
44
|
+
* only tool) is skipped, matching the router's own route-building rule.
|
|
45
|
+
*/
|
|
46
|
+
export declare function generateOpenApiDocument(config: OpenApiConfig): OpenApiDocument;
|
|
47
|
+
/**
|
|
48
|
+
* A `RawRoute` that serves a generated OpenAPI document as JSON — mount it
|
|
49
|
+
* alongside contract routes to expose `/openapi.json`.
|
|
50
|
+
*/
|
|
51
|
+
export declare function openApiRoute(path: string, document: OpenApiDocument): RawRoute;
|
|
52
|
+
//# sourceMappingURL=openapi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../src/server/openapi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEpD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;IACxB,iFAAiF;IACjF,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC,CAAC;IAChE,oCAAoC;IACpC,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAChD;AAsED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,aAAa,GAAG,eAAe,CAgH9E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,QAAQ,CAM9E"}
|
|
@@ -6,8 +6,13 @@ export interface RateLimitConfig {
|
|
|
6
6
|
/**
|
|
7
7
|
* In-memory token-bucket rate limiter. `check(key, config)` consumes a token
|
|
8
8
|
* and returns whether the request is allowed; `remaining(key, config)` reports
|
|
9
|
-
* the count without consuming. Idle keys are swept on a 60-second timer
|
|
10
|
-
* `destroy()`
|
|
9
|
+
* the count without consuming. Idle keys are swept on a 60-second timer and the
|
|
10
|
+
* map is capped at `MAX_BUCKETS` (least-recently-used eviction); `destroy()`
|
|
11
|
+
* stops the timer.
|
|
12
|
+
*
|
|
13
|
+
* `config` is per-call — reusing one `key` with two different configs lets
|
|
14
|
+
* whichever call created the bucket fix its `max` / `window`. Key a bucket to
|
|
15
|
+
* one config (one limiter per limit) if that matters.
|
|
11
16
|
*/
|
|
12
17
|
export declare function createRateLimiter(): {
|
|
13
18
|
destroy: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/server/rate-limit.ts"],"names":[],"mappings":"AAOA,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;
|
|
1
|
+
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/server/rate-limit.ts"],"names":[],"mappings":"AAOA,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAeD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB;;eAQlB,MAAM,UAAU,eAAe,GAAG,OAAO;mBA6BrC,MAAM,UAAU,eAAe,GAAG,MAAM;EAO1D"}
|
package/dist/server/request.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* HTTP request helpers — header parsing, client identification, trace ids.
|
|
3
3
|
* Pure `Request → value` functions; no framework state.
|
|
4
4
|
*/
|
|
5
|
-
/** Compact, time-sortable id — base36 timestamp +
|
|
5
|
+
/** Compact, time-sortable id — base36 timestamp + a cryptographic suffix. */
|
|
6
6
|
export declare function generateTraceId(): string;
|
|
7
7
|
/**
|
|
8
8
|
* Trace id for a request: a trusted inbound `x-request-id` / `x-trace-id`
|
|
@@ -10,10 +10,33 @@ export declare function generateTraceId(): string;
|
|
|
10
10
|
* Shared by the router, the logger and any consumer that wants the same id.
|
|
11
11
|
*/
|
|
12
12
|
export declare function resolveTraceId(req: Request): string;
|
|
13
|
-
/**
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the real socket peer IP from the runtime — unspoofable, unlike a
|
|
15
|
+
* header. On Bun the server resolves it (`server.requestIP`); on Node / Deno
|
|
16
|
+
* the `srvx` adapter attaches `.ip` to the request. `undefined` when neither
|
|
17
|
+
* is available (the bare `createHandler` fetch with no server).
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveSocketIp(req: Request, server: unknown): string | undefined;
|
|
20
|
+
/** Options for `extractIp` / `getClientInfo`. */
|
|
21
|
+
export interface ClientIpOptions {
|
|
22
|
+
/**
|
|
23
|
+
* Trust `x-forwarded-for` / `x-real-ip` for the client IP. Enable only behind
|
|
24
|
+
* a proxy that overwrites them — they are client-controllable. Default
|
|
25
|
+
* `false`: the real socket IP (`socketIp`) is used instead.
|
|
26
|
+
*/
|
|
27
|
+
trustProxy?: boolean;
|
|
28
|
+
/** The real socket peer IP — see `resolveSocketIp`. */
|
|
29
|
+
socketIp?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The client IP for a request. With `trustProxy`, the `x-forwarded-for` /
|
|
33
|
+
* `x-real-ip` client wins (the server sits behind a proxy that rewrites them);
|
|
34
|
+
* otherwise the real, unspoofable socket peer (`socketIp`) is used. Returns
|
|
35
|
+
* `''` when nothing is known.
|
|
36
|
+
*/
|
|
37
|
+
export declare function extractIp(req: Request, options?: ClientIpOptions): string;
|
|
15
38
|
/** Client identity — IP + user-agent. The one place projects derive both. */
|
|
16
|
-
export declare function getClientInfo(req: Request): {
|
|
39
|
+
export declare function getClientInfo(req: Request, options?: ClientIpOptions): {
|
|
17
40
|
ipAddress?: string;
|
|
18
41
|
userAgent?: string;
|
|
19
42
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/server/request.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/server/request.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,6EAA6E;AAC7E,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CASnD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAejF;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,CAQ7E;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAC3B,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE,eAAoB,GAC5B;IACD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAKA;AAED,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAU5E"}
|
package/dist/server/router.d.ts
CHANGED
|
@@ -34,8 +34,10 @@ export declare function matchRawRoute(rawRoutes: RawRoute[], httpMethod: string,
|
|
|
34
34
|
params: Record<string, string>;
|
|
35
35
|
} | null;
|
|
36
36
|
/**
|
|
37
|
-
* Build a `RawRoute` that serves files from `dir` under `prefix`.
|
|
38
|
-
*
|
|
37
|
+
* Build a `RawRoute` that serves files from `dir` under `prefix`. Basic by
|
|
38
|
+
* design — no Range, no conditional requests; put a CDN in front for those.
|
|
39
|
+
* Rejects path traversal (including the percent-encoded form); 404 for a
|
|
40
|
+
* missing file. Uses `node:fs`, so it runs on both Bun and Node.
|
|
39
41
|
*/
|
|
40
42
|
export declare function staticRoute(prefix: string, dir: string): RawRoute;
|
|
41
43
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE/E,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,UAAU,CAAC;IACpB,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB;AAED,UAAU,UAAU;IAClB,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAED,+EAA+E;AAC/E,MAAM,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAqCD,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,QAAQ,CAmCjE;AAED,wBAAgB,UAAU,CACxB,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,UAAU,GAAG,IAAI,CAmBnB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAc7E;AAED,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAiBvD;AAID,wBAAgB,aAAa,CAC3B,SAAS,EAAE,QAAQ,EAAE,EACrB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,IAAI,CAyB5D;AAoBD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,CAmCjE"}
|
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Socket.IO server setup — the family WebSocket server boilerplate.
|
|
2
|
+
* Socket.IO server setup — the family WebSocket server boilerplate, runtime-aware.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* The engine differs per runtime, so the socket packages are loaded **lazily**
|
|
5
|
+
* (dynamic `import` inside the function) — a `type`-only import at the top would
|
|
6
|
+
* still be erased, but a top-level *value* import of `@socket.io/bun-engine`
|
|
7
|
+
* (Bun-only) would crash the whole `stitchkit/server` barrel on Node before any
|
|
8
|
+
* socket code runs. Lazy loading keeps the barrel Node-importable for apps that
|
|
9
|
+
* never use sockets.
|
|
8
10
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* - **Bun** — `@socket.io/bun-engine` + `io.bind(engine)`; returns the
|
|
12
|
+
* `websocket` handler for `Bun.serve` and a `/socket.io/*` route.
|
|
13
|
+
* - **Node** — `io.attach(server)` onto the `node:http.Server` exposed by
|
|
14
|
+
* `serveNode` (srvx `server.node.server`); Socket.IO owns the `upgrade` event.
|
|
15
|
+
*
|
|
16
|
+
* Connection handlers, rooms and handshake auth stay in the project.
|
|
13
17
|
*/
|
|
14
|
-
import { Server as
|
|
15
|
-
import { Server as
|
|
18
|
+
import type { Server as HttpServer } from 'node:http';
|
|
19
|
+
import type { Server as BunEngine } from '@socket.io/bun-engine';
|
|
20
|
+
import type { Server as SocketIOServer } from 'socket.io';
|
|
16
21
|
import type { SocketEventMap } from '../browser/socket-io';
|
|
17
22
|
import type { RawRoute } from './types';
|
|
23
|
+
import { type ComposedLane } from './websocket';
|
|
18
24
|
export interface SocketIOServerConfig {
|
|
19
25
|
/** CORS — the browser origin(s) allowed to open a socket. */
|
|
20
26
|
cors: {
|
|
@@ -23,7 +29,13 @@ export interface SocketIOServerConfig {
|
|
|
23
29
|
};
|
|
24
30
|
/** Socket.IO endpoint path. Default `/socket.io/`. */
|
|
25
31
|
path?: string;
|
|
26
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Transports offered to clients. Default `['websocket', 'polling']` on Bun;
|
|
34
|
+
* on Node the default is `['websocket']` — Socket.IO shares the HTTP server
|
|
35
|
+
* with srvx there, so its polling request-handler would collide with srvx's;
|
|
36
|
+
* WebSocket uses the separate `upgrade` event and does not. Configure the
|
|
37
|
+
* client with `transports: ['websocket']` to match.
|
|
38
|
+
*/
|
|
27
39
|
transports?: Array<'websocket' | 'polling'>;
|
|
28
40
|
/** Heartbeat: ms without a pong before the connection is dropped. Default `20000`. */
|
|
29
41
|
pingTimeout?: number;
|
|
@@ -33,10 +45,43 @@ export interface SocketIOServerConfig {
|
|
|
33
45
|
export interface SocketIOServerHandle<TServerEvents extends SocketEventMap, TClientEvents extends SocketEventMap> {
|
|
34
46
|
/** The typed Socket.IO server — attach `io.on('connection', ...)` handlers. */
|
|
35
47
|
io: SocketIOServer<TClientEvents, TServerEvents>;
|
|
36
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* WebSocket handler for `Bun.serve({ websocket })`. Real on Bun; on Node it is
|
|
50
|
+
* an inert no-op — sockets there are driven by the `node:http.Server`
|
|
51
|
+
* `upgrade` event via `serveNode({ socket })`, never by this field — so a Bun
|
|
52
|
+
* consumer can pass it unconditionally without a runtime guard.
|
|
53
|
+
*/
|
|
37
54
|
websocket: ReturnType<BunEngine['handler']>['websocket'];
|
|
38
|
-
/**
|
|
55
|
+
/**
|
|
56
|
+
* `/socket.io/*` route for `createServer({ rawRoutes })`. Real on Bun; on Node
|
|
57
|
+
* it is unused (sockets attach to the http.Server via `serveNode({ socket })`)
|
|
58
|
+
* and throws if it is ever mounted — so it is safe to spread into `rawRoutes`
|
|
59
|
+
* unconditionally on either runtime.
|
|
60
|
+
*/
|
|
39
61
|
route: RawRoute;
|
|
62
|
+
/**
|
|
63
|
+
* Node only — attach the Socket.IO server to the `node:http.Server` from
|
|
64
|
+
* `serveNode`. A no-op on Bun (the engine + route handle transport there).
|
|
65
|
+
* `serveNode({ socket })` calls this for you.
|
|
66
|
+
*/
|
|
67
|
+
attach(server: HttpServer): void;
|
|
40
68
|
}
|
|
41
|
-
export declare function createSocketIOServer<TServerEvents extends SocketEventMap, TClientEvents extends SocketEventMap>(config: SocketIOServerConfig): SocketIOServerHandle<TServerEvents, TClientEvents
|
|
69
|
+
export declare function createSocketIOServer<TServerEvents extends SocketEventMap, TClientEvents extends SocketEventMap>(config: SocketIOServerConfig): Promise<SocketIOServerHandle<TServerEvents, TClientEvents>>;
|
|
70
|
+
/**
|
|
71
|
+
* Wrap a Socket.IO handle's `websocket` as a catch-all {@link ComposedLane} for
|
|
72
|
+
* {@link composeWebSocketHandlers} — when a second, raw WebSocket lane shares
|
|
73
|
+
* the one `Bun.serve` websocket handler. It claims every socket no earlier
|
|
74
|
+
* (raw-marker) lane matched, so the engine owns whatever the raw lanes did not
|
|
75
|
+
* — and it never inspects the engine's opaque `ws.data`. Place it **last**.
|
|
76
|
+
*
|
|
77
|
+
* ```ts
|
|
78
|
+
* const ws = composeWebSocketHandlers([
|
|
79
|
+
* webSocketLane({ match: isPcmSocket, handlers: pcmHandlers }),
|
|
80
|
+
* socketIoLane(socket.websocket),
|
|
81
|
+
* ])
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* Bun-only (so is the raw-lane composition it serves).
|
|
85
|
+
*/
|
|
86
|
+
export declare function socketIoLane(websocket: SocketIOServerHandle<SocketEventMap, SocketEventMap>['websocket']): ComposedLane;
|
|
42
87
|
//# sourceMappingURL=socket-io.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket-io.d.ts","sourceRoot":"","sources":["../../src/server/socket-io.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"socket-io.d.ts","sourceRoot":"","sources":["../../src/server/socket-io.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,KAAK,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,KAAK,YAAY,EAAiB,MAAM,aAAa,CAAC;AAE/D,MAAM,WAAW,oBAAoB;IACnC,6DAA6D;IAC7D,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3D,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IAC5C,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB,CACnC,aAAa,SAAS,cAAc,EACpC,aAAa,SAAS,cAAc;IAEpC,+EAA+E;IAC/E,EAAE,EAAE,cAAc,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IACjD;;;;;OAKG;IACH,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IACzD;;;;;OAKG;IACH,KAAK,EAAE,QAAQ,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;CAClC;AAOD,wBAAsB,oBAAoB,CACxC,aAAa,SAAS,cAAc,EACpC,aAAa,SAAS,cAAc,EACpC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC,CA8D3F;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,oBAAoB,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC,WAAW,CAAC,GAC3E,YAAY,CAMd"}
|
package/dist/server/stream.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Turn an async generator into a Server-Sent Events `Response` — each yielded
|
|
3
3
|
* value is one JSON `data:` event, the stream ends with a `[DONE]` sentinel,
|
|
4
|
-
* and a thrown error is emitted as a final
|
|
4
|
+
* and a thrown error is emitted as a final error event. The error is
|
|
5
|
+
* normalised (`normalizeError`) so an internal failure never leaks its raw
|
|
6
|
+
* message into the stream.
|
|
5
7
|
*/
|
|
6
8
|
export declare function streamSSE(generator: AsyncGenerator<unknown>): Response;
|
|
7
9
|
/** Options for `parseSSE`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/server/stream.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/server/stream.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,QAAQ,CA2BtE;AAED,8BAA8B;AAC9B,MAAM,WAAW,eAAe;IAC9B,sFAAsF;IACtF,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACpD;AAED;;;;GAIG;AACH,wBAAuB,QAAQ,CAAC,CAAC,EAC/B,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,eAAe,GACxB,cAAc,CAAC,CAAC,CAAC,CAmCnB"}
|
package/dist/server/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ZodType } from 'zod';
|
|
2
|
-
import type { EndpointDef, HandlerContext, HttpMethod, RuntimeContext, Transport } from '../contract';
|
|
2
|
+
import type { EndpointDef, EndpointToolAnnotations, EndpointUiMeta, HandlerContext, HttpMethod, RuntimeContext, Transport } from '../contract';
|
|
3
3
|
import type { CorsConfig } from './middleware/cors';
|
|
4
4
|
type Prop<T, K extends string> = K extends keyof T ? T[K] : undefined;
|
|
5
5
|
type InferParams<E> = Prop<E, 'params'> extends ZodType<infer P> ? P : undefined;
|
|
@@ -22,6 +22,10 @@ export interface MethodDef<TParams = unknown, TInput = unknown, TOutput = unknow
|
|
|
22
22
|
inputSchema?: ZodType<TInput>;
|
|
23
23
|
outputSchema?: ZodType<TOutput>;
|
|
24
24
|
multipart?: string;
|
|
25
|
+
/** MCP Apps widget metadata — carried onto the MCP tool's `_meta.ui`. */
|
|
26
|
+
ui?: EndpointUiMeta;
|
|
27
|
+
/** MCP behavioural hints — carried onto the MCP tool's `annotations`. */
|
|
28
|
+
annotations?: EndpointToolAnnotations;
|
|
25
29
|
handler: (ctx: RuntimeContext) => Promise<TOutput> | TOutput;
|
|
26
30
|
}
|
|
27
31
|
export interface ServiceDef {
|
|
@@ -61,6 +65,11 @@ export interface RawRouteContext {
|
|
|
61
65
|
* Absent when the handler runs via the bare `createHandler` fetch.
|
|
62
66
|
*/
|
|
63
67
|
server?: BunServer;
|
|
68
|
+
/**
|
|
69
|
+
* Client IP — the real socket peer, or the `x-forwarded-for` client when
|
|
70
|
+
* `trustProxy` is set. Resolved by the framework; never spoofable by default.
|
|
71
|
+
*/
|
|
72
|
+
ipAddress?: string;
|
|
64
73
|
}
|
|
65
74
|
export interface RawRoute {
|
|
66
75
|
method: HttpMethod | 'ALL';
|
|
@@ -91,6 +100,13 @@ export interface HandlerConfig {
|
|
|
91
100
|
hooks?: LifecycleHooks;
|
|
92
101
|
logging?: boolean | StitchLogger;
|
|
93
102
|
traceId?: (req: Request) => string;
|
|
103
|
+
/**
|
|
104
|
+
* Trust the `x-forwarded-for` / `x-real-ip` headers for the client IP.
|
|
105
|
+
* These are client-controllable — enable only when the server runs behind a
|
|
106
|
+
* proxy that overwrites them. Default `false`: the IP a spoofable header
|
|
107
|
+
* carries never reaches `ctx.ipAddress`, a rate-limit key or an audit row.
|
|
108
|
+
*/
|
|
109
|
+
trustProxy?: boolean;
|
|
94
110
|
}
|
|
95
111
|
type BunServeOptions = Parameters<typeof Bun.serve>[0];
|
|
96
112
|
type BunWebSocketHandlers = BunServeOptions extends {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compose one Bun `websocket` handler from several independent lanes.
|
|
3
|
+
*
|
|
4
|
+
* `Bun.serve` accepts a **single** `websocket` handler. `@socket.io/bun-engine`
|
|
5
|
+
* claims it (via `createSocketIOServer().websocket`). A project that also wants a
|
|
6
|
+
* second, truly-raw binary WebSocket lane on the same server — a high-frequency
|
|
7
|
+
* stream (PCM, video, large transfers) with no Socket.IO framing — has to
|
|
8
|
+
* hand-compose that one handler: route each socket to the engine or to its own
|
|
9
|
+
* raw handlers.
|
|
10
|
+
*
|
|
11
|
+
* The fragile part is the discriminator. Routing *to* Socket.IO means asking
|
|
12
|
+
* "is this an engine socket?", which forces inspecting the engine's opaque
|
|
13
|
+
* `ws.data` — a brittle guard, hard to keep cast-free. The fix here is to invert
|
|
14
|
+
* it: a raw lane stamps **its own** marker onto `ws.data` at upgrade time and is
|
|
15
|
+
* matched positively; Socket.IO is simply the **fallback** lane (matched last,
|
|
16
|
+
* `() => true`). The engine's data is therefore never inspected.
|
|
17
|
+
*
|
|
18
|
+
* Cast-free: each lane carries a type-predicate `match` that narrows
|
|
19
|
+
* `ServerWebSocket<unknown>` to its own data type, so the typed handlers are
|
|
20
|
+
* invoked without a single `as`.
|
|
21
|
+
*
|
|
22
|
+
* Bun-only. On Node, Socket.IO drives sockets through the `node:http.Server`
|
|
23
|
+
* `upgrade` event (`serveNode({ socket })`) — a different model, and a raw lane
|
|
24
|
+
* there would be a separate upgrade handler, not this composition.
|
|
25
|
+
*/
|
|
26
|
+
import type { ServerWebSocket, WebSocketHandler } from 'bun';
|
|
27
|
+
/** One lane of a composed handler — a typed slice of the single Bun websocket. */
|
|
28
|
+
export interface WebSocketLane<TData> {
|
|
29
|
+
/**
|
|
30
|
+
* Type-predicate selecting the sockets this lane owns — usually a check on
|
|
31
|
+
* `ws.data` set at upgrade. As a predicate it narrows `ws` to the lane's data
|
|
32
|
+
* type, which is what keeps the handler call cast-free.
|
|
33
|
+
*/
|
|
34
|
+
match: (ws: ServerWebSocket<unknown>) => ws is ServerWebSocket<TData>;
|
|
35
|
+
/** Handlers for this lane's sockets — `ws.data` is fully typed as `TData`. */
|
|
36
|
+
handlers: WebSocketHandler<TData>;
|
|
37
|
+
}
|
|
38
|
+
/** A lane already bridged to the loose (`unknown`) data type, ready to compose. */
|
|
39
|
+
export interface ComposedLane {
|
|
40
|
+
match: (ws: ServerWebSocket<unknown>) => boolean;
|
|
41
|
+
handlers: WebSocketHandler<unknown>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Server-wide WebSocket tuning for the composed handler. Bun applies these to
|
|
45
|
+
* every socket on the server (they cannot be per-lane), so set them to the most
|
|
46
|
+
* permissive value across lanes — a raw binary lane typically needs a larger
|
|
47
|
+
* `maxPayloadLength` than Socket.IO's default (its `maxHttpBufferSize`, 1 MB).
|
|
48
|
+
*/
|
|
49
|
+
export type WebSocketComposeConfig = Omit<WebSocketHandler<unknown>, 'open' | 'message' | 'close' | 'drain' | 'ping' | 'pong'>;
|
|
50
|
+
/**
|
|
51
|
+
* Build a `ComposedLane` from typed handlers. Each callback is wrapped so it
|
|
52
|
+
* fires only for sockets the lane's `match` predicate claims — narrowing `ws`
|
|
53
|
+
* to `ServerWebSocket<TData>` for the typed handler. This is the one bridge from
|
|
54
|
+
* Bun's single untyped `websocket` to a typed, per-lane handler, and it holds
|
|
55
|
+
* no casts.
|
|
56
|
+
*/
|
|
57
|
+
export declare function webSocketLane<TData>(lane: WebSocketLane<TData>): ComposedLane;
|
|
58
|
+
/**
|
|
59
|
+
* Compose lanes into the single `websocket` handler for `createServer`. On each
|
|
60
|
+
* callback the first lane whose `match` claims the socket handles it — so put
|
|
61
|
+
* specific lanes (raw markers) first and the catch-all (Socket.IO,
|
|
62
|
+
* `socketIoLane`) last. `config` carries the server-wide tuning.
|
|
63
|
+
*
|
|
64
|
+
* ```ts
|
|
65
|
+
* const ws = composeWebSocketHandlers(
|
|
66
|
+
* [webSocketLane({ match: isPcmSocket, handlers: pcmHandlers }), socketIoLane(socket.websocket)],
|
|
67
|
+
* { maxPayloadLength: 16 * 1024 * 1024 },
|
|
68
|
+
* )
|
|
69
|
+
* createServer({ websocket: ws, rawRoutes: [socket.route, pcmUpgradeRoute] })
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare function composeWebSocketHandlers(lanes: ComposedLane[], config?: WebSocketComposeConfig): WebSocketHandler<unknown>;
|
|
73
|
+
//# sourceMappingURL=websocket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/server/websocket.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAC;AAE7D,kFAAkF;AAClF,MAAM,WAAW,aAAa,CAAC,KAAK;IAClC;;;;OAIG;IACH,KAAK,EAAE,CAAC,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC;IACtE,8EAA8E;IAC9E,QAAQ,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC;CACnC;AAED,mFAAmF;AACnF,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,CAAC,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC;IACjD,QAAQ,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;CACrC;AAED;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,gBAAgB,CAAC,OAAO,CAAC,EACzB,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CACzD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,YAAY,CAyB7E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,YAAY,EAAE,EACrB,MAAM,CAAC,EAAE,sBAAsB,GAC9B,gBAAgB,CAAC,OAAO,CAAC,CAyB3B"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turn a CLI `argv` slice into the flat argument object `executeToolMethod`
|
|
3
|
+
* parses — the CLI transport's front half, the counterpart of how the HTTP
|
|
4
|
+
* transport slices a `Request`.
|
|
5
|
+
*
|
|
6
|
+
* Two jobs the other transports never face:
|
|
7
|
+
* 1. **Reserved options.** `--json`, `--wait`, `--output-dir`, … are CLI
|
|
8
|
+
* behaviour, not tool arguments — they are stripped before the rest is read
|
|
9
|
+
* as tool args.
|
|
10
|
+
* 2. **String → typed coercion.** Every argv token is a string; the tool's Zod
|
|
11
|
+
* schema says what each field should be. We coerce primitives here
|
|
12
|
+
* (`--count 5` → `5`, `--flag` → `true`) and leave array / object values as
|
|
13
|
+
* strings for `executeToolMethod`'s `coerceJson` pass (the same path the MCP
|
|
14
|
+
* transport uses for an LLM's double-serialized JSON).
|
|
15
|
+
*
|
|
16
|
+
* The advertised schema is never mutated — coercion operates on the arguments,
|
|
17
|
+
* so a CLI call validates against the exact same contract schema an HTTP or MCP
|
|
18
|
+
* call does (ADR 0014 parity).
|
|
19
|
+
*/
|
|
20
|
+
import { z } from 'zod';
|
|
21
|
+
/** CLI-behaviour flags, parsed out of argv before the tool arguments. */
|
|
22
|
+
export interface CliRunOptions {
|
|
23
|
+
/** `--json` — emit raw JSON on stdout for piping. */
|
|
24
|
+
json: boolean;
|
|
25
|
+
/** `--wait` — block-poll an async result to a terminal state. */
|
|
26
|
+
wait: boolean;
|
|
27
|
+
/** `--wait-timeout <seconds>` — override the poll timeout. */
|
|
28
|
+
waitTimeout?: number;
|
|
29
|
+
/** `--output-dir <dir>` — download result media into this directory. */
|
|
30
|
+
outputDir?: string;
|
|
31
|
+
/** `--quiet` — suppress non-essential stderr chatter. */
|
|
32
|
+
quiet: boolean;
|
|
33
|
+
/** `--dry-run` — print the resolved call instead of executing it. */
|
|
34
|
+
dryRun: boolean;
|
|
35
|
+
/** `--help` / `-h` — print usage for the command. */
|
|
36
|
+
help: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface ParsedCliArgs {
|
|
39
|
+
/** The flat tool-argument object handed to `executeToolMethod`. */
|
|
40
|
+
toolArgs: Record<string, unknown>;
|
|
41
|
+
/** The CLI-behaviour flags. */
|
|
42
|
+
options: CliRunOptions;
|
|
43
|
+
}
|
|
44
|
+
type FieldKind = 'boolean' | 'number' | 'bigint' | 'date' | 'string' | 'enum' | 'array' | 'object' | 'other';
|
|
45
|
+
interface FieldInfo {
|
|
46
|
+
kind: FieldKind;
|
|
47
|
+
/** Element kind for an `array` field — drives per-element coercion. */
|
|
48
|
+
elementKind?: FieldKind;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Map a merged tool schema to per-field kind info — what each `--flag` should
|
|
52
|
+
* coerce to. A non-object schema (a union) yields an empty map: every value is
|
|
53
|
+
* left as a string and the schema validates it.
|
|
54
|
+
*/
|
|
55
|
+
export declare function describeSchemaFields(schema: z.ZodType | undefined): Map<string, FieldInfo>;
|
|
56
|
+
/**
|
|
57
|
+
* Parse a command's argv slice (everything after the command name) against its
|
|
58
|
+
* merged tool schema.
|
|
59
|
+
*
|
|
60
|
+
* Supported forms:
|
|
61
|
+
* - `--key value` / `--key=value` / `-` repeated for arrays
|
|
62
|
+
* - `--flag` boolean presence, `--no-flag` to negate
|
|
63
|
+
* - `--a.b=c` dotted path → nested object (loose-coerced leaf)
|
|
64
|
+
* - positional args fill non-boolean fields in schema-declaration order
|
|
65
|
+
*/
|
|
66
|
+
export declare function parseCliArgs(argv: string[], schema: z.ZodType | undefined): ParsedCliArgs;
|
|
67
|
+
export {};
|
|
68
|
+
//# sourceMappingURL=cli-args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-args.d.ts","sourceRoot":"","sources":["../../src/tools/cli-args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,yEAAyE;AACzE,MAAM,WAAW,aAAa;IAC5B,qDAAqD;IACrD,IAAI,EAAE,OAAO,CAAC;IACd,iEAAiE;IACjE,IAAI,EAAE,OAAO,CAAC;IACd,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,KAAK,EAAE,OAAO,CAAC;IACf,qEAAqE;IACrE,MAAM,EAAE,OAAO,CAAC;IAChB,qDAAqD;IACrD,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,+BAA+B;IAC/B,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,KAAK,SAAS,GACV,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,MAAM,GACN,OAAO,GACP,QAAQ,GACR,OAAO,CAAC;AAEZ,UAAU,SAAS;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB,uEAAuE;IACvE,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB;AA6BD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAa1F;AAmFD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,GAAG,aAAa,CAkIzF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render a `ToolResult` for the CLI surface and map it to a process exit code.
|
|
3
|
+
*
|
|
4
|
+
* Output is JSON — the CLI's audience is agents (Skills via Bash), scripts and
|
|
5
|
+
* `| jq`, for which structured JSON is the right shape, not a hand-formatted
|
|
6
|
+
* table. The default is pretty-printed (indented, the same shape an MCP tool
|
|
7
|
+
* returns); `--json` switches to a compact single line for piping.
|
|
8
|
+
*
|
|
9
|
+
* stdout is reserved for that result; an error goes to stderr as the same
|
|
10
|
+
* model-facing `{ error, details, _hint }` object the MCP / agent transports
|
|
11
|
+
* return (`formatToolError`), so a script can keep `2>/dev/null` clean while
|
|
12
|
+
* still parsing a success.
|
|
13
|
+
*/
|
|
14
|
+
import type { ToolResult } from './execute';
|
|
15
|
+
/** Map a `ToolResult.code` to a process exit code. */
|
|
16
|
+
export type ExitCodeMap = Record<string, number>;
|
|
17
|
+
/**
|
|
18
|
+
* Conventional exit codes — `0` success, distinct non-zero per error class so a
|
|
19
|
+
* script can branch on `$?`. Merged under any `CliConfig.exitCodes` override.
|
|
20
|
+
*/
|
|
21
|
+
export declare const DEFAULT_EXIT_CODES: ExitCodeMap;
|
|
22
|
+
export interface CliWriters {
|
|
23
|
+
stdout: (text: string) => void;
|
|
24
|
+
stderr: (text: string) => void;
|
|
25
|
+
}
|
|
26
|
+
export interface EmitOptions {
|
|
27
|
+
/** Compact single-line JSON (for `| jq` / scripts); otherwise pretty-printed. */
|
|
28
|
+
json: boolean;
|
|
29
|
+
toolName: string;
|
|
30
|
+
errorHint?: (toolName: string, errorCode: string) => string | null;
|
|
31
|
+
exitCodes?: ExitCodeMap;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Write a result to the right stream and return the exit code. Success → JSON
|
|
35
|
+
* on stdout (pretty by default, compact with `--json`), exit `0`. Failure → the
|
|
36
|
+
* error JSON on stderr, exit per the code map (unknown code → `1`).
|
|
37
|
+
*/
|
|
38
|
+
export declare function emitResult(result: ToolResult, writers: CliWriters, opts: EmitOptions): number;
|
|
39
|
+
//# sourceMappingURL=cli-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-format.d.ts","sourceRoot":"","sources":["../../src/tools/cli-format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAG5C,sDAAsD;AACtD,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAUhC,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,WAAW;IAC1B,iFAAiF;IACjF,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACnE,SAAS,CAAC,EAAE,WAAW,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,UAAU,EACnB,IAAI,EAAE,WAAW,GAChB,MAAM,CAeR"}
|