stitchkit 0.32.0 → 0.33.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/cli.js CHANGED
@@ -4,10 +4,10 @@ import {
4
4
  emitResult,
5
5
  parseCliArgs,
6
6
  pollUntilDone
7
- } from "./index-36qnfzxe.js";
7
+ } from "./index-jr8vf7g8.js";
8
8
  import"./index-0ed3bx43.js";
9
- import"./index-zza375qp.js";
10
- import"./index-c7nyw0yt.js";
9
+ import"./index-x3fcszf8.js";
10
+ import"./index-enc7t99e.js";
11
11
  export {
12
12
  pollUntilDone,
13
13
  parseCliArgs,
@@ -1,6 +1,5 @@
1
- import {
2
- isRecord
3
- } from "./index-c7nyw0yt.js";
1
+ import { createRequire } from "node:module";
2
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
4
3
 
5
4
  // src/contract/errors.ts
6
5
  var APP_ERROR_BRAND = Symbol.for("stitchkit.AppError");
@@ -77,6 +76,13 @@ function mergeMeta(contractMeta, endpointMeta) {
77
76
  return { ...contractMeta };
78
77
  return { ...contractMeta, ...endpointMeta };
79
78
  }
79
+ // src/internal/typed.ts
80
+ function typedEntries(value) {
81
+ return Object.entries(value);
82
+ }
83
+ function isRecord(value) {
84
+ return typeof value === "object" && value !== null && !Array.isArray(value);
85
+ }
80
86
  // src/contract/pagination.ts
81
87
  import { z } from "zod";
82
88
 
@@ -123,6 +129,15 @@ function errorCode(err) {
123
129
  return "VALIDATION_ERROR";
124
130
  return;
125
131
  }
132
+ function recordedErrorMessage(code, envelopeMessage, thrown) {
133
+ if (code === "INTERNAL_SERVER_ERROR" && thrown !== undefined) {
134
+ if (thrown instanceof Error)
135
+ return thrown.message;
136
+ if (typeof thrown === "string")
137
+ return thrown;
138
+ }
139
+ return envelopeMessage;
140
+ }
126
141
  function normalizeError(err) {
127
142
  if (AppError.is(err))
128
143
  return err;
@@ -169,11 +184,12 @@ function validateHandlerOutput(schema, data, onStripped) {
169
184
  };
170
185
  }
171
186
 
172
- // src/internal/within-dir.ts
173
- import { sep } from "node:path";
174
- function isWithinDir(root, target) {
175
- const base = root.endsWith(sep) ? root.slice(0, -sep.length) : root;
176
- return target === root || target === base || target.startsWith(base + sep);
187
+ // src/internal/safe-json.ts
188
+ function isUnsafeKey(key) {
189
+ return key === "__proto__";
190
+ }
191
+ function safeJsonParse(text) {
192
+ return JSON.parse(text, (key, value) => isUnsafeKey(key) ? undefined : value);
177
193
  }
178
194
 
179
- export { mergeMeta, AppError, notFound, badRequest, unauthorized, forbidden, conflict, rateLimited, STITCH_ERROR_STATUS, isStitchErrorCode, appError, bytesToBase64Url, base64UrlToBytes, formatZodError, zodIssues, errorCode, normalizeError, validateHandlerOutput, isWithinDir };
195
+ export { __require, mergeMeta, AppError, notFound, badRequest, unauthorized, forbidden, conflict, rateLimited, STITCH_ERROR_STATUS, isStitchErrorCode, appError, typedEntries, isRecord, bytesToBase64Url, base64UrlToBytes, formatZodError, zodIssues, errorCode, recordedErrorMessage, normalizeError, validateHandlerOutput, isUnsafeKey, safeJsonParse };
@@ -3,16 +3,16 @@ import {
3
3
  toJsonSchema
4
4
  } from "./index-0ed3bx43.js";
5
5
  import {
6
- formatZodError,
7
- isWithinDir,
8
- normalizeError,
9
- validateHandlerOutput
10
- } from "./index-zza375qp.js";
6
+ isWithinDir
7
+ } from "./index-x3fcszf8.js";
11
8
  import {
9
+ formatZodError,
12
10
  isRecord,
13
11
  isUnsafeKey,
14
- safeJsonParse
15
- } from "./index-c7nyw0yt.js";
12
+ normalizeError,
13
+ safeJsonParse,
14
+ validateHandlerOutput
15
+ } from "./index-enc7t99e.js";
16
16
 
