stitchkit 0.26.0 → 0.28.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.
Files changed (51) hide show
  1. package/dist/browser/client.d.ts.map +1 -1
  2. package/dist/browser/http.d.ts +7 -1
  3. package/dist/browser/http.d.ts.map +1 -1
  4. package/dist/cli.js +2 -2
  5. package/dist/contract/define.d.ts +60 -3
  6. package/dist/contract/define.d.ts.map +1 -1
  7. package/dist/contract/index.js +1 -1
  8. package/dist/{index-bkccbx64.js → index-17jpjnhd.js} +196 -44
  9. package/dist/{index-q5w3cvvp.js → index-4whcb3c3.js} +3 -1
  10. package/dist/{index-dzx781tm.js → index-9g9d6r1h.js} +40 -4
  11. package/dist/{index-tje0q6gp.js → index-czmqks7r.js} +6 -1
  12. package/dist/{index-p6fge9a5.js → index-jvescqgr.js} +1 -1
  13. package/dist/{index-h4y2wg3n.js → index-pmftwk2a.js} +18 -0
  14. package/dist/index.js +20 -8
  15. package/dist/node.d.ts +1 -1
  16. package/dist/node.d.ts.map +1 -1
  17. package/dist/node.js +7 -7
  18. package/dist/observability/context.d.ts +8 -4
  19. package/dist/observability/context.d.ts.map +1 -1
  20. package/dist/observability/index.js +6 -8
  21. package/dist/server/create.d.ts +2 -2
  22. package/dist/server/create.d.ts.map +1 -1
  23. package/dist/server/implement.d.ts.map +1 -1
  24. package/dist/server/index.d.ts +3 -2
  25. package/dist/server/index.d.ts.map +1 -1
  26. package/dist/server/index.js +19 -7
  27. package/dist/server/logger.d.ts +36 -4
  28. package/dist/server/logger.d.ts.map +1 -1
  29. package/dist/server/logging.d.ts +20 -0
  30. package/dist/server/logging.d.ts.map +1 -0
  31. package/dist/server/middleware/cors.d.ts +25 -0
  32. package/dist/server/middleware/cors.d.ts.map +1 -1
  33. package/dist/server/node.d.ts +2 -2
  34. package/dist/server/node.d.ts.map +1 -1
  35. package/dist/server/openapi.d.ts.map +1 -1
  36. package/dist/server/router.d.ts +27 -0
  37. package/dist/server/router.d.ts.map +1 -1
  38. package/dist/server/types.d.ts +116 -4
  39. package/dist/server/types.d.ts.map +1 -1
  40. package/dist/tools/list-names.d.ts +2 -1
  41. package/dist/tools/list-names.d.ts.map +1 -1
  42. package/dist/tools/mount.d.ts.map +1 -1
  43. package/dist/tools/remote.d.ts.map +1 -1
  44. package/dist/tools/tool-logger.d.ts +7 -0
  45. package/dist/tools/tool-logger.d.ts.map +1 -1
  46. package/dist/tools.js +29 -14
  47. package/llms-full.txt +234 -14
  48. package/llms.txt +1 -1
  49. package/package.json +1 -1
  50. package/dist/index-khwedj16.js +0 -40
  51. /package/dist/{index-0d0rb85d.js → index-zza375qp.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/browser/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAI/F,OAAO,EAEL,KAAK,UAAU,IAAI,WAAW,EAG/B,MAAM,QAAQ,CAAC;AA+EhB,kFAAkF;AAClF,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClE,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACnD;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAC1D,OAAO,GACP;KAAG,CAAC,IAAI,CAAC,GAAG,MAAM;CAAE,CAAC;AAEzB;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB,CAAC,CAAC,SAAS,MAAM,GAAG,KAAK;IAC5D,UAAU,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,CAAC;IAClE,eAAe,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACrC,KAAK,CAAC,CAAC,SAAS,MAAM,GAAG,KAAK,EAE9B,QAAQ,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,EAChC,cAAc,EAAE,YAAY,GAAG,WAAW,EAC1C,cAAc,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,GACvC,gBAAgB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAepC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC,EAC1E,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;CAAE,CAKzF"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/browser/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAI/F,OAAO,EAEL,KAAK,UAAU,IAAI,WAAW,EAG/B,MAAM,QAAQ,CAAC;AAsFhB,kFAAkF;AAClF,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClE,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACnD;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAC1D,OAAO,GACP;KAAG,CAAC,IAAI,CAAC,GAAG,MAAM;CAAE,CAAC;AAEzB;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB,CAAC,CAAC,SAAS,MAAM,GAAG,KAAK;IAC5D,UAAU,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,CAAC;IAClE,eAAe,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACrC,KAAK,CAAC,CAAC,SAAS,MAAM,GAAG,KAAK,EAE9B,QAAQ,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,EAChC,cAAc,EAAE,YAAY,GAAG,WAAW,EAC1C,cAAc,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,GACvC,gBAAgB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAepC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC,EAC1E,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;CAAE,CAKzF"}
@@ -65,7 +65,13 @@ type ParamArrayValue = Array<string | number>;
65
65
  export interface RequestOptions {
66
66
  params?: Record<string, ParamValue | ParamArrayValue>;
67
67
  timeout?: number;
68
- responseType?: 'json' | 'blob';
68
+ /**
69
+ * How to read the body. `'response'` hands back the untouched `Response` —
70
+ * what a `raw` endpoint answers with, and strictly more than `'blob'`: the
71
+ * caller still gets `.blob()` / `.body`, plus the headers where
72
+ * `Content-Disposition` (the download filename) lives.
73
+ */
74
+ responseType?: 'json' | 'blob' | 'response';
69
75
  }
70
76
  /** The HTTP transport adapter `createClient` builds typed methods on. */
71
77
  export interface HttpClient {
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/browser/http.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/browser/http.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -4,9 +4,9 @@ import {
4
4
  emitResult,
5
5
  parseCliArgs,
6
6
  pollUntilDone
7
- } from "./index-q5w3cvvp.js";
7
+ } from "./index-4whcb3c3.js";
8
8
  import"./index-0ed3bx43.js";
9
- import"./index-0d0rb85d.js";
9
+ import"./index-zza375qp.js";
10
10
  import"./index-c7nyw0yt.js";
11
11
  export {
12
12
  pollUntilDone,
@@ -93,6 +93,7 @@ export interface EndpointToolAnnotations {
93
93
  interface HttpOnlyEndpointDef extends EndpointDefBase {
94
94
  expose: readonly ['HTTP'];
95
95
  toolName?: never;
96
+ rawResponse?: never;
96
97
  }
97
98
  interface ToolEndpointDef extends EndpointDefBase {
98
99
  toolName?: string;
@@ -101,8 +102,55 @@ interface ToolEndpointDef extends EndpointDefBase {
101
102
  ui?: EndpointUiMeta;
102
103
  /** MCP behavioural hints (read-only / destructive / title) for hosts. */
103
104
  annotations?: EndpointToolAnnotations;
105
+ rawResponse?: never;
104
106
  }
105
- export type EndpointDef = HttpOnlyEndpointDef | ToolEndpointDef;
107
+ /**
108
+ * An endpoint whose handler returns the **`Response` itself** instead of data —
109
+ * a file download, a PDF, an SSE stream, a redirect. → ADR 0038.
110
+ *
111
+ * ```ts
112
+ * pdf: {
113
+ * method: 'GET', path: '/:id/pdf', desc: 'Download the offer as a PDF',
114
+ * params: z.object({ id: z.uuid() }),
115
+ * rawResponse: true, contentType: 'application/pdf',
116
+ * }
117
+ * ```
118
+ *
119
+ * Only the **response** is raw — hence the name, and the difference from
120
+ * `rawRoutes`, which sit outside the contract entirely. Here the request half is
121
+ * unchanged: `params` / `input` / `multipart` parse and validate exactly as
122
+ * elsewhere, and `beforeHandle` runs, so the auth gate applies with no guard in
123
+ * the handler. What is handed over is the response, so there is no `output` to
124
+ * validate, nothing to serialize into a tool result, and the endpoint is
125
+ * **HTTP-only**: never an MCP tool, an agent tool or a CLI command.
126
+ * `afterHandle` is skipped (it transforms data; there is none).
127
+ */
128
+ interface RawResponseEndpointDef extends EndpointDefBase {
129
+ /**
130
+ * Marks the response as raw. Must be the literal `true` — it is the
131
+ * discriminant of the union, so `rawResponse: false` is not a way to say
132
+ * "normal".
133
+ */
134
+ rawResponse: true;
135
+ /**
136
+ * The `Content-Type` this endpoint answers with, for documentation only —
137
+ * the handler still sets the real header (`serveFile` detects it from the
138
+ * path). Drives the OpenAPI response media type; without it the endpoint
139
+ * documents as `application/octet-stream`.
140
+ */
141
+ contentType?: string;
142
+ /** There is no output schema — the handler owns the whole response. */
143
+ output?: never;
144
+ /** Never a tool, so a tool name would be dead metadata. */
145
+ toolName?: never;
146
+ /** MCP-only decoration; a raw endpoint never reaches MCP. */
147
+ ui?: never;
148
+ /** MCP-only decoration; a raw endpoint never reaches MCP. */
149
+ annotations?: never;
150
+ /** Redundant but allowed, so `expose: ['HTTP']` survives a migration. */
151
+ expose?: readonly ['HTTP'];
152
+ }
153
+ export type EndpointDef = HttpOnlyEndpointDef | ToolEndpointDef | RawResponseEndpointDef;
106
154
  export interface ContractMeta<TScope extends string = string> {
107
155
  prefix: string;
108
156
  scope?: TScope;
@@ -110,7 +158,9 @@ export interface ContractMeta<TScope extends string = string> {
110
158
  * Contract-wide default for every endpoint's opaque `meta` (→ ADR 0021).
111
159
  * Endpoints **shallow-merge** over it, key by key — so a contract-wide
112
160
  * `{ public: true }` survives an endpoint that adds `{ rateTier: 2 }`. One
113
- * level only: no deep merge, no unset sentinel. ADR 0036.
161
+ * level only, no deep merge. An explicit `key: undefined` on the endpoint is
162
+ * the opt-out: it shadows the contract's value, so `meta?.key` readers see
163
+ * nothing — test values, not key membership. → ADR 0036.
114
164
  *
115
165
  * `expose` deliberately has no equivalent — see ADR 0036 for why, and pin
116
166
  * `listToolNames` in a snapshot to catch an endpoint that forgot it.
@@ -211,7 +261,14 @@ type MultipartArgs<E> = E extends {
211
261
  [P in K]: MultipartFile;
212
262
  } : unknown;
213
263
  type EndpointArgs<E> = InferInput<Prop<E, 'params'>> & InferInput<Prop<E, 'input'>> & MultipartArgs<E>;
214
- type EndpointOutput<E> = Prop<E, 'output'> extends ZodType<infer O> ? O : undefined;
264
+ /**
265
+ * What the typed client resolves to. A `raw` endpoint hands back the untouched
266
+ * `Response` — its body is bytes, and the headers carry what the caller needs
267
+ * (`Content-Disposition`, `Content-Range`, `ETag`). → ADR 0038.
268
+ */
269
+ type EndpointOutput<E> = E extends {
270
+ rawResponse: true;
271
+ } ? Response : Prop<E, 'output'> extends ZodType<infer O> ? O : undefined;
215
272
  export type EndpointFn<E> = [keyof EndpointArgs<E>] extends [never] ? () => Promise<EndpointOutput<E>> : (args: EndpointArgs<E>) => Promise<EndpointOutput<E>>;
216
273
  export type TypedClient<C extends Record<string, EndpointDef>> = {
217
274
  [K in keyof C]: EndpointFn<C[K]>;
@@ -1 +1 @@
1
- {"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../src/contract/define.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../src/contract/define.ts"],"names":[],"mappings":"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"}
@@ -16,7 +16,7 @@ import {
16
16
  paginatedSchema,
17
17
  rateLimited,
18
18
  unauthorized
19
- } from "../index-h4y2wg3n.js";
19
+ } from "../index-pmftwk2a.js";
20
20
  import"../index-809wc1tt.js";
21
21
  export {
22
22
  unauthorized,
@@ -2,7 +2,7 @@ import {
2
2
  assertCorsConfig,
3
3
  corsHeaders,
4
4
  corsPreflightResponse
5
- } from "./index-tje0q6gp.js";
5
+ } from "./index-czmqks7r.js";
6
6
  import {
7
7
  AppError,
8
8
  badRequest,
@@ -11,17 +11,19 @@ import {
11
11
  mergeMeta,
12
12
  normalizeError,
13
13
  validateHandlerOutput
14
- } from "./index-0d0rb85d.js";
14
+ } from "./index-zza375qp.js";
15
15
  import {
16
16
  extractIp,
17
17
  getClientInfo,
18
+ getRequestContext,
18
19
  parseQueryParams,
19
20
  resolveSocketIp,
20
21
  resolveTraceId,
21
22
  setRequestEndpoint
22
- } from "./index-dzx781tm.js";
23
+ } from "./index-9g9d6r1h.js";
23
24
  import {
24
25
  __require,
26
+ isRecord,
25
27
  isUnsafeKey,
26
28
  safeJsonParse,
27
29
  typedEntries
@@ -213,6 +215,26 @@ function validateRoutes(routeMap) {
213
215
  }
214
216
  }
215
217
  }
218
+ function findShadowedRoutes(routeMap, rawRoutes) {
219
+ if (!rawRoutes || rawRoutes.length === 0)
220
+ return [];
221
+ const shadowed = [];
222
+ for (const [httpMethod, entries] of routeMap) {
223
+ for (const entry of entries) {
224
+ const probe = `/${entry.segments.map((s) => s.startsWith(":") ? "__param__" : s).join("/")}`;
225
+ const match = matchRawRoute(rawRoutes, httpMethod, probe);
226
+ if (!match)
227
+ continue;
228
+ shadowed.push({
229
+ pattern: `${httpMethod} ${entry.pattern}`,
230
+ endpoint: `${entry.method.serviceName}.${entry.method.key}`,
231
+ rawRoute: `${match.route.method} ${match.route.path}`,
232
+ scope: entry.method.scope
233
+ });
234
+ }
235
+ }
236
+ return shadowed;
237
+ }
216
238
  function matchRawRoute(rawRoutes, httpMethod, pathname) {
217
239
  for (const route of rawRoutes) {
218
240
  if (route.method !== "ALL" && route.method !== httpMethod)
@@ -406,7 +428,7 @@ function levelForStatus(status) {
406
428
  return "info";
407
429
  }
408
430
  function buildLogFields(method, path, status, durationMs, traceId, errorCode2) {
409
- return { traceId, method, path, status, durationMs, ...errorCode2 && { errorCode: errorCode2 } };
431
+ return { traceId, method, path, status, durationMs, errorCode: errorCode2 };
410
432
  }
411
433
  function formatMs(ms) {
412
434
  if (ms >= 1000)
@@ -450,16 +472,25 @@ function logIncoming(req, pathname, traceId, ipAddress) {
450
472
  }
451
473
  return log;
452
474
  }
453
- function logOutgoing(req, pathname, status, log, ipAddress, errorCode2) {
475
+ function structuredLine(own, extra) {
476
+ try {
477
+ return JSON.stringify({ ...extra, ...own });
478
+ } catch {
479
+ return JSON.stringify(own);
480
+ }
481
+ }
482
+ function logOutgoing(entry) {
483
+ const { req, pathname, status, log, ipAddress, errorCode: errorCode2, durationMs, extra } = entry;
454
484
  const ms = elapsedMs(log.startTime);
455
485
  if (isProd) {
456
- console.log(JSON.stringify({
486
+ const own = {
457
487
  ts: new Date().toISOString(),
458
488
  level: levelForStatus(status),
459
489
  msg: `${req.method} ${pathname} ${status}`,
460
- ...buildLogFields(req.method, pathname, status, Math.round(ms), log.traceId, errorCode2),
490
+ ...buildLogFields(req.method, pathname, status, durationMs, log.traceId, errorCode2),
461
491
  ip: ipAddress
462
- }));
492
+ };
493
+ console.log(structuredLine(own, extra));
463
494
  return;
464
495
  }
465
496
  const mc = METHOD_COLOR[req.method] ?? c.dim;
@@ -467,42 +498,126 @@ function logOutgoing(req, pathname, status, log, ipAddress, errorCode2) {
467
498
  console.log(`${c.gray}[${timestamp()}]${c.reset} ${mc}${req.method}${c.reset} ${c.dim}${log.traceId}${c.reset} ${c.cyan}←${c.reset} ${safePath(pathname)} ${statusColor(status)}${status}${c.reset}${code} ${durationColor(ms)}${formatMs(ms)}${c.reset} ${ipLabel(ipAddress ?? "")}`);
468
499
  }
469
500
 
501
+ // src/server/logging.ts
502
+ var LOGGER_METHODS = ["info", "warn", "error", "debug"];
503
+ function isBareLogger(value) {
504
+ if (value.logger !== undefined || value.skip !== undefined || value.enrich !== undefined) {
505
+ return false;
506
+ }
507
+ return LOGGER_METHODS.every((method) => typeof value[method] === "function");
508
+ }
509
+ function resolveLoggingConfig(logging) {
510
+ if (logging === false)
511
+ return null;
512
+ if (logging === true)
513
+ return {};
514
+ if (isRecord(logging) && isBareLogger(logging)) {
515
+ throw new Error("[stitchkit] `logging` no longer takes a StitchLogger directly — nest it: " + "`logging: { logger: myLogger }`.");
516
+ }
517
+ return logging;
518
+ }
519
+ function shouldSkipLog(config, req, url) {
520
+ if (!config.skip)
521
+ return false;
522
+ try {
523
+ return config.skip(req, url);
524
+ } catch {
525
+ return false;
526
+ }
527
+ }
528
+ function collectExtraLogFields(config, req, url, outcome) {
529
+ const fields = {};
530
+ const ctx = getRequestContext();
531
+ if (ctx) {
532
+ if (ctx.userId)
533
+ fields.userId = ctx.userId;
534
+ if (ctx.serviceName)
535
+ fields.serviceName = ctx.serviceName;
536
+ if (ctx.action)
537
+ fields.action = ctx.action;
538
+ if (ctx.dimensions)
539
+ fields.dimensions = ctx.dimensions;
540
+ }
541
+ if (config.enrich) {
542
+ try {
543
+ const extra = config.enrich(req, url, outcome);
544
+ if (extra)
545
+ Object.assign(fields, extra);
546
+ } catch {}
547
+ }
548
+ return fields;
549
+ }
550
+
470
551
  // src/server/create.ts
471
552
  function createHandler(config) {
472
553
  const { cors, hooks, logging = false, trustProxy = false } = config;
473
554
  if (cors)
474
555
  assertCorsConfig(cors);
475
- const customLogger = typeof logging === "object" ? logging : null;
476
- const useDefaultLog = logging === true;
477
- const resolveId = config.traceId ?? resolveTraceId;
556
+ const logConfig = resolveLoggingConfig(logging);
557
+ const customLogger = logConfig?.logger ?? null;
558
+ const useDefaultLog = logConfig !== null && !logConfig.logger;
559
+ const customTraceId = config.traceId;
478
560
  const routeMap = buildRouteMap(normalizeGroups(config));
479
561
  validateRoutes(routeMap);
562
+ for (const shadow of findShadowedRoutes(routeMap, config.rawRoutes)) {
563
+ const gate = shadow.scope && shadow.scope !== "public" ? ` (scope "${shadow.scope}")` : "";
564
+ const line = `[stitchkit] raw route ${shadow.rawRoute} shadows contract route ${shadow.pattern}` + ` → ${shadow.endpoint}${gate} will never run, and its hooks never apply`;
565
+ if (customLogger)
566
+ customLogger.warn(line);
567
+ else
568
+ console.warn(line);
569
+ }
480
570
  async function dispatch(req, url, traceId, server, clientIp) {
481
- const shouldLogRequest = logging && shouldLog(url.pathname, req.method);
571
+ const shouldLogRequest = logConfig !== null && shouldLog(url.pathname, req.method) && !shouldSkipLog(logConfig, req, url);
482
572
  const ipAddress = extractIp(req, clientIp) || undefined;
483
573
  let reqLog;
484
574
  if (shouldLogRequest && useDefaultLog) {
485
575
  reqLog = logIncoming(req, url.pathname, traceId, ipAddress);
486
576
  }
487
577
  if (shouldLogRequest && customLogger) {
488
- customLogger.debug(`${req.method} ${url.pathname}`, {
489
- traceId,
490
- method: req.method,
491
- path: url.pathname,
492
- ip: ipAddress
493
- });
494
578
  reqLog = { traceId, startTime: performance.now() };
579
+ try {
580
+ customLogger.debug(`${req.method} ${url.pathname}`, {
581
+ traceId,
582
+ method: req.method,
583
+ path: url.pathname,
584
+ ip: ipAddress
585
+ });
586
+ } catch {}
495
587
  }
588
+ let logged = false;
496
589
  const logDone = (status, errorCode2) => {
497
- if (!reqLog)
590
+ if (!reqLog || logged || !logConfig)
498
591
  return;
499
- if (useDefaultLog)
500
- logOutgoing(req, url.pathname, status, reqLog, ipAddress, errorCode2);
501
- if (customLogger) {
592
+ logged = true;
593
+ try {
502
594
  const durationMs = Math.round(elapsedMs(reqLog.startTime));
503
- const level = levelForStatus(status);
504
- customLogger[level](`${req.method} ${url.pathname} ${status}${errorCode2 ? ` ${errorCode2}` : ""} ${durationMs}ms`, buildLogFields(req.method, url.pathname, status, durationMs, reqLog.traceId, errorCode2));
505
- }
595
+ const extra = collectExtraLogFields(logConfig, req, url, {
596
+ status,
597
+ durationMs,
598
+ errorCode: errorCode2
599
+ });
600
+ if (useDefaultLog) {
601
+ logOutgoing({
602
+ req,
603
+ pathname: url.pathname,
604
+ status,
605
+ log: reqLog,
606
+ ipAddress,
607
+ errorCode: errorCode2,
608
+ durationMs,
609
+ extra
610
+ });
611
+ }
612
+ if (customLogger) {
613
+ const level = levelForStatus(status);
614
+ customLogger[level](`${req.method} ${url.pathname} ${status}${errorCode2 ? ` ${errorCode2}` : ""} ${durationMs}ms`, {
615
+ ...extra,
616
+ ...buildLogFields(req.method, url.pathname, status, durationMs, reqLog.traceId, errorCode2),
617
+ ip: ipAddress
618
+ });
619
+ }
620
+ } catch {}
506
621
  };
507
622
  const respondError = async (err, errCtx, endpoint) => {
508
623
  if (hooks?.onError) {
@@ -520,9 +635,7 @@ function createHandler(config) {
520
635
  return json(appErr.toJSON(), appErr.status, cors, req);
521
636
  };
522
637
  if (cors && req.method === "OPTIONS") {
523
- const res = corsPreflightResponse(cors, req);
524
- logDone(204);
525
- return res;
638
+ return corsPreflightResponse(cors, req);
526
639
  }
527
640
  if (hooks?.onRequest) {
528
641
  const earlyResponse = await hooks.onRequest(req);
@@ -571,6 +684,14 @@ function createHandler(config) {
571
684
  await groupHooks.beforeHandle(ctx, method);
572
685
  }
573
686
  let result = await method.handler(ctx);
687
+ if (method.rawResponse) {
688
+ if (!(result instanceof Response)) {
689
+ throw new AppError("INTERNAL_SERVER_ERROR", `Raw endpoint ${method.serviceName}.${method.key} must return a Response`, 500);
690
+ }
691
+ const rawRes = applyCors(result, cors, req);
692
+ logDone(rawRes.status);
693
+ return rawRes;
694
+ }
574
695
  if (groupHooks?.afterHandle) {
575
696
  const transformed = await groupHooks.afterHandle(ctx, result, method);
576
697
  if (transformed !== undefined)
@@ -581,13 +702,18 @@ function createHandler(config) {
581
702
  if (transformed !== undefined)
582
703
  result = transformed;
583
704
  }
705
+ if (result instanceof Response) {
706
+ throw new AppError("INTERNAL_SERVER_ERROR", `${method.serviceName}.${method.key} produced a Response on the data path — only a \`rawResponse: true\` endpoint may return one (an afterHandle hook must return data)`, 500);
707
+ }
584
708
  if (method.outputSchema) {
585
709
  const checked = validateHandlerOutput(method.outputSchema, result, config.warnOnOutputStrip ? (paths) => {
586
710
  const line = `[stitchkit] output strip ${method.serviceName}.${method.key}: ${paths.join(", ")}`;
587
- if (customLogger)
588
- customLogger.warn(line);
589
- else
590
- console.warn(line);
711
+ try {
712
+ if (customLogger)
713
+ customLogger.warn(line);
714
+ else
715
+ console.warn(line);
716
+ } catch {}
591
717
  } : undefined);
592
718
  if (!checked.ok) {
593
719
  throw new AppError("INTERNAL_SERVER_ERROR", checked.message, 500);
@@ -595,18 +721,20 @@ function createHandler(config) {
595
721
  result = checked.data;
596
722
  }
597
723
  if (result === undefined || result === null) {
724
+ const empty = new Response(null, { status: 204, headers: corsHeaders2(cors, req) });
598
725
  logDone(204);
599
- return new Response(null, { status: 204, headers: corsHeaders2(cors, req) });
726
+ return empty;
600
727
  }
728
+ const body = json(result, 200, cors, req);
601
729
  logDone(200);
602
- return json(result, 200, cors, req);
730
+ return body;
603
731
  } catch (err) {
604
732
  return respondError(err, ctx, method);
605
733
  }
606
734
  }
607
735
  return async (req, server) => {
608
736
  const url = new URL(req.url, "http://localhost");
609
- const traceId = resolveId(req);
737
+ const traceId = customTraceId?.(req) ?? resolveTraceId(req);
610
738
  const clientIp = {
611
739
  trustProxy,
612
740
  socketIp: resolveSocketIp(req, server)
@@ -620,7 +748,8 @@ function createHandler(config) {
620
748
  }
621
749
  function createServer(config) {
622
750
  const { routes, websocket, development, bun: bunExtra, port = 3000, hostname } = config;
623
- const fetch = createHandler(config);
751
+ const handler = createHandler(config);
752
+ const fetch = config.wrapFetch ? config.wrapFetch(handler) : handler;
624
753
  return websocket ? Bun.serve({
625
754
  ...bunExtra,
626
755
  ...routes && { routes },
@@ -663,20 +792,41 @@ function applyCors(res, cors, req) {
663
792
  const extra = corsHeaders2(cors, req);
664
793
  if (Object.keys(extra).length === 0)
665
794
  return res;
666
- const headers = new Headers(res.headers);
667
- for (const [key, value] of Object.entries(extra))
795
+ try {
796
+ for (const [key, value] of Object.entries(extra))
797
+ setCorsHeader(res.headers, key, value);
798
+ return res;
799
+ } catch {
800
+ const headers = new Headers(res.headers);
801
+ for (const [key, value] of Object.entries(extra))
802
+ setCorsHeader(headers, key, value);
803
+ return new Response(res.body, {
804
+ status: res.status,
805
+ statusText: res.statusText,
806
+ headers
807
+ });
808
+ }
809
+ }
810
+ function setCorsHeader(headers, key, value) {
811
+ if (key !== "Vary") {
668
812
  headers.set(key, value);
669
- return new Response(res.body, {
670
- status: res.status,
671
- statusText: res.statusText,
672
- headers
673
- });
813
+ return;
814
+ }
815
+ const existing = headers.get("Vary");
816
+ if (existing === null || existing.trim() === "") {
817
+ headers.set("Vary", value);
818
+ return;
819
+ }
820
+ const present = existing.split(",").some((field) => field.trim().toLowerCase() === "origin");
821
+ if (!present)
822
+ headers.set("Vary", `${existing}, ${value}`);
674
823
  }
675
824
  function json(data, status, cors, req) {
676
825
  return Response.json(data, { status, headers: corsHeaders2(cors, req) });
677
826
  }
678
827
 
679
828
  // src/server/implement.ts
829
+ var HTTP_ONLY = Object.freeze(["HTTP"]);
680
830
  function implement(contract, handlers) {
681
831
  const methods = {};
682
832
  const groupScope = contract.meta.scope ?? "public";
@@ -689,7 +839,7 @@ function implement(contract, handlers) {
689
839
  serviceName: contract.meta.prefix,
690
840
  key: String(key),
691
841
  toolName: "toolName" in endpoint ? endpoint.toolName : undefined,
692
- expose: endpoint.expose,
842
+ expose: endpoint.rawResponse ? HTTP_ONLY : endpoint.expose,
693
843
  scope: endpoint.scope ?? groupScope,
694
844
  paramsSchema: endpoint.params,
695
845
  inputSchema: endpoint.input,
@@ -700,6 +850,8 @@ function implement(contract, handlers) {
700
850
  ui: "ui" in endpoint ? endpoint.ui : undefined,
701
851
  annotations: "annotations" in endpoint ? endpoint.annotations : undefined,
702
852
  meta: mergeMeta(contract.meta.meta, endpoint.meta),
853
+ rawResponse: endpoint.rawResponse,
854
+ contentType: "contentType" in endpoint ? endpoint.contentType : undefined,
703
855
  handler: (ctx) => typedHandler(ctx)
704
856
  };
705
857
  }
@@ -7,7 +7,7 @@ import {
7
7
  isWithinDir,
8
8
  normalizeError,
9
9
  validateHandlerOutput
10
- } from "./index-0d0rb85d.js";
10
+ } from "./index-zza375qp.js";
11
11
  import {
12
12
  isRecord,
13
13
  isUnsafeKey,
@@ -515,6 +515,8 @@ function collectTools(service, transport, config = {}) {
515
515
  }
516
516
  if (method.multipart)
517
517
  continue;
518
+ if (method.rawResponse)
519
+ continue;
518
520
  const name = method.toolName ?? toToolName(service.name, methodName);
519
521
  if (assertNames && transport !== "CLI") {
520
522
  if (!method.toolName && !hasUsableChars(service.name)) {
@@ -1,6 +1,3 @@
1
- import {
2
- resolveTraceContext
3
- } from "./index-khwedj16.js";
4
1
  import {
5
2
  isRecord,
6
3
  isUnsafeKey
@@ -58,6 +55,45 @@ function parseQueryParams(url) {
58
55
  return query;
59
56
  }
60
57
 
58
+ // src/observability/trace.ts
59
+ var TRACEPARENT_RE = /^00-([0-9a-f]{32})-([0-9a-f]{16})-[0-9a-f]{2}$/i;
60
+ function randomHex(bytes) {
61
+ const arr = new Uint8Array(bytes);
62
+ crypto.getRandomValues(arr);
63
+ let hex = "";
64
+ for (const byte of arr)
65
+ hex += byte.toString(16).padStart(2, "0");
66
+ return hex;
67
+ }
68
+ function createTraceContext() {
69
+ return { traceId: randomHex(16), spanId: randomHex(8) };
70
+ }
71
+ function parseTraceparent(header) {
72
+ if (!header)
73
+ return null;
74
+ const match = TRACEPARENT_RE.exec(header.trim());
75
+ if (!match?.[1] || !match[2])
76
+ return null;
77
+ const traceId = match[1].toLowerCase();
78
+ const parentSpanId = match[2].toLowerCase();
79
+ if (/^0+$/.test(traceId) || /^0+$/.test(parentSpanId))
80
+ return null;
81
+ return { traceId, spanId: randomHex(8), parentSpanId };
82
+ }
83
+ function formatTraceparent(ctx) {
84
+ return `00-${ctx.traceId}-${ctx.spanId}-01`;
85
+ }
86
+ function resolveTraceContext(req) {
87
+ return parseTraceparent(req.headers.get("traceparent")) ?? createTraceContext();
88
+ }
89
+ function childSpan(parent) {
90
+ return {
91
+ traceId: parent.traceId,
92
+ spanId: randomHex(8),
93
+ parentSpanId: parent.spanId
94
+ };
95
+ }
96
+
61
97
  // src/observability/context.ts
62
98
  import { AsyncLocalStorage } from "node:async_hooks";
63
99
  var storage = new AsyncLocalStorage;
@@ -112,4 +148,4 @@ function wrapInRequestContext(handler, options = {}) {
112
148
  };
113
149
  }
114
150
 
115
- export { generateTraceId, resolveTraceId, resolveSocketIp, extractIp, getClientInfo, parseQueryParams, runWithRequestContext, getRequestContext, getTraceId, getUserId, setRequestUser, setRequestEndpoint, setRequestDimensions, setRequestError, wrapInRequestContext };
151
+ export { generateTraceId, resolveTraceId, resolveSocketIp, extractIp, getClientInfo, parseQueryParams, createTraceContext, parseTraceparent, formatTraceparent, resolveTraceContext, childSpan, runWithRequestContext, getRequestContext, getTraceId, getUserId, setRequestUser, setRequestEndpoint, setRequestDimensions, setRequestError, wrapInRequestContext };