stitchkit 0.17.0 → 0.19.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/dist/browser/client.d.ts.map +1 -1
- package/dist/browser/http.d.ts +9 -0
- package/dist/browser/http.d.ts.map +1 -1
- package/dist/browser/socket-io.d.ts.map +1 -1
- package/dist/cli.js +3 -3
- package/dist/contract/errors-factory.d.ts +18 -0
- package/dist/contract/errors-factory.d.ts.map +1 -0
- package/dist/contract/factory.d.ts +36 -0
- package/dist/contract/factory.d.ts.map +1 -0
- package/dist/contract/index.d.ts +2 -0
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +6 -1
- package/dist/contract/pagination.d.ts.map +1 -1
- package/dist/index-809wc1tt.js +18 -0
- package/dist/{index-tm7dqzxc.js → index-c7nyw0yt.js} +9 -9
- package/dist/{index-fwqnkc90.js → index-dzx781tm.js} +5 -41
- package/dist/index-khwedj16.js +40 -0
- package/dist/{index-ktn76xz0.js → index-ng2v2ts4.js} +17 -1
- package/dist/index-tje0q6gp.js +44 -0
- package/dist/{index-6k6y7wat.js → index-wpbn133x.js} +13 -50
- package/dist/{index-yzac2zbh.js → index-x62gnfsk.js} +50 -9
- package/dist/{index-akv8rk4w.js → index-xmncnw8z.js} +2 -2
- package/dist/{index-yv93m4yr.js → index-ynnh9x6h.js} +11 -29
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +141 -73
- package/dist/internal/base64url.d.ts +16 -0
- package/dist/internal/base64url.d.ts.map +1 -0
- package/dist/node.js +6 -4
- package/dist/observability/index.js +9 -7
- package/dist/react/entity-cache.d.ts +54 -0
- package/dist/react/entity-cache.d.ts.map +1 -0
- package/dist/react.d.ts +1 -0
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +74 -0
- package/dist/server/create.d.ts.map +1 -1
- package/dist/server/error-hook.d.ts +56 -0
- package/dist/server/error-hook.d.ts.map +1 -0
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +33 -7
- package/dist/server/middleware/auth.d.ts.map +1 -1
- package/dist/server/middleware/cors.d.ts +13 -0
- package/dist/server/middleware/cors.d.ts.map +1 -1
- package/dist/server/middleware/pkce.d.ts +0 -6
- package/dist/server/middleware/pkce.d.ts.map +1 -1
- package/dist/server/router.d.ts +0 -2
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/types.d.ts +0 -8
- package/dist/server/types.d.ts.map +1 -1
- package/dist/tools/agent.d.ts +2 -2
- package/dist/tools/agent.d.ts.map +1 -1
- package/dist/tools/cli-format.d.ts +2 -2
- package/dist/tools/cli-format.d.ts.map +1 -1
- package/dist/tools/cli.d.ts +2 -2
- package/dist/tools/cli.d.ts.map +1 -1
- package/dist/tools/execute.d.ts +7 -0
- package/dist/tools/execute.d.ts.map +1 -1
- package/dist/tools/list-names.d.ts +33 -0
- package/dist/tools/list-names.d.ts.map +1 -0
- package/dist/tools/mcp.d.ts +3 -3
- package/dist/tools/mcp.d.ts.map +1 -1
- package/dist/tools/mount.d.ts +3 -3
- package/dist/tools/mount.d.ts.map +1 -1
- package/dist/tools/oauth-metadata.d.ts.map +1 -1
- package/dist/tools/oauth-provider.d.ts.map +1 -1
- package/dist/tools/tool-logger.d.ts +31 -0
- package/dist/tools/tool-logger.d.ts.map +1 -0
- package/dist/tools/transports.d.ts +28 -0
- package/dist/tools/transports.d.ts.map +1 -0
- package/dist/tools.d.ts +4 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +114 -25
- package/llms-full.txt +307 -7
- package/package.json +1 -1
package/llms-full.txt
CHANGED
|
@@ -33,19 +33,23 @@ realtime, `@tanstack/react-query` + `react-query-kit` for React). See
|
|
|
33
33
|
|
|
34
34
|
## Entrypoints
|
|
35
35
|
|
|
36
|
-
stitchkit ships
|
|
36
|
+
stitchkit ships eight entrypoints. Each is import-safe for one environment —
|
|
37
37
|
keeping server-only code (`Bun.serve`, the MCP SDK) out of browser bundles.
|
|
38
38
|
|
|
39
39
|
| Import | Use in | Holds |
|
|
40
40
|
|--------|--------|-------|
|
|
41
41
|
| `stitchkit` | browser **and** server | `defineContract`, `createClient`, `createHttpClient`, `createSocketIOClient`, `parseSSE`, the error model |
|
|
42
42
|
| `stitchkit/contract` | browser **and** server | the contract layer alone — `defineContract`, errors, pagination |
|
|
43
|
-
| `stitchkit/server` | server | `createServer`, `implement`, hooks, auth, Socket.IO server, server primitives |
|
|
44
|
-
| `stitchkit/
|
|
43
|
+
| `stitchkit/server` | server (Bun) | `createServer`, `implement`, hooks, auth, Socket.IO server, server primitives |
|
|
44
|
+
| `stitchkit/node` | server (Node ≥ 22) | `serveNode` + the runtime-agnostic core — the Node mirror of `/server` |
|
|
45
|
+
| `stitchkit/tools` | server | `createMcpHandler`, `mountMcp`, `mountAgent`, the OAuth provider, native tools |
|
|
46
|
+
| `stitchkit/cli` | server | `createCli` — the CLI transport, light (no MCP SDK / `ai`) |
|
|
47
|
+
| `stitchkit/observability` | server | the audit layer — `createAuditHook`, trace context, sanitisation |
|
|
45
48
|
| `stitchkit/react` | browser | `createCursorQuery`, `createCacheBridge` |
|
|
46
49
|
|
|
47
50
|
Rule of thumb: browser code imports `stitchkit` and `stitchkit/react`; server
|
|
48
|
-
code adds `stitchkit/server` and `stitchkit/tools`.
|
|
51
|
+
code adds `stitchkit/server` (or `stitchkit/node` on Node) and `stitchkit/tools`.
|
|
52
|
+
The full export list of each is in the [API reference](../api/reference.md).
|
|
49
53
|
|
|
50
54
|
## Project layout
|
|
51
55
|
|
|
@@ -268,6 +272,26 @@ For the client, an endpoint's argument type is the schema's **input** type
|
|
|
268
272
|
present (required) in the handler's parsed `ctx.input`. The contract handles the
|
|
269
273
|
two type views; you do not.
|
|
270
274
|
|
|
275
|
+
### Query input (`GET` / `DELETE`)
|
|
276
|
+
|
|
277
|
+
`GET` and `DELETE` carry their input as the **query string**, and a query
|
|
278
|
+
string can only encode flat values. An input field on these verbs must be a
|
|
279
|
+
`string`, `number`, `boolean`, or an array of `string` / `number` (repeated
|
|
280
|
+
query keys). A **nested object has no canonical query encoding** — the typed
|
|
281
|
+
client throws on one instead of sending a silently incomplete request:
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
// input: z.object({ q: z.string(), filter: z.object({ … }) }) on a GET
|
|
285
|
+
await api.search({ q: 'x', filter: { status: 'active' } })
|
|
286
|
+
// ✗ throws: GET /: input field "filter" is a nested object — it cannot travel
|
|
287
|
+
// as a query parameter
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Flatten the field (`status: 'active'`) or move the operation to a body verb
|
|
291
|
+
(`POST`). Remember the server parses query values from **strings** — use
|
|
292
|
+
`z.coerce.number()` / `z.coerce.boolean()` in a query-input schema for
|
|
293
|
+
non-string fields.
|
|
294
|
+
|
|
271
295
|
## Transports
|
|
272
296
|
|
|
273
297
|
By default an endpoint is exposed on **every** surface — HTTP, MCP and agent
|
|
@@ -293,9 +317,9 @@ file upload is not a tool call.
|
|
|
293
317
|
|
|
294
318
|
## `toolName`
|
|
295
319
|
|
|
296
|
-
When an endpoint is exposed as a tool, its name defaults to
|
|
297
|
-
(`users` + `create` ⇒ `
|
|
298
|
-
name:
|
|
320
|
+
When an endpoint is exposed as a tool, its name defaults to a verb-aware
|
|
321
|
+
derivation from the method key + prefix (`users` + `create` ⇒ `create_user`,
|
|
322
|
+
`users` + `list` ⇒ `list_users`). Set `toolName` for an explicit, stable name:
|
|
299
323
|
|
|
300
324
|
```ts
|
|
301
325
|
{ method: 'POST', path: '/', desc: 'Create a user', toolName: 'create_user', /* … */ }
|
|
@@ -407,6 +431,21 @@ for every endpoint that declares none. Scopes are free strings — the framework
|
|
|
407
431
|
attaches no meaning, your auth hook does. See
|
|
408
432
|
[Auth & errors](./auth-and-errors.md).
|
|
409
433
|
|
|
434
|
+
A plain `defineContract` defaults a missing `scope` to `'public'` — forget it and
|
|
435
|
+
the endpoint is public (fail-open). If every contract in your app must be scoped,
|
|
436
|
+
`createContractFactory` binds your scope vocabulary once and makes `scope`
|
|
437
|
+
**required and typed** — a missing or mistyped scope is a compile error:
|
|
438
|
+
|
|
439
|
+
```ts
|
|
440
|
+
// app: one line, once
|
|
441
|
+
export const { defineContract } = createContractFactory<'public' | 'user' | 'admin'>()
|
|
442
|
+
|
|
443
|
+
// scope is now mandatory and checked against the union
|
|
444
|
+
export const users = defineContract({ prefix: 'users', scope: 'user' }, { … })
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
The vocabulary is yours; the returned contracts are ordinary `ContractDef`s.
|
|
448
|
+
|
|
410
449
|
## One source of truth
|
|
411
450
|
|
|
412
451
|
A contract is plain data — no classes, no decorators, no codegen. It is imported
|
|
@@ -831,10 +870,16 @@ const http = createHttpClient({ baseUrl: '/api' })
|
|
|
831
870
|
| `headers` | — | extra headers — an object, or a function re-run per request |
|
|
832
871
|
| `authEndpoints` | `['auth/']` | paths that should **not** emit `unauthorized` on 401 |
|
|
833
872
|
| `parseError` | built-in | map an error body to `{ code, message, details, hint }` |
|
|
873
|
+
| `trace` | `false` | emit a W3C `traceparent` header on every request |
|
|
834
874
|
|
|
835
875
|
`headers` as a function is the hook for runtime tokens — a bearer token or any
|
|
836
876
|
short-lived credential — re-evaluated on every request.
|
|
837
877
|
|
|
878
|
+
`trace: true` mints a fresh root trace per request. The stitchkit server
|
|
879
|
+
[continues an inbound `traceparent`](./observability.md#trace-context), so the
|
|
880
|
+
browser call, the HTTP handler and every nested tool call share one trace id
|
|
881
|
+
end-to-end. A `traceparent` you set yourself (via `headers`) always wins.
|
|
882
|
+
|
|
838
883
|
Retry is deliberately conservative: only a connection that never landed (a
|
|
839
884
|
network error), only on idempotent `GET`. A server that *responded* with a 5xx
|
|
840
885
|
is the data layer's call (TanStack Query), not the transport's — retrying in
|
|
@@ -1053,6 +1098,27 @@ to a verb-aware name from the method + prefix (`list` → `list_widgets`, `get`
|
|
|
1053
1098
|
`get_widget`); set `toolName` for an explicit one. See
|
|
1054
1099
|
[Contracts → transports](./contracts.md#transports).
|
|
1055
1100
|
|
|
1101
|
+
### Pinning tool names — `listToolNames`
|
|
1102
|
+
|
|
1103
|
+
Derived tool names are part of your public surface — an MCP client config or an
|
|
1104
|
+
agent prompt refers to them by string. `listToolNames(services)` resolves every
|
|
1105
|
+
tool name your services expose (the exact resolver the mounts use), with its
|
|
1106
|
+
`(service, method)` identity and transports, sorted — a stable shape to
|
|
1107
|
+
snapshot:
|
|
1108
|
+
|
|
1109
|
+
```ts
|
|
1110
|
+
import { listToolNames } from 'stitchkit/tools'
|
|
1111
|
+
|
|
1112
|
+
test('tool names have not drifted', () => {
|
|
1113
|
+
expect(listToolNames(services)).toMatchSnapshot()
|
|
1114
|
+
})
|
|
1115
|
+
```
|
|
1116
|
+
|
|
1117
|
+
A stitchkit upgrade (or a contract refactor) that would shift a derived name
|
|
1118
|
+
now fails this test instead of silently breaking the clients that call the
|
|
1119
|
+
tool. It is also the mechanical diff when migrating a service: run it before
|
|
1120
|
+
and after, compare.
|
|
1121
|
+
|
|
1056
1122
|
## MCP — `createMcpHandler`
|
|
1057
1123
|
|
|
1058
1124
|
`createMcpHandler` builds a complete Streamable-HTTP MCP server as a single
|
|
@@ -1393,6 +1459,25 @@ const handleMcp = createMcpHandler({
|
|
|
1393
1459
|
})
|
|
1394
1460
|
```
|
|
1395
1461
|
|
|
1462
|
+
## Logging tool calls — `createToolLogger`
|
|
1463
|
+
|
|
1464
|
+
Every tool mount fires an `afterToolCall` hook. `createToolLogger` is a ready
|
|
1465
|
+
preset for it — one line logs each call (ok / failed, duration, which endpoint,
|
|
1466
|
+
keyed by the endpoint's stable `serviceName` / `key` identity):
|
|
1467
|
+
|
|
1468
|
+
```ts
|
|
1469
|
+
import { createToolLogger } from 'stitchkit/tools'
|
|
1470
|
+
|
|
1471
|
+
mountMcp(server, services, { hooks: createToolLogger() })
|
|
1472
|
+
// [tool] ok list_widgets (widgets.list) 12ms
|
|
1473
|
+
// [tool] warn get_widget (widgets.get) NOT_FOUND 4ms
|
|
1474
|
+
```
|
|
1475
|
+
|
|
1476
|
+
Pass `log` to redirect the line, or `onRecord` to feed a metrics sink the
|
|
1477
|
+
structured `ToolCallRecord`. For a boot-time picture of what is exposed where,
|
|
1478
|
+
`summarizeTransports(services)` returns per-transport operation counts (HTTP /
|
|
1479
|
+
MCP / AGENT / CLI) for you to log.
|
|
1480
|
+
|
|
1396
1481
|
## One handler, three callers
|
|
1397
1482
|
|
|
1398
1483
|
A contract handler runs the same for an HTTP request, an MCP tool call and an
|
|
@@ -1811,6 +1896,35 @@ onSuccess: () => bridge.markFresh(['notes'])
|
|
|
1811
1896
|
to the socket and call `queryClient` directly. The bridge just centralises the
|
|
1812
1897
|
event-to-cache mapping and the echo guard.
|
|
1813
1898
|
|
|
1899
|
+
### Entity cache handlers
|
|
1900
|
+
|
|
1901
|
+
The created / updated / deleted events of one entity almost always patch the
|
|
1902
|
+
cache the same way: prepend to the list, replace by id, remove by id — plus the
|
|
1903
|
+
detail query. `createEntityCacheHandlers` builds those three handlers from a
|
|
1904
|
+
small config, so you wire them onto the bridge instead of hand-rolling the
|
|
1905
|
+
updater per entity:
|
|
1906
|
+
|
|
1907
|
+
```ts
|
|
1908
|
+
import { createEntityCacheHandlers } from 'stitchkit/react'
|
|
1909
|
+
|
|
1910
|
+
const widgetCache = createEntityCacheHandlers<Widget>({
|
|
1911
|
+
getId: (w) => w.id,
|
|
1912
|
+
listKey: ['widgets'],
|
|
1913
|
+
detailKey: (id) => ['widgets', id],
|
|
1914
|
+
})
|
|
1915
|
+
|
|
1916
|
+
createCacheBridge({ socket, queryClient, handlers: {
|
|
1917
|
+
widgetCreated: widgetCache.created,
|
|
1918
|
+
widgetUpdated: widgetCache.updated,
|
|
1919
|
+
widgetDeleted: widgetCache.deleted,
|
|
1920
|
+
}})
|
|
1921
|
+
```
|
|
1922
|
+
|
|
1923
|
+
It patches stitchkit's `Paginated<T>` list envelope (plain or an infinite list
|
|
1924
|
+
of pages) and honours the same `isFresh` echo guard. It deliberately does **not**
|
|
1925
|
+
flatten pages or add a `useAllX` surface — flattening stays in the component;
|
|
1926
|
+
this only keeps the cache correct.
|
|
1927
|
+
|
|
1814
1928
|
## Raw binary lane (Bun)
|
|
1815
1929
|
|
|
1816
1930
|
Socket.IO carries binary fine — for most streams a binary event (`pcm(frame)`)
|
|
@@ -2195,6 +2309,54 @@ onError: (ctx, err) => {
|
|
|
2195
2309
|
}
|
|
2196
2310
|
```
|
|
2197
2311
|
|
|
2312
|
+
## Domain errors — `defineErrors`
|
|
2313
|
+
|
|
2314
|
+
Declaring your app's error codes once gives you typed throwers on the server and
|
|
2315
|
+
a code table the client matches with autocomplete — instead of reading the raw
|
|
2316
|
+
`message` string (which breaks the moment a code expects a string but gets an
|
|
2317
|
+
object):
|
|
2318
|
+
|
|
2319
|
+
```ts
|
|
2320
|
+
export const { errors, codes, isCode } = defineErrors({
|
|
2321
|
+
SESSION_NOT_FOUND: 404,
|
|
2322
|
+
QUOTA_EXCEEDED: 429,
|
|
2323
|
+
})
|
|
2324
|
+
|
|
2325
|
+
// server — a typed thrower, the right HTTP status baked in
|
|
2326
|
+
throw errors.SESSION_NOT_FOUND('no such session')
|
|
2327
|
+
|
|
2328
|
+
// client — match the code, never a magic string
|
|
2329
|
+
if (err instanceof ApiError && err.code === codes.SESSION_NOT_FOUND) { … }
|
|
2330
|
+
```
|
|
2331
|
+
|
|
2332
|
+
The `code` rides through unchanged in both the HTTP envelope and the MCP tool
|
|
2333
|
+
result, so one vocabulary covers every transport. The codes are yours; the core
|
|
2334
|
+
stays domain-free.
|
|
2335
|
+
|
|
2336
|
+
## `createErrorHook`
|
|
2337
|
+
|
|
2338
|
+
`createErrorHook` is the code-map above, packaged — you supply the exhaustive
|
|
2339
|
+
`codeMap` and the envelope shape, it does the normalisation (including the
|
|
2340
|
+
never-leak-an-internal-message rule for a raw throw):
|
|
2341
|
+
|
|
2342
|
+
```ts
|
|
2343
|
+
const onError = createErrorHook({
|
|
2344
|
+
codeMap: {
|
|
2345
|
+
BAD_REQUEST: 'bad_request', VALIDATION_ERROR: 'bad_request',
|
|
2346
|
+
UNAUTHORIZED: 'unauthenticated', FORBIDDEN: 'forbidden',
|
|
2347
|
+
NOT_FOUND: 'not_found', METHOD_NOT_ALLOWED: 'not_found',
|
|
2348
|
+
CONFLICT: 'conflict', RATE_LIMITED: 'rate_limited',
|
|
2349
|
+
INTERNAL_SERVER_ERROR: 'internal',
|
|
2350
|
+
} satisfies Record<StitchErrorCode, string>,
|
|
2351
|
+
render: (info) => ({ ok: false, error: { code: info.code, message: info.message } }),
|
|
2352
|
+
})
|
|
2353
|
+
|
|
2354
|
+
createServer({ services, hooks: { onError } })
|
|
2355
|
+
```
|
|
2356
|
+
|
|
2357
|
+
Codes you threw yourself (not stitchkit's) pass through `codeMap` unchanged; the
|
|
2358
|
+
`satisfies Record<StitchErrorCode, …>` keeps the map exhaustive across upgrades.
|
|
2359
|
+
|
|
2198
2360
|
|
|
2199
2361
|
==============================================================================
|
|
2200
2362
|
# Guide: Observability (docs/guide/observability.md)
|
|
@@ -2361,6 +2523,17 @@ You rarely call the trace functions directly — `wrapInRequestContext` and
|
|
|
2361
2523
|
`parseTraceparent`, `formatTraceparent`, `childSpan`) for when you need to
|
|
2362
2524
|
propagate a `traceparent` onward to another service.
|
|
2363
2525
|
|
|
2526
|
+
The browser side starts the trace:
|
|
2527
|
+
[`createHttpClient({ trace: true })`](./client.md#httpclientconfig) emits a
|
|
2528
|
+
fresh root `traceparent` on every request, which the server then continues. The
|
|
2529
|
+
trace helpers themselves are browser-safe and also exported from the root
|
|
2530
|
+
`stitchkit` entry — a custom client can format its own header.
|
|
2531
|
+
|
|
2532
|
+
The default CORS allow-list already permits `traceparent` / `tracestate`, so a
|
|
2533
|
+
cross-origin `trace: true` client works out of the box. If you set a custom
|
|
2534
|
+
`cors.headers`, extend `DEFAULT_CORS_ALLOW_HEADERS` rather than replacing it, or
|
|
2535
|
+
the preflight will reject the trace header.
|
|
2536
|
+
|
|
2364
2537
|
> **Span ids live in the request context, not on `ctx`.** The handler `ctx`
|
|
2365
2538
|
> carries a single `traceId`; the full `{ traceId, spanId, parentSpanId }` is on
|
|
2366
2539
|
> the observability request context. To stamp `spanId` / `parentSpanId` into an
|
|
@@ -2859,6 +3032,20 @@ The browser-and-server entrypoint. Re-exports everything from
|
|
|
2859
3032
|
| `RetainedTopics` | _type_ | the `createRetainedTopics` handle |
|
|
2860
3033
|
| `ParseSSEOptions` | _type_ | options for `parseSSE` |
|
|
2861
3034
|
|
|
3035
|
+
### Trace (client)
|
|
3036
|
+
|
|
3037
|
+
Browser-safe W3C trace helpers — the same functions as on
|
|
3038
|
+
[`stitchkit/observability`](#stitchkitobservability), re-exported so a client
|
|
3039
|
+
can emit / propagate a `traceparent` (see `HttpClientConfig.trace`).
|
|
3040
|
+
|
|
3041
|
+
| Export | Kind | Summary |
|
|
3042
|
+
|--------|------|---------|
|
|
3043
|
+
| `createTraceContext` | function | a fresh root trace |
|
|
3044
|
+
| `formatTraceparent` | function | render a `traceparent` header value |
|
|
3045
|
+
| `parseTraceparent` | function | parse a `traceparent` header |
|
|
3046
|
+
| `childSpan` | function | a child span of a parent trace |
|
|
3047
|
+
| `TraceContext` | _type_ | `{ traceId, spanId, parentSpanId? }` |
|
|
3048
|
+
|
|
2862
3049
|
---
|
|
2863
3050
|
|
|
2864
3051
|
## `stitchkit/contract`
|
|
@@ -2871,6 +3058,8 @@ from the root `stitchkit`.
|
|
|
2871
3058
|
| Export | Kind | Summary |
|
|
2872
3059
|
|--------|------|---------|
|
|
2873
3060
|
| `defineContract` | function | declare a contract — [guide](../guide/contracts.md#definecontract) |
|
|
3061
|
+
| `createContractFactory` | function | a `defineContract` with a required, typed `scope` — [guide](../guide/contracts.md#scope) |
|
|
3062
|
+
| `ScopedDefineContract` | _type_ | the `defineContract` `createContractFactory` returns |
|
|
2874
3063
|
| `ALL_TRANSPORTS` | constant | `['HTTP', 'MCP', 'AGENT', 'CLI']` |
|
|
2875
3064
|
| `ContractDef` | _type_ | a defined contract |
|
|
2876
3065
|
| `ContractMeta` | _type_ | a contract's `prefix` + optional `scope` |
|
|
@@ -2887,6 +3076,8 @@ from the root `stitchkit`.
|
|
|
2887
3076
|
| `ScopedEndpointFn` | _type_ | one method's signature with the consumed keys folded in |
|
|
2888
3077
|
| `MultipartFile` | _type_ | a `multipart` file field — `Blob \| FileDescriptor` |
|
|
2889
3078
|
| `FileDescriptor` | _type_ | a React Native / Expo file — `{ uri, name, type }` |
|
|
3079
|
+
| `EndpointToolAnnotations` | _type_ | MCP behavioural hints on an endpoint (`readOnlyHint` / `destructiveHint` / `title`) |
|
|
3080
|
+
| `EndpointUiMeta` | _type_ | MCP Apps widget metadata on an endpoint |
|
|
2890
3081
|
|
|
2891
3082
|
### Errors
|
|
2892
3083
|
|
|
@@ -2901,6 +3092,9 @@ from the root `stitchkit`.
|
|
|
2901
3092
|
| `conflict` | function | throw `409 CONFLICT` |
|
|
2902
3093
|
| `rateLimited` | function | throw `429 RATE_LIMITED` |
|
|
2903
3094
|
| `appError` | function | throw an `AppError` for any code |
|
|
3095
|
+
| `defineErrors` | function | declare domain error codes → typed throwers + a code table — [guide](../guide/auth-and-errors.md#domain-errors--defineerrors) |
|
|
3096
|
+
| `DefinedErrors` | _type_ | the `{ errors, codes, isCode }` handle `defineErrors` returns |
|
|
3097
|
+
| `ErrorThrower` | _type_ | one `defineErrors` thrower — `(message?, details?, hint?) => never` |
|
|
2904
3098
|
| `STITCH_ERROR_STATUS` | const | `code → HTTP status` map for stitchkit's own error codes — [guide](../guide/auth-and-errors.md#stitch-codes-vs-your-codes) |
|
|
2905
3099
|
| `StitchErrorCode` | _type_ | a code stitchkit itself emits (`keyof STITCH_ERROR_STATUS`) |
|
|
2906
3100
|
| `isStitchErrorCode` | function | type guard — is a code one of stitchkit's own? |
|
|
@@ -2956,14 +3150,22 @@ Also re-exports the error helpers from `stitchkit/contract`.
|
|
|
2956
3150
|
| Export | Kind | Summary |
|
|
2957
3151
|
|--------|------|---------|
|
|
2958
3152
|
| `createAuthHook` | function | a scope-enforcing `beforeHandle` hook — [guide](../guide/auth-and-errors.md#createauthhook) |
|
|
3153
|
+
| `createErrorHook` | function | an `onError` hook from a code map + envelope renderer — [guide](../guide/auth-and-errors.md#createerrorhook) |
|
|
3154
|
+
| `ErrorHookConfig` | _type_ | config for `createErrorHook` |
|
|
3155
|
+
| `ResolvedError` | _type_ | the normalised error handed to `createErrorHook`'s `render` |
|
|
2959
3156
|
| `createBearerResolver` | function | a bearer-token identity resolver |
|
|
3157
|
+
| `signJwt` | function | sign an HS256 JWT |
|
|
2960
3158
|
| `verifyJwt` | function | verify an HS256 JWT |
|
|
2961
3159
|
| `extractToken` | function | read a bearer token from header or cookie |
|
|
3160
|
+
| `deriveCodeChallenge` | function | PKCE — derive the `code_challenge` from a verifier |
|
|
3161
|
+
| `verifyPkce` | function | PKCE — verify a verifier against a stored challenge |
|
|
2962
3162
|
| `AuthHook` | _type_ | the hook `createAuthHook` returns |
|
|
2963
3163
|
| `AuthHookConfig` | _type_ | config for `createAuthHook` |
|
|
2964
3164
|
| `AuthRule` | _type_ | `'public' \| 'authenticated' \| predicate` |
|
|
2965
3165
|
| `BearerResolverConfig` | _type_ | config for `createBearerResolver` |
|
|
2966
3166
|
| `JwtPayload` | _type_ | a decoded JWT payload |
|
|
3167
|
+
| `SignJwtOptions` | _type_ | options for `signJwt` (expiry, claims) |
|
|
3168
|
+
| `PkceMethod` | _type_ | the PKCE challenge method — `'S256' \| 'plain'` |
|
|
2967
3169
|
|
|
2968
3170
|
### Cookies & CORS
|
|
2969
3171
|
|
|
@@ -2974,6 +3176,7 @@ Also re-exports the error helpers from `stitchkit/contract`.
|
|
|
2974
3176
|
| `serializeCookie` | function | build a `Set-Cookie` value |
|
|
2975
3177
|
| `corsHeaders` | function | compute CORS response headers |
|
|
2976
3178
|
| `corsPreflightResponse` | function | build a preflight `Response` |
|
|
3179
|
+
| `DEFAULT_CORS_ALLOW_HEADERS` | const | the default `Access-Control-Allow-Headers` (incl. `traceparent`) — extend it when overriding `cors.headers` |
|
|
2977
3180
|
| `CookieDef` | _type_ | the `defineCookie` handle |
|
|
2978
3181
|
| `CookieOptions` | _type_ | cookie attributes |
|
|
2979
3182
|
| `CorsConfig` | _type_ | CORS policy |
|
|
@@ -3006,9 +3209,11 @@ Also re-exports the error helpers from `stitchkit/contract`.
|
|
|
3006
3209
|
| `generateTraceId` | function | a fresh trace id |
|
|
3007
3210
|
| `resolveTraceId` | function | the default per-request trace-id resolver |
|
|
3008
3211
|
| `extractIp` | function | the caller IP from a request |
|
|
3212
|
+
| `resolveSocketIp` | function | the caller IP for a Socket.IO handshake (proxy-aware) |
|
|
3009
3213
|
| `getClientInfo` | function | caller IP + user-agent |
|
|
3010
3214
|
| `EventBus` | _type_ | the `createEventBus` handle |
|
|
3011
3215
|
| `RateLimitConfig` | _type_ | config for `createRateLimiter` |
|
|
3216
|
+
| `ClientIpOptions` | _type_ | trusted-proxy config for `extractIp` / `resolveSocketIp` |
|
|
3012
3217
|
| `ParseSSEOptions` | _type_ | options for `parseSSE` |
|
|
3013
3218
|
|
|
3014
3219
|
### OpenAPI
|
|
@@ -3048,6 +3253,8 @@ audit event. See the [Observability guide](../guide/observability.md).
|
|
|
3048
3253
|
| `getTraceId` | function | the active trace id — pass as `traceId` to `createServer` |
|
|
3049
3254
|
| `getUserId` | function | the active user id, once auth has resolved it |
|
|
3050
3255
|
| `setRequestUser` | function | attach the resolved user to the active context |
|
|
3256
|
+
| `setRequestEndpoint` | function | attach the resolved endpoint identity to the active context |
|
|
3257
|
+
| `setRequestDimensions` | function | attach custom audit dimensions to the active context |
|
|
3051
3258
|
| `setRequestError` | function | record the error outcome on the active context |
|
|
3052
3259
|
| `runWithRequestContext` | function | run a function inside a given context |
|
|
3053
3260
|
| `RequestContext` | _type_ | the per-request record |
|
|
@@ -3095,6 +3302,7 @@ Server-only. Turns contracts into MCP and AI-agent tools. Needs the
|
|
|
3095
3302
|
| `mountViewFile` | function | a native multimodal "view file" MCP tool |
|
|
3096
3303
|
| `resolveMedia` | function | resolve a media reference for a tool result |
|
|
3097
3304
|
| `validateMcpSchemas` | function | assert every tool schema is JSON Schema-compatible — [guide](../guide/mcp-and-agents.md#incompatible-schemas--onincompatibleschema) |
|
|
3305
|
+
| `listToolNames` | function | every mounted tool name with its `(service, method)` identity — for name-baseline snapshots — [guide](../guide/mcp-and-agents.md#pinning-tool-names--listtoolnames) |
|
|
3098
3306
|
| `McpHandlerConfig` | _type_ | config for `createMcpHandler` |
|
|
3099
3307
|
| `StdioMcpServerConfig` | _type_ | config for `createStdioMcpServer` |
|
|
3100
3308
|
| `McpServerBuildConfig` | _type_ | shared config for `buildMcpServer` |
|
|
@@ -3109,10 +3317,98 @@ Server-only. Turns contracts into MCP and AI-agent tools. Needs the
|
|
|
3109
3317
|
| `ToolExtend` | _type_ | extra-args extension for `mountMcp` / `mountAgent` |
|
|
3110
3318
|
| `ToolLifecycle` | _type_ | `beforeHandle` / `afterHandle` gate for tool calls — [guide](../guide/mcp-and-agents.md#guarding-tools--lifecycle) |
|
|
3111
3319
|
| `ToolCallHooks` | _type_ | `beforeToolCall` / `afterToolCall` observability hooks |
|
|
3320
|
+
| `ErrorHintFn` | _type_ | `(toolName, errorCode) => string \| null` — a per-tool recovery hint, shared by every mount |
|
|
3112
3321
|
| `ToolResult` | _type_ | the result of one tool call |
|
|
3322
|
+
| `ToolNameEntry` | _type_ | one `listToolNames` row — `{ name, service, method, transports }` |
|
|
3113
3323
|
| `IncompatibleSchemaPolicy` | _type_ | `'throw' \| 'skip' \| 'warn'` |
|
|
3114
3324
|
| `McpMediaContent` | _type_ | a multimodal MCP content item |
|
|
3115
3325
|
|
|
3326
|
+
### Native tools
|
|
3327
|
+
|
|
3328
|
+
Generic host-supplied tools mounted onto a server — not derived from a contract.
|
|
3329
|
+
|
|
3330
|
+
| Export | Kind | Summary |
|
|
3331
|
+
|--------|------|---------|
|
|
3332
|
+
| `mountDownload` | function | a "download a URL to disk" tool (SSRF-guarded, size-capped) |
|
|
3333
|
+
| `mountUpload` | function | an "upload a local file" tool |
|
|
3334
|
+
| `mountWait` | function | a generic `--wait`-style polling tool |
|
|
3335
|
+
| `DownloadToolConfig` | _type_ | config for `mountDownload` |
|
|
3336
|
+
| `UploadToolConfig` | _type_ | config for `mountUpload` |
|
|
3337
|
+
| `WaitToolConfig` | _type_ | config for `mountWait` |
|
|
3338
|
+
|
|
3339
|
+
### OAuth 2.1 provider
|
|
3340
|
+
|
|
3341
|
+
A native remote-connector auth surface for MCP — [guide](../guide/mcp-and-agents.md#oauth-21--a-native-remote-connector).
|
|
3342
|
+
|
|
3343
|
+
| Export | Kind | Summary |
|
|
3344
|
+
|--------|------|---------|
|
|
3345
|
+
| `mountOAuthProvider` | function | the OAuth 2.1 provider routes (DCR, PKCE, token) |
|
|
3346
|
+
| `oauthProtectedResourceRoute` | function | the RFC 9728 protected-resource-metadata route |
|
|
3347
|
+
| `protectedResourceMetadataUrl` | function | build the metadata URL for a resource |
|
|
3348
|
+
| `wwwAuthenticateHeader` | function | build the `WWW-Authenticate` challenge header |
|
|
3349
|
+
| `PROTECTED_RESOURCE_PATH` | const | the well-known metadata path |
|
|
3350
|
+
| `OAuthProviderConfig` | _type_ | config for `mountOAuthProvider` |
|
|
3351
|
+
| `ProtectedResourceConfig` | _type_ | config for `oauthProtectedResourceRoute` |
|
|
3352
|
+
| `AuthCodeData` | _type_ | a stored authorization-code record |
|
|
3353
|
+
| `AuthRequest` | _type_ | a parsed authorization request |
|
|
3354
|
+
| `ClientMetadata` | _type_ | dynamic-client-registration metadata |
|
|
3355
|
+
| `RefreshData` | _type_ | a stored refresh-token record |
|
|
3356
|
+
| `RegisteredClient` | _type_ | a registered OAuth client |
|
|
3357
|
+
|
|
3358
|
+
### MCP Apps (widgets)
|
|
3359
|
+
|
|
3360
|
+
Interactive MCP resources — [ADR 0019](../decisions/0019-generic-native-tools.md).
|
|
3361
|
+
|
|
3362
|
+
| Export | Kind | Summary |
|
|
3363
|
+
|--------|------|---------|
|
|
3364
|
+
| `mountMcpResource` | function | mount an MCP Apps widget resource |
|
|
3365
|
+
| `inlineMcpAppBundle` | function | inline a built widget bundle into a resource |
|
|
3366
|
+
| `EXT_APPS_BUNDLE_PLACEHOLDER` | const | the placeholder token `inlineMcpAppBundle` replaces |
|
|
3367
|
+
| `RESOURCE_MIME_TYPE` | const | the MCP Apps resource MIME type |
|
|
3368
|
+
| `McpResourceDef` | _type_ | an MCP Apps resource definition |
|
|
3369
|
+
| `McpAppResourceMeta` | _type_ | resource `_meta` for an MCP App |
|
|
3370
|
+
| `McpAppCsp` | _type_ | the widget content-security policy |
|
|
3371
|
+
|
|
3372
|
+
### Introspection & internals
|
|
3373
|
+
|
|
3374
|
+
Advanced building blocks — the shared machinery the mounts are built on.
|
|
3375
|
+
|
|
3376
|
+
| Export | Kind | Summary |
|
|
3377
|
+
|--------|------|---------|
|
|
3378
|
+
| `collectTools` | function | resolve a service's methods to mountable tools (the shared resolver) |
|
|
3379
|
+
| `createToolLogger` | function | a ready `afterToolCall` that logs every tool call — [guide](../guide/mcp-and-agents.md#logging-tool-calls--createtoollogger) |
|
|
3380
|
+
| `summarizeTransports` | function | per-transport operation counts for a boot-time summary |
|
|
3381
|
+
| `buildToolManifest` | function | a searchable `{ name, description, inputSchema }` manifest for a `tool_search` tool |
|
|
3382
|
+
| `ToolLoggerConfig` | _type_ | config for `createToolLogger` |
|
|
3383
|
+
| `ToolCallRecord` | _type_ | the structured record `createToolLogger` passes to `onRecord` |
|
|
3384
|
+
| `TransportSummary` | _type_ | the result of `summarizeTransports` |
|
|
3385
|
+
| `TransportCounts` | _type_ | per-transport counts (`{ HTTP, MCP, AGENT, CLI }`) |
|
|
3386
|
+
| `coerceJsonArgs` | function | coerce JSON-stringified array/object tool arguments |
|
|
3387
|
+
| `flattenDiscriminatedUnion` | function | flatten one discriminated union into a single object schema |
|
|
3388
|
+
| `flattenUnionsDeep` | function | flatten discriminated unions at every depth (advertised schema only) |
|
|
3389
|
+
| `MountableTool` | _type_ | one contract method resolved for mounting |
|
|
3390
|
+
| `ToolManifestEntry` | _type_ | one `buildToolManifest` row |
|
|
3391
|
+
|
|
3392
|
+
---
|
|
3393
|
+
|
|
3394
|
+
## `stitchkit/node`
|
|
3395
|
+
|
|
3396
|
+
Server-only, for Node ≥ 22 (Bun uses `stitchkit/server`). The runtime-agnostic
|
|
3397
|
+
core plus a Node HTTP adapter — [ADR 0013](../decisions/0013-runtime-agnostic-core.md),
|
|
3398
|
+
[deployment guide](../guide/testing-and-deployment.md#node). Re-exports the
|
|
3399
|
+
runtime-agnostic pieces of `stitchkit/server` and the error helpers.
|
|
3400
|
+
|
|
3401
|
+
| Export | Kind | Summary |
|
|
3402
|
+
|--------|------|---------|
|
|
3403
|
+
| `serveNode` | function | build the router and start a Node HTTP server (via `srvx`) |
|
|
3404
|
+
| `createHandler` | function | the router as a bare `(req) => Response` (same as `/server`) |
|
|
3405
|
+
| `createSocketIOServer` | function | the typed Socket.IO server (same as `/server`) |
|
|
3406
|
+
| `implement` / `createImplement` | function | bind a contract to typed handlers (same as `/server`) |
|
|
3407
|
+
| `NodeServerConfig` | _type_ | config for `serveNode` |
|
|
3408
|
+
| `NodeServerHandle` | _type_ | the `serveNode` handle (`{ port, stop }`) |
|
|
3409
|
+
| `HandlerConfig` / `ServiceDef` / `RawRoute` / `RawRouteContext` / `SocketIOServerConfig` / `SocketIOServerHandle` | _type_ | re-exported from `/server` |
|
|
3410
|
+
| `AppError` + `appError` / `badRequest` / `unauthorized` / `forbidden` / `notFound` / `conflict` / `rateLimited` | — | error helpers (same as `/contract`) |
|
|
3411
|
+
|
|
3116
3412
|
---
|
|
3117
3413
|
|
|
3118
3414
|
## `stitchkit/cli`
|
|
@@ -3147,6 +3443,10 @@ and `react-query-kit` peers.
|
|
|
3147
3443
|
|--------|------|---------|
|
|
3148
3444
|
| `createCursorQuery` | function | a cursor-paginated infinite query — [guide](../guide/client.md#cursor-pagination) |
|
|
3149
3445
|
| `createCacheBridge` | function | sync socket events into the Query cache — [guide](../guide/realtime.md#cache-bridge) |
|
|
3446
|
+
| `createEntityCacheHandlers` | function | created/updated/deleted cache handlers for one entity — [guide](../guide/realtime.md#entity-cache-handlers) |
|
|
3447
|
+
| `EntityCacheConfig` | _type_ | config for `createEntityCacheHandlers` |
|
|
3448
|
+
| `EntityCacheHandlers` | _type_ | the `{ created, updated, deleted }` handlers it returns |
|
|
3449
|
+
| `DeletedPayload` | _type_ | a `deleted` event payload — the entity or a bare `{ id }` |
|
|
3150
3450
|
| `CursorQueryConfig` | _type_ | config for `createCursorQuery` |
|
|
3151
3451
|
| `CacheBridge` | _type_ | the `createCacheBridge` handle |
|
|
3152
3452
|
| `CacheBridgeConfig` | _type_ | config for `createCacheBridge` |
|
package/package.json
CHANGED