17
17
  // src/tools/coerce.ts
18
18
  import { z } from "zod";
@@ -4,14 +4,8 @@ import {
4
4
  corsPreflightResponse
5
5
  } from "./index-czmqks7r.js";
6
6
  import {
7
- AppError,
8
- badRequest,
9
- errorCode,
10
- isWithinDir,
11
- mergeMeta,
12
- normalizeError,
13
- validateHandlerOutput
14
- } from "./index-zza375qp.js";
7
+ isWithinDir
8
+ } from "./index-x3fcszf8.js";
15
9
  import {
16
10
  extractIp,
17
11
  getClientInfo,
@@ -19,15 +13,23 @@ import {
19
13
  parseQueryParams,
20
14
  resolveSocketIp,
21
15
  resolveTraceId,
22
- setRequestEndpoint
23
- } from "./index-9g9d6r1h.js";
16
+ setRequestEndpoint,
17
+ setRequestError
18
+ } from "./index-wya8bkme.js";
24
19
  import {
20
+ AppError,
25
21
  __require,
22
+ badRequest,
23
+ errorCode,
26
24
  isRecord,
27
25
  isUnsafeKey,
26
+ mergeMeta,
27
+ normalizeError,
28
+ recordedErrorMessage,
28
29
  safeJsonParse,
29
- typedEntries
30
- } from "./index-c7nyw0yt.js";
30
+ typedEntries,
31
+ validateHandlerOutput
32
+ } from "./index-enc7t99e.js";
31
33
 
32
34
  // src/server/multipart.ts
33
35
  var DEFAULT_MAX_UPLOAD_BYTES = 25 * 1024 * 1024;
@@ -646,10 +648,22 @@ function createHandler(config) {
646
648
  } catch {}
647
649
  };
648
650
  const respondError = async (err, errCtx, endpoint) => {
651
+ const recordFailure = (normalized) => {
652
+ if (getRequestContext()?.error !== undefined)
653
+ return;
654
+ const known = AppError.is(err) ? err : normalized;
655
+ const code = known?.code ?? errorCode(err) ?? "INTERNAL_SERVER_ERROR";
656
+ setRequestError({
657
+ code,
658
+ message: recordedErrorMessage(code, known?.message, err),
659
+ details: known?.details
660
+ });
661
+ };
649
662
  if (hooks?.onError) {
650
663
  try {
651
664
  const response = await hooks.onError(errCtx ?? buildErrorContext(req, url, traceId, clientIp), err, endpoint);
652
665
  if (response instanceof Response) {
666
+ recordFailure();
653
667
  const withCors = applyCors(response, cors, req);
654
668
  logDone(withCors.status, errorCode(err));
655
669
  return withCors;
@@ -657,6 +671,7 @@ function createHandler(config) {
657
671
  } catch {}
658
672
  }
659
673
  const appErr = normalizeError(err);
674
+ recordFailure(appErr);
660
675
  logDone(appErr.status, appErr.code);
661
676
  return json(appErr.toJSON(), appErr.status, cors, req);
662
677
  };
@@ -2,13 +2,11 @@ import {
2
2
  base64UrlToBytes,
3
3
  bytesToBase64Url,
4
4
  forbidden,
5
- unauthorized
6
- } from "./index-zza375qp.js";
7
- import {
8
5
  isRecord,
9
6
  isUnsafeKey,
10
- safeJsonParse
11
- } from "./index-c7nyw0yt.js";
7
+ safeJsonParse,
8
+ unauthorized
9
+ } from "./index-enc7t99e.js";
12
10
 
13
11
  // src/server/middleware/cookies.ts
14
12
  function parseCookies(header) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  isRecord,
3
3
  isUnsafeKey
4
- } from "./index-c7nyw0yt.js";
4
+ } from "./index-enc7t99e.js";
5
5
 
6
6
  // src/server/request.ts
7
7
  function generateTraceId() {
@@ -0,0 +1,8 @@
1
+ // src/internal/within-dir.ts
2
+ import { sep } from "node:path";
3
+ function isWithinDir(root, target) {
4
+ const base = root.endsWith(sep) ? root.slice(0, -sep.length) : root;
5
+ return target === root || target === base || target.startsWith(base + sep);
6
+ }
7
+
8
+ export { isWithinDir };
@@ -24,6 +24,21 @@ export declare function zodIssues(error: z.ZodError): ZodIssueSummary[];
24
24
  * produced elsewhere — a custom `onError` hook that returns its own `Response`.
25
25
  */
26
26
  export declare function errorCode(err: unknown): string | undefined;
27
+ /**
28
+ * The message a **server-side record** should carry for a failure — an audit
29
+ * row, not a response.
30
+ *
31
+ * Normally the envelope's: it is truthful for an `AppError` or a `ZodError`, and
32
+ * it is what the caller was told, so the record and the response agree. The
33
+ * exception is the scrubbed one — an unexpected throw becomes
34
+ * `INTERNAL_SERVER_ERROR` / "Internal server error", which tells a later reader
35
+ * nothing at all, and there the raw message goes in instead.
36
+ *
37
+ * The line this holds is not "the framework never touches a raw message" but
38
+ * **"a raw message never crosses to the caller"**. Shared by the HTTP and tool
39
+ * paths so that line is one rule in one place. → ADR 0042.
40
+ */
41
+ export declare function recordedErrorMessage(code: string, envelopeMessage: string | undefined, thrown: unknown): string | undefined;
27
42
  export declare function normalizeError(err: unknown): AppError;
28
43
  /**
29
44
  * Validate a handler's return value against the contract `output` schema. A
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/internal/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAQvC,wBAAgB,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,GAAG,MAAM,CAMxD;AAED,qFAAqF;AACrF,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,GAAG,eAAe,EAAE,CAM9D;AAKD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAI1D;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,CAgBrD;AA4BD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,OAAO,EACb,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,GACrC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAe9D"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/internal/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAQvC,wBAAgB,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,GAAG,MAAM,CAMxD;AAED,qFAAqF;AACrF,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,GAAG,eAAe,EAAE,CAM9D;AAKD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAI1D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,MAAM,EAAE,OAAO,GACd,MAAM,GAAG,SAAS,CAMpB;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,CAgBrD;AA4BD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,OAAO,EACb,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,GACrC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAe9D"}
package/dist/node.js CHANGED
@@ -3,8 +3,10 @@ import {
3
3
  createImplement,
4
4
  createSocketIOServer,
5
5
  implement
6
- } from "./index-3hsagjqf.js";
6
+ } from "./index-k7ysesv0.js";
7
7
  import"./index-czmqks7r.js";
8
+ import"./index-x3fcszf8.js";
9
+ import"./index-wya8bkme.js";
8
10
  import {
9
11
  AppError,
10
12
  appError,
@@ -14,9 +16,7 @@ import {
14
16
  notFound,
15
17
  rateLimited,
16
18
  unauthorized
17
- } from "./index-zza375qp.js";
18
- import"./index-9g9d6r1h.js";
19
- import"./index-c7nyw0yt.js";
19
+ } from "./index-enc7t99e.js";
20
20
  // src/server/node.ts
21
21
  import { serve } from "srvx";
22
22
  async function serveNode(config) {
@@ -1 +1 @@
1
- {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/observability/audit.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,kBAAkB,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAe,KAAK,eAAe,EAAmB,MAAM,YAAY,CAAC;AAGhF,oCAAoC;AACpC,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,KAAK,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,iFAAiF;IACjF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC;IAC1C,yEAAyE;IACzE,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,qEAAqE;AACrE,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,IAAI,EAAE,CAAC,CAAC,EACN,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,KACpD,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpD;;;OAGG;IACH,QAAQ,EAAE,aAAa,CAAC;CACzB;AAyCD,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CA6G9D"}
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/observability/audit.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,kBAAkB,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAe,KAAK,eAAe,EAAmB,MAAM,YAAY,CAAC;AAGhF,oCAAoC;AACpC,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,KAAK,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,iFAAiF;IACjF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC;IAC1C,yEAAyE;IACzE,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,qEAAqE;AACrE,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,IAAI,EAAE,CAAC,CAAC,EACN,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,KACpD,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpD;;;OAGG;IACH,QAAQ,EAAE,aAAa,CAAC;CACzB;AA8BD,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CA6G9D"}
@@ -13,11 +13,12 @@ import {
13
13
  setRequestError,
14
14
  setRequestUser,
15
15
  wrapInRequestContext
16
- } from "../index-9g9d6r1h.js";
16
+ } from "../index-wya8bkme.js";
17
17
  import {
18
18
  isRecord,
19
- isUnsafeKey
20
- } from "../index-c7nyw0yt.js";
19
+ isUnsafeKey,
20
+ recordedErrorMessage
21
+ } from "../index-enc7t99e.js";
21
22
 
22
23
  // src/observability/sanitize.ts
23
24
  var DEFAULT_SENSITIVE_KEYS = /(password|passwd|pwd|secret|token|apikey|api[-_ ]?key|auth|authorization|bearer|session|cookie|init[-_ ]?data|credential|private[-_ ]?key)/i;
@@ -110,13 +111,7 @@ function toolErrorMessage(result) {
110
111
  return hint;
111
112
  }
112
113
  function auditErrorMessage(result, thrown) {
113
- if (result.code === "INTERNAL_SERVER_ERROR" && thrown !== undefined) {
114
- if (thrown instanceof Error)
115
- return thrown.message;
116
- if (typeof thrown === "string")
117
- return thrown;
118
- }
119
- return toolErrorMessage(result);
114
+ return recordedErrorMessage(result.code, toolErrorMessage(result), thrown);
120
115
  }
121
116
  function readString(value) {
122
117
  return typeof value === "string" ? value : undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/server/create.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAEV,eAAe,EACf,YAAY,EACZ,aAAa,EAGd,MAAM,SAAS,CAAC;AAEjB,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,YAAY,CA6XjE;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,uBAuBnD"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/server/create.ts"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EAEV,eAAe,EACf,YAAY,EACZ,aAAa,EAGd,MAAM,SAAS,CAAC;AAEjB,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,YAAY,CAoZjE;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,uBAuBnD"}
@@ -10,7 +10,7 @@ import {
10
10
  socketIoLane,
11
11
  staticRoute,
12
12
  webSocketLane
13
- } from "../index-3hsagjqf.js";
13
+ } from "../index-k7ysesv0.js";
14
14
  import {
15
15
  createAuthHook,
16
16
  createBearerResolver,
@@ -23,7 +23,7 @@ import {
23
23
  signJwt,
24
24
  verifyJwt,
25
25
  verifyPkce
26
- } from "../index-jvescqgr.js";
26
+ } from "../index-nmq59nae.js";
27
27
  import {
28
28
  DEFAULT_CORS_ALLOW_HEADERS,
29
29
  DEFAULT_CORS_EXPOSE_HEADERS,
@@ -34,6 +34,17 @@ import {
34
34
  jsonSchemaFields,
35
35
  toJsonSchema
36
36
  } from "../index-0ed3bx43.js";
37
+ import {
38
+ isWithinDir
39
+ } from "../index-x3fcszf8.js";
40
+ import {
41
+ extractIp,
42
+ generateTraceId,
43
+ getClientInfo,
44
+ getTraceId,
45
+ resolveSocketIp,
46
+ resolveTraceId
47
+ } from "../index-wya8bkme.js";
37
48
  import {
38
49
  AppError,
39
50
  STITCH_ERROR_STATUS,
@@ -43,25 +54,14 @@ import {
43
54
  errorCode,
44
55
  forbidden,
45
56
  formatZodError,
57
+ isRecord,
46
58
  isStitchErrorCode,
47
- isWithinDir,
48
59
  normalizeError,
49
60
  notFound,
50
61
  rateLimited,
51
62
  unauthorized,
52
63
  zodIssues
53
- } from "../index-zza375qp.js";
54
- import {
55
- extractIp,
56
- generateTraceId,
57
- getClientInfo,
58
- getTraceId,
59
- resolveSocketIp,
60
- resolveTraceId
61
- } from "../index-9g9d6r1h.js";
62
- import {
63
- isRecord
64
- } from "../index-c7nyw0yt.js";
64
+ } from "../index-enc7t99e.js";
65
65
  // src/server/swept-map.ts
66
66
  function createSweptMap(options) {
67
67
  const store = new Map;
package/dist/tools.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  inputIsQuery,
3
3
  signJwt,
4
4
  verifyPkce
5
- } from "./index-jvescqgr.js";
5
+ } from "./index-nmq59nae.js";
6
6
  import {
7
7
  DEFAULT_CORS_ALLOW_HEADERS
8
8
  } from "./index-czmqks7r.js";
@@ -21,22 +21,22 @@ import {
21
21
  readCapped,
22
22
  toolResultFromError,
23
23
  writeDownload
24
- } from "./index-36qnfzxe.js";
24
+ } from "./index-jr8vf7g8.js";
25
25
  import {
26
26
  toJsonSchema
27
27
  } from "./index-0ed3bx43.js";
28
28
  import {
29
- AppError,
30
- isWithinDir,
31
- mergeMeta
32
- } from "./index-zza375qp.js";
29
+ isWithinDir
30
+ } from "./index-x3fcszf8.js";
33
31
  import {
34
32
  getTraceId
35
- } from "./index-9g9d6r1h.js";
33
+ } from "./index-wya8bkme.js";
36
34
  import {
35
+ AppError,
37
36
  isRecord,
37
+ mergeMeta,
38
38
  typedEntries
39
- } from "./index-c7nyw0yt.js";
39
+ } from "./index-enc7t99e.js";
40
40
 
41
41
  // src/tools/agent.ts
42
42
  import { tool, zodSchema } from "ai";
package/llms-full.txt CHANGED
@@ -2879,10 +2879,22 @@ import {
2879
2879
  } from 'stitchkit/observability'
2880
2880
 
2881
2881
  createAuthHook({ /* … */ inject: (ctx, user) => user && setRequestUser(user.id) })
2882
- // in your onError hook:
2882
+ // only to override what the framework already recorded — see below:
2883
2883
  setRequestError({ code: err.code, message: err.message, details: err.issues })
2884
2884
  ```
2885
2885
 
2886
+ **The failure is recorded for you.** Every error travels one path inside the
2887
+ framework, and that path writes `{ code, message, details }` onto the context —
2888
+ so an audited failure names its cause whether or not you wrote an `onError`, and
2889
+ whether or not your `onError` returns its own `Response`. Where the envelope was
2890
+ scrubbed to `INTERNAL_SERVER_ERROR`, the row gets the **real** message rather than
2891
+ the placeholder; the caller still receives the scrubbed one. → ADR 0043
2892
+
2893
+ `setRequestError` is therefore an **override**, not the wiring: call it when you
2894
+ want the row to say something other than what the framework derived (a domain
2895
+ code, a curated message, structured issues). The framework writes only when the
2896
+ context carries nothing yet, so your value always wins.
2897
+
2886
2898
  **Endpoint identity is automatic.** The framework writes the matched operation's
2887
2899
  `(serviceName, action)` into the context at route-match, *before* validation — so
2888
2900
  `event.serviceName` / `event.action` are present on every event, including a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitchkit",
3
- "version": "0.32.0",
3
+ "version": "0.33.0",
4
4
  "description": "Contract-first backend framework — one defineContract() into an HTTP API, MCP tools, AI-agent tools and a typed client. Bun and Node.",
5
5
  "keywords": [
6
6
  "bun",
@@ -90,7 +90,8 @@
90
90
  "dev": "bun run build:js -- --watch",
91
91
  "prepublishOnly": "cp ../../README.md ./README.md && bun ../../scripts/gen-llms.ts && bun run build",
92
92
  "test": "bun test",
93
- "smoke:node": "node scripts/node-smoke.mjs"
93
+ "smoke:node": "node scripts/node-smoke.mjs",
94
+ "consumer-lane": "bun scripts/consumer-lane/run.mjs"
94
95
  },
95
96
  "peerDependencies": {
96
97
  "@modelcontextprotocol/ext-apps": "^1.7.2",
@@ -1,20 +0,0 @@
1
- import { createRequire } from "node:module";
2
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
3
-
4
- // src/internal/typed.ts
5
- function typedEntries(value) {
6
- return Object.entries(value);
7
- }
8
- function isRecord(value) {
9
- return typeof value === "object" && value !== null && !Array.isArray(value);
10
- }
11
-
12
- // src/internal/safe-json.ts
13
- function isUnsafeKey(key) {
14
- return key === "__proto__";
15
- }
16
- function safeJsonParse(text) {
17
- return JSON.parse(text, (key, value) => isUnsafeKey(key) ? undefined : value);
18
- }
19
-
20
- export { __require, typedEntries, isRecord, isUnsafeKey, safeJsonParse };