@pithy-sh/core 0.2.0 → 0.3.1

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 (68) hide show
  1. package/dist/capability/bindings.d.ts +5 -0
  2. package/dist/capability/bindings.d.ts.map +1 -1
  3. package/dist/capability/bindings.js +44 -3
  4. package/dist/capability/capability.d.ts +33 -0
  5. package/dist/capability/capability.d.ts.map +1 -1
  6. package/dist/capability/manifest.d.ts +5 -0
  7. package/dist/capability/manifest.d.ts.map +1 -1
  8. package/dist/capability/manifest.js +1 -1
  9. package/dist/capability/validateBindings.js +1 -1
  10. package/dist/controlPlane/http/cors.js +1 -1
  11. package/dist/createBackend.d.ts +2 -1
  12. package/dist/createBackend.d.ts.map +1 -1
  13. package/dist/createBackend.js +5 -4
  14. package/dist/error/http.d.ts +27 -5
  15. package/dist/error/http.d.ts.map +1 -1
  16. package/dist/error/http.js +33 -9
  17. package/dist/error/messageParams.d.ts +28 -0
  18. package/dist/error/messageParams.d.ts.map +1 -0
  19. package/dist/error/messageParams.js +31 -0
  20. package/dist/error/terminal.d.ts +16 -5
  21. package/dist/error/terminal.d.ts.map +1 -1
  22. package/dist/error/terminal.js +16 -5
  23. package/dist/http/oidcWebhook.d.ts +283 -0
  24. package/dist/http/oidcWebhook.d.ts.map +1 -0
  25. package/dist/http/oidcWebhook.js +414 -0
  26. package/dist/http/signedWebhook.d.ts +9 -65
  27. package/dist/http/signedWebhook.d.ts.map +1 -1
  28. package/dist/http/signedWebhook.js +19 -9
  29. package/dist/http/webhookWindow.d.ts +33 -0
  30. package/dist/http/webhookWindow.d.ts.map +1 -0
  31. package/dist/http/webhookWindow.js +35 -0
  32. package/dist/logger/errorHandler.d.ts +11 -0
  33. package/dist/logger/errorHandler.d.ts.map +1 -0
  34. package/dist/logger/errorHandler.js +87 -0
  35. package/dist/naming/environment.js +1 -1
  36. package/dist/naming/provisionScope.d.ts +108 -3
  37. package/dist/naming/provisionScope.d.ts.map +1 -1
  38. package/dist/naming/provisionScope.js +27 -2
  39. package/dist/naming/resource.js +1 -1
  40. package/dist/naming/resourceNames.js +1 -1
  41. package/dist/schema/describedness.d.ts +30 -1
  42. package/dist/schema/describedness.d.ts.map +1 -1
  43. package/dist/schema/describedness.js +42 -6
  44. package/dist/test-utils/oidcFixtures.d.ts +93 -0
  45. package/dist/test-utils/oidcFixtures.d.ts.map +1 -0
  46. package/dist/test-utils/oidcFixtures.js +111 -0
  47. package/dist/version.generated.d.ts +1 -1
  48. package/dist/version.generated.js +1 -1
  49. package/dist/workflow/naming.js +1 -1
  50. package/dist/workflow/stepMessage.d.ts +28 -3
  51. package/dist/workflow/stepMessage.d.ts.map +1 -1
  52. package/dist/workflow/stepMessage.js +48 -6
  53. package/package.json +1 -1
  54. package/src/capability/bindings.ts +49 -0
  55. package/src/capability/capability.ts +34 -0
  56. package/src/createBackend.ts +7 -3
  57. package/src/error/http.ts +34 -10
  58. package/src/error/messageParams.ts +38 -0
  59. package/src/error/terminal.ts +16 -5
  60. package/src/http/oidcWebhook.ts +672 -0
  61. package/src/http/signedWebhook.ts +44 -16
  62. package/src/http/webhookWindow.ts +35 -0
  63. package/src/logger/errorHandler.ts +94 -0
  64. package/src/naming/provisionScope.ts +150 -4
  65. package/src/schema/describedness.ts +51 -6
  66. package/src/test-utils/oidcFixtures.ts +138 -0
  67. package/src/version.generated.ts +1 -1
  68. package/src/workflow/stepMessage.ts +52 -6
@@ -57,6 +57,11 @@ export declare const BindingSpec: z.ZodObject<{
57
57
  job: z.ZodOptional<z.ZodString>;
58
58
  service: z.ZodOptional<z.ZodString>;
59
59
  remote: z.ZodOptional<z.ZodBoolean>;
60
+ scope: z.ZodOptional<z.ZodEnum<{
61
+ environment: "environment";
62
+ global: "global";
63
+ }>>;
64
+ resource: z.ZodOptional<z.ZodString>;
60
65
  }, z.core.$strip>;
61
66
  export type BindingSpec = z.infer<typeof BindingSpec>;
62
67
  /** Authoring shape for a capability's `requiredBindings`: `optional` may be omitted. */
@@ -1 +1 @@
1
- {"version":3,"file":"bindings.d.ts","sourceRoot":"","sources":["../../src/capability/bindings.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,WAAW,sTAmBuC,CAAC;AAChE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAE/D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAU3D;AAqBD;;;GAGG;AACH,eAAO,MAAM,WAAW;;;;;;;;;iBAqFpB,CAAC;AACL,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD,wFAAwF;AACxF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC"}
1
+ {"version":3,"file":"bindings.d.ts","sourceRoot":"","sources":["../../src/capability/bindings.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,WAAW,sTAmBuC,CAAC;AAChE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAE/D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAU3D;AAkCD;;;GAGG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;iBAwHpB,CAAC;AACL,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD,wFAAwF;AACxF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC"}
@@ -1,6 +1,7 @@
1
1
  // SPDX-FileCopyrightText: 2026 Pithy
2
2
  // SPDX-License-Identifier: MIT
3
3
  import { NAME_SEGMENT } from "../naming/segment.js";
4
+ import { FEATURE_RESOURCE_KINDS } from "../naming/feature.js";
4
5
  import { z } from "zod";
5
6
  //#region src/capability/bindings.ts
6
7
  const BindingType = z.union([
@@ -63,6 +64,35 @@ function isWrittenBinding(type) {
63
64
  return type === "d1" || type === "kv" || type === "r2" || type === "ai" || type === "durable_object" || type === "ratelimit" || type === "workflow";
64
65
  }
65
66
  /**
67
+ * A JavaScript class name — what `className` may be.
68
+ *
69
+ * Constrained because it is no longer only a JSON value. A Durable Object's `className` is written into
70
+ * the adopter's Worker entry as `export { <className> } from "…";` (#428), which is generated TypeScript
71
+ * built out of third-party data read from `node_modules` — the shape #171, #174 and #183 each met one
72
+ * field too late. An identifier cannot close the statement and open another.
73
+ */
74
+ const CLASS_NAME = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
75
+ /**
76
+ * A bare module specifier — a package, optionally with a path into it.
77
+ *
78
+ * The other half of the generated export line, and narrowed for the same reason. No quotes, no
79
+ * whitespace, no `..`: a specifier that walked back out of its own package would re-export whatever it
80
+ * landed on, which is `configImports.isInside`'s argument in a regex.
81
+ */
82
+ const CLASS_MODULE = /^(@[a-z0-9~-][a-z0-9._~-]*\/)?[a-z0-9~-][a-z0-9._~-]*(\/[A-Za-z0-9_~-][A-Za-z0-9._~-]*)*$/;
83
+ /**
84
+ * The kinds whose resource Pithy names and creates — the only kinds `scope` and `resource` mean anything
85
+ * for.
86
+ *
87
+ * {@link FEATURE_RESOURCE_KINDS} rather than a fresh literal, because it is already the repo's answer to
88
+ * "which bindings does a provisioning run compose a `<project>-<scope>-<thing>` name for": it is the
89
+ * domain of `ProvisionScope.resource`, and the CLI's own `PROVISIONABLE` map is the same three. Every
90
+ * other kind's name is composed by a different rule with no `<thing>` slot to fill — a Workflow's from
91
+ * the capability and the job, a Worker script's by wrangler — and a `secret` already states its scope in
92
+ * `defineSecretRegistry`, where the value it names lives.
93
+ */
94
+ const NAMED_RESOURCE_KINDS = new Set(FEATURE_RESOURCE_KINDS);
95
+ /**
66
96
  * Declares a Cloudflare binding a capability requires in the Worker env. The authoring
67
97
  * shape lets `optional` be omitted (defaults false); `createBackend` normalizes via parse.
68
98
  */
@@ -70,11 +100,13 @@ const BindingSpec = z.object({
70
100
  type: BindingType.describe("Resource kind this binding provides."),
71
101
  name: z.string().min(1).describe("Binding name expected in the Worker env (e.g. \"DB\", \"SESSIONS\")."),
72
102
  optional: z.boolean().default(false).describe("If true, createBackend won't fail when this binding is absent."),
73
- className: z.string().min(1).regex(/^[A-Za-z_$][A-Za-z0-9_$]*$/, "A className is a JavaScript identifier: letters, digits, `_` and `$`, not leading a digit.").optional().describe("The exported class this binding is backed by. For a `durable_object` binding it is the DO class (e.g. \"MultiplayerSession\") the CLI writes into `durable_objects.bindings`, the DO class migration tag, and the `export { … }` line in the Worker entry. For a `workflow` binding it is the `WorkflowEntrypoint` subclass (e.g. \"EmailSendWorkflow\") the CLI writes as `class_name` — the same value the capability's own `WorkflowSpec.className` carries. Ignored for every other kind."),
74
- classModule: z.string().min(1).regex(/^(@[a-z0-9~-][a-z0-9._~-]*\/)?[a-z0-9~-][a-z0-9._~-]*(\/[A-Za-z0-9_~-][A-Za-z0-9._~-]*)*$/, "A classModule is a bare module specifier: a package, optionally with a path into it.").optional().describe("The module the class is exported from (e.g. \"@pithy-sh/multiplayer/src/session/durableObject\") — what the CLI writes the Worker entry's `export { <className> } from \"<classModule>\";` against. Required for a `durable_object` binding, because wrangler resolves `class_name` against the entry `main` names and refuses the deploy when nothing there exports it. Its own module, never the package entry point, which `pithy.config.ts` loads in Node. Ignored for every other kind."),
103
+ className: z.string().min(1).regex(CLASS_NAME, "A className is a JavaScript identifier: letters, digits, `_` and `$`, not leading a digit.").optional().describe("The exported class this binding is backed by. For a `durable_object` binding it is the DO class (e.g. \"MultiplayerSession\") the CLI writes into `durable_objects.bindings`, the DO class migration tag, and the `export { … }` line in the Worker entry. For a `workflow` binding it is the `WorkflowEntrypoint` subclass (e.g. \"EmailSendWorkflow\") the CLI writes as `class_name` — the same value the capability's own `WorkflowSpec.className` carries. Ignored for every other kind."),
104
+ classModule: z.string().min(1).regex(CLASS_MODULE, "A classModule is a bare module specifier: a package, optionally with a path into it.").optional().describe("The module the class is exported from (e.g. \"@pithy-sh/multiplayer/src/session/durableObject\") — what the CLI writes the Worker entry's `export { <className> } from \"<classModule>\";` against. Required for a `durable_object` binding, because wrangler resolves `class_name` against the entry `main` names and refuses the deploy when nothing there exports it. Its own module, never the package entry point, which `pithy.config.ts` loads in Node. Ignored for every other kind."),
75
105
  job: z.string().min(1).regex(NAME_SEGMENT, "A job is one name segment: lowercase letters, digits, and single hyphens.").optional().describe("The job within the capability this Workflow runs (e.g. \"send\") — the `<job>` segment of the deployed `<project>-<env>-<capability>-<job>` name, and the second half of the `<capability>/<job>` dispatch key. Meaningful only for a `workflow` binding, where it is what lets `pithy add` name the Workflow offline instead of leaving the binding unwritten. Ignored for every other kind."),
76
106
  service: z.string().min(1).optional().describe("The Worker this binding calls, named as it appears in `apps/<name>/` (e.g. \"api\"). Meaningful only for a `service` binding — the CLI resolves it to that Worker's environment-scoped script name when writing `services` into wrangler.jsonc, so worker-to-worker RPC targets the right deployment per environment. Ignored for every other kind."),
77
- remote: z.boolean().optional().describe("Reach the real Cloudflare resource during local development instead of a local emulation. Set it for a binding that has none — Vectorize and Workers AI both lack local simulation — so `wrangler dev` and any Workflow host, which always runs locally, still work. Left unset rather than defaulting to false, so a spec that does not care emits no flag at all. Ignored in a deployed Worker.")
107
+ remote: z.boolean().optional().describe("Reach the real Cloudflare resource during local development instead of a local emulation. Set it for a binding that has none — Vectorize and Workers AI both lack local simulation — so `wrangler dev` and any Workflow host, which always runs locally, still work. Left unset rather than defaulting to false, so a spec that does not care emits no flag at all. Ignored in a deployed Worker."),
108
+ scope: z.enum(["environment", "global"]).optional().describe("Whether the resource behind this binding is one per environment (absent, the default) or one for the whole project. A `global` resource takes the literal `global` where the environment segment goes — `<project>-global-<thing>` — so every environment's stanza names the identical resource and provisioning creates it once. Declare it where the data is not an environment-local fact: `@pithy-sh/email`'s suppression list is one per project, because an unsubscribe recorded through a staging Worker has to be honored by a production one, and three per-environment databases meant it was not (#513). Say nothing where it is: a session store, a cache, and `@pithy-sh/secrets`' own database are per environment, and one line apart in the same env there is no convention to tell them apart by — which is why this is declared rather than inferred. Meaningful only for a `d1`, `kv` or `r2` binding."),
109
+ resource: z.string().min(1).regex(NAME_SEGMENT, "A resource is one name segment: lowercase letters, digits, and single hyphens.").optional().describe("The `<thing>` segment of this resource's name, when it is not the kebabbed binding name. Absent is the ordinary case and means the binding name is the segment (`EMAIL_SUPPRESSIONS` → `email-suppressions`). Declare it where the two must differ: `SUPPORT_BUCKET` backs `<project>-global-support`, because the binding keeps `_BUCKET` for whoever reads `env.SUPPORT_BUCKET` in a Worker while the resource drops it — `r2` is already the composed name's kind, so the suffix repeats it. Meaningful only for a `d1`, `kv` or `r2` binding.")
78
110
  }).describe("Declares a Cloudflare binding a capability requires in the Worker env.").check((ctx) => {
79
111
  if (ctx.value.type === "durable_object" && ctx.value.className === void 0) ctx.issues.push({
80
112
  code: "custom",
@@ -94,6 +126,15 @@ const BindingSpec = z.object({
94
126
  path: ["service"],
95
127
  message: `Service binding "${ctx.value.name}" needs a service — the Worker it calls, as named in apps/.`
96
128
  });
129
+ if (!NAMED_RESOURCE_KINDS.has(ctx.value.type)) for (const field of ["scope", "resource"]) {
130
+ if (ctx.value[field] === void 0) continue;
131
+ ctx.issues.push({
132
+ code: "custom",
133
+ input: ctx.value,
134
+ path: [field],
135
+ message: `Binding "${ctx.value.name}" declares a ${field}, which only a d1, kv or r2 binding has — this one is a ${ctx.value.type}.`
136
+ });
137
+ }
97
138
  });
98
139
  //#endregion
99
140
  export { BindingSpec, BindingType, isProvisionedBinding, isWrittenBinding };
@@ -156,6 +156,33 @@ export interface SecretRegistryEntrySeam {
156
156
  }
157
157
  /** A capability's secret-registry slice: secret name → {@link SecretRegistryEntrySeam}. */
158
158
  export type SecretRegistrySeam = Record<string, SecretRegistryEntrySeam>;
159
+ /**
160
+ * **Which branches of a `json` secret's schema this Worker's configuration actually uses** — secret
161
+ * name → the top-level keys that apply, in the order they should be offered.
162
+ *
163
+ * A `json` secret is often a bundle of independent blocks: `payments-provider-credentials` is five
164
+ * optional rail blocks, `turnstile-secret-keys` is two optional widgets. The schema says which blocks
165
+ * are *possible*; only the composed config says which are *real*, and a credential for a rail that is
166
+ * off is a value nothing will ever read. So `pithy secrets create` asks per field for the blocks named
167
+ * here, and never offers — never writes — one that is not.
168
+ *
169
+ * **It is declared, not matched by name.** `PaymentsRailToggles.paddle` and
170
+ * `PaymentsProviderCredentials.paddle` happen to be spelled the same today, and a CLI that keyed off
171
+ * that would be right by coincidence: nothing makes a config flag and a schema key the same thing, and
172
+ * two of them one line apart cannot be told apart by convention (#513). The capability already knows
173
+ * the answer at construction — it has both halves in hand — so it states it, and the CLI reads a fact
174
+ * instead of inferring one.
175
+ *
176
+ * **It lives on the capability rather than on the entry** because a registry entry is plain data,
177
+ * shared by every Worker that declares the name and projected into `pithy.manifest.json`. This answer
178
+ * is per composition — the same secret, two Workers, two configs — so it belongs where the config is.
179
+ *
180
+ * An absent declaration is not an empty one. A capability that says nothing leaves the CLI with no way
181
+ * to know which blocks apply, and it falls back to asking for the whole document rather than guessing;
182
+ * an empty array says *none of them apply*, which is the same fallback for a different reason. A
183
+ * secret whose schema has no branches at all needs no declaration — every field is asked.
184
+ */
185
+ export type SecretBranchSeam = Record<string, readonly string[]>;
159
186
  /**
160
187
  * The structural seam for one capability's token-profile slice — profile name → the scoped CF API
161
188
  * token that capability's code needs. Declared next to the code that uses it (alongside
@@ -280,6 +307,12 @@ export interface Capability<Databases extends DatabaseSpecMap = DatabaseSpecMap,
280
307
  * every declared secret in one batch — and no capability needs to know another's secrets.
281
308
  */
282
309
  secretRegistry?: SecretRegistrySeam;
310
+ /**
311
+ * Which branches of this capability's `json` secrets this Worker's configuration uses — see
312
+ * {@link SecretBranchSeam}. Additive and optional: a capability whose secrets are flat, or which has
313
+ * no `json` secret at all, declares nothing.
314
+ */
315
+ secretBranches?: SecretBranchSeam;
283
316
  /**
284
317
  * The scoped CF API tokens this capability's code needs, as a token-profile slice (profile name →
285
318
  * {@link TokenProfileSeam}). Additive and optional, and declared next to {@link Capability.secretRegistry}
@@ -1 +1 @@
1
- {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../../src/capability/capability.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../../src/capability/capability.ts"],"names":[],"mappings":"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"}
@@ -296,6 +296,11 @@ export declare const CapabilityManifest: z.ZodObject<{
296
296
  job: z.ZodOptional<z.ZodString>;
297
297
  service: z.ZodOptional<z.ZodString>;
298
298
  remote: z.ZodOptional<z.ZodBoolean>;
299
+ scope: z.ZodOptional<z.ZodEnum<{
300
+ environment: "environment";
301
+ global: "global";
302
+ }>>;
303
+ resource: z.ZodOptional<z.ZodString>;
299
304
  }, z.core.$strip>>;
300
305
  peerCapabilities: z.ZodDefault<z.ZodArray<z.ZodString>>;
301
306
  optionalCapabilities: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/capability/manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/capability/manifest.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  // SPDX-FileCopyrightText: 2026 Pithy
2
2
  // SPDX-License-Identifier: MIT
3
- import { BindingSpec } from "./bindings.js";
4
3
  import { ValidationError } from "../error/pithyError.js";
4
+ import { BindingSpec } from "./bindings.js";
5
5
  import { manifestRecord } from "./vanishingKey.js";
6
6
  import { DevSecret } from "./devSecret.js";
7
7
  import { NAMESPACE_PATTERN } from "../migrations/registry.js";
@@ -1,7 +1,7 @@
1
1
  // SPDX-FileCopyrightText: 2026 Pithy
2
2
  // SPDX-License-Identifier: MIT
3
- import { isProvisionedBinding } from "./bindings.js";
4
3
  import { InternalError } from "../error/pithyError.js";
4
+ import { isProvisionedBinding } from "./bindings.js";
5
5
  //#region src/capability/validateBindings.ts
6
6
  /** How a missing binding is named in both halves of the error: `kv:SESSIONS`. */
7
7
  function label(binding) {
@@ -1,8 +1,8 @@
1
1
  // SPDX-FileCopyrightText: 2026 Pithy
2
2
  // SPDX-License-Identifier: MIT
3
+ import "../../naming/environment.js";
3
4
  import "../../worker/identity.js";
4
5
  import { CONTROL_PLANE_HEADER, CONTROL_PLANE_VERSION_CREATED_HEADER, CONTROL_PLANE_VERSION_HEADER } from "../wire.js";
5
- import "../../naming/environment.js";
6
6
  //#region src/controlPlane/http/cors.ts
7
7
  /**
8
8
  * CORS for the control-plane surface — the one thing standing between a browser and a Worker that is
@@ -47,7 +47,8 @@ type BackendEnv<Caps extends readonly Capability[]> = {
47
47
  * each capability's middleware; and mounts the capability (then app) routes. On every request
48
48
  * `c.var.db` is the typed database registry — one `Kysely` per named database (`c.var.db.app`) —
49
49
  * and `c.var.kv` the typed namespace registry — one `TypedKv` per store (`c.var.kv.cms.pages`).
50
- * `PithyError`s become their declared HTTP status via {@link pithyErrorHandler}.
50
+ * `PithyError`s become their declared HTTP status via {@link loggingErrorHandler}, which also writes
51
+ * each fault to the request logger with its `action` and `detail` — the fields the wire body strips.
51
52
  *
52
53
  * Binding validation runs **once on the first request**, not at module load: in Workers `env` is
53
54
  * per-request, so there is no env to check until a request arrives. The result is memoized.
@@ -1 +1 @@
1
- {"version":3,"file":"createBackend.d.ts","sourceRoot":"","sources":["../src/createBackend.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EAEpB,SAAS,EACV,MAAM,yBAAyB,CAAC;AAKjC,OAAO,EAAqC,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAMtF,OAAO,EAA8B,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAK9C,OAAO,EAA2B,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGvF,oGAAoG;AACpG,MAAM,WAAW,oBAAoB,CAAC,IAAI,SAAS,SAAS,UAAU,EAAE,EAAE,GAAG,SAAS,UAAU;IAC9F,2EAA2E;IAC3E,YAAY,EAAE,IAAI,CAAC;IACnB;;;OAGG;IACH,GAAG,CAAC,EAAE,GAAG,CAAC;IACV;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,iHAAiH;AACjH,KAAK,UAAU,CAAC,IAAI,SAAS,SAAS,UAAU,EAAE,IAAI;IACpD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,GAAG,IAAI,GAAG,WAAW,CAAC,GAAG;QACtD,EAAE,EAAE,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;QACtC,EAAE,EAAE,UAAU,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;QACzC,SAAS,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC;KAC3D,CAAC;CACH,CAAC;AAuCF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAC3B,KAAK,CAAC,IAAI,SAAS,SAAS,UAAU,EAAE,EACxC,KAAK,CAAC,GAAG,SAAS,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,EACrF,OAAO,EAAE,oBAAoB,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAuKrF"}
1
+ {"version":3,"file":"createBackend.d.ts","sourceRoot":"","sources":["../src/createBackend.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EAEpB,SAAS,EACV,MAAM,yBAAyB,CAAC;AAKjC,OAAO,EAAqC,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAKtF,OAAO,EAA8B,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAK9C,OAAO,EAA2B,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGvF,oGAAoG;AACpG,MAAM,WAAW,oBAAoB,CAAC,IAAI,SAAS,SAAS,UAAU,EAAE,EAAE,GAAG,SAAS,UAAU;IAC9F,2EAA2E;IAC3E,YAAY,EAAE,IAAI,CAAC;IACnB;;;OAGG;IACH,GAAG,CAAC,EAAE,GAAG,CAAC;IACV;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,iHAAiH;AACjH,KAAK,UAAU,CAAC,IAAI,SAAS,SAAS,UAAU,EAAE,IAAI;IACpD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,GAAG,IAAI,GAAG,WAAW,CAAC,GAAG;QACtD,EAAE,EAAE,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;QACtC,EAAE,EAAE,UAAU,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;QACzC,SAAS,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC;KAC3D,CAAC;CACH,CAAC;AAuCF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAC3B,KAAK,CAAC,IAAI,SAAS,SAAS,UAAU,EAAE,EACxC,KAAK,CAAC,GAAG,SAAS,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,EACrF,OAAO,EAAE,oBAAoB,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CA0KrF"}
@@ -1,8 +1,8 @@
1
1
  // SPDX-FileCopyrightText: 2026 Pithy
2
2
  // SPDX-License-Identifier: MIT
3
3
  import { noopEmit } from "./audit/recorder.js";
4
- import { BindingSpec } from "./capability/bindings.js";
5
4
  import { ValidationError } from "./error/pithyError.js";
5
+ import { BindingSpec } from "./capability/bindings.js";
6
6
  import { recordComposition } from "./capability/composition.js";
7
7
  import { validateBindings } from "./capability/validateBindings.js";
8
8
  import { workerVersion } from "./worker/identity.js";
@@ -10,11 +10,11 @@ import { isControlPlaneCapability } from "./controlPlane/capability.js";
10
10
  import { allowedOriginSet, corsSurface, registerControlPlaneCors } from "./controlPlane/http/cors.js";
11
11
  import { buildDbRegistry, composeDatabases } from "./data/databases.js";
12
12
  import { noEntitlementProvider } from "./entitlement/entitlement.js";
13
- import { pithyErrorHandler } from "./error/http.js";
14
13
  import { bakedTranslator } from "./i18n/translator.js";
15
14
  import { catalogFor, composeMessages } from "./i18n/registry.js";
16
15
  import { buildKvRegistry, composeKv } from "./kv/namespaces.js";
17
16
  import { bindRequestContext, createWorkerLogger } from "./logger/worker.js";
17
+ import { loggingErrorHandler } from "./logger/errorHandler.js";
18
18
  import { HEALTH_PATH } from "./worker/health.js";
19
19
  import { registeredWorkflowBinding } from "./workflow/bindings.js";
20
20
  import { buildWorkflowDispatcher } from "./workflow/dispatch.js";
@@ -63,7 +63,8 @@ function envNameOf(env, fallback) {
63
63
  * each capability's middleware; and mounts the capability (then app) routes. On every request
64
64
  * `c.var.db` is the typed database registry — one `Kysely` per named database (`c.var.db.app`) —
65
65
  * and `c.var.kv` the typed namespace registry — one `TypedKv` per store (`c.var.kv.cms.pages`).
66
- * `PithyError`s become their declared HTTP status via {@link pithyErrorHandler}.
66
+ * `PithyError`s become their declared HTTP status via {@link loggingErrorHandler}, which also writes
67
+ * each fault to the request logger with its `action` and `detail` — the fields the wire body strips.
67
68
  *
68
69
  * Binding validation runs **once on the first request**, not at module load: in Workers `env` is
69
70
  * per-request, so there is no env to check until a request arrives. The result is memoized.
@@ -98,7 +99,7 @@ function createBackend(options) {
98
99
  ...Object.values(workflows).map((entry) => BindingSpec.parse(registeredWorkflowBinding(entry)))
99
100
  ]);
100
101
  const app = new Hono();
101
- app.onError(pithyErrorHandler);
102
+ app.onError(loggingErrorHandler);
102
103
  const baseLogger = options.logger ?? createWorkerLogger();
103
104
  const controlPlane = all.find(isControlPlaneCapability);
104
105
  if (controlPlane) {
@@ -2,6 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  import type { Context } from "hono";
4
4
  import { z } from "zod";
5
+ import { PithyError } from "./pithyError";
5
6
  /**
6
7
  * The HTTP surface of an error, as a real codec. `encode` (server emits) maps an in-memory
7
8
  * `ErrorPayload` down to the public wire shape by calling {@link clientError} — **the security
@@ -1508,11 +1509,32 @@ export declare const HttpError: z.ZodCodec<z.ZodUnion<readonly [z.ZodDiscriminat
1508
1509
  status: z.ZodInt;
1509
1510
  }, z.core.$strip>]>>;
1510
1511
  /**
1511
- * Hono `onError` handler. Register once on the root app (`app.onError(pithyErrorHandler)`): any
1512
- * `PithyError` becomes `{ error: <public payload> }` at its declared status; a Hono `HTTPException`
1513
- * 400 becomes `validation/invalid_input`; any other throw is wrapped as a `core/internal` 500
1514
- * carrying the original as `cause` (kept internal) and a generic public message — mirroring the
1515
- * CLI's "unexpected crash" path.
1512
+ * Whatever was thrown, as the `PithyError` the response will be rendered from.
1513
+ *
1514
+ * A `PithyError` is itself; a Hono `HTTPException` 400 becomes `validation/invalid_input`; anything
1515
+ * else is wrapped as a `core/internal` 500 carrying the original as `cause` (kept internal) and a
1516
+ * generic public message — mirroring the CLI's "unexpected crash" path.
1517
+ *
1518
+ * Split out from {@link pithyErrorHandler} so a caller that wants to **read** the fault before it is
1519
+ * encoded — the logging handler in `logger/errorHandler.ts` — works from the same object the response
1520
+ * is built from, rather than translating a second time and logging a different instance of it. The
1521
+ * split is what keeps this module free of the logger: the translation is exported, the log is written
1522
+ * on the other side of the boundary. See `logger/boundary.test.ts`.
1523
+ */
1524
+ export declare function toPithyError(err: Error): PithyError;
1525
+ /** Render an already-translated fault as its HTTP response — the client half, and only that. */
1526
+ export declare function renderPithyError(pithy: PithyError, c: Context): Response;
1527
+ /**
1528
+ * Hono `onError` handler — the **encoder**, with no log of its own.
1529
+ *
1530
+ * Any `PithyError` becomes `{ error: <public payload> }` at its declared status; a Hono
1531
+ * `HTTPException` 400 becomes `validation/invalid_input`; any other throw is wrapped as a
1532
+ * `core/internal` 500.
1533
+ *
1534
+ * **Prefer `loggingErrorHandler` from `logger/errorHandler.ts`** — `createBackend` registers that one,
1535
+ * and it is what makes a misconfiguration's `action` reach an operator instead of dying at the wire
1536
+ * (#521). This one stays exported for an app assembled without the logger seam, and it stays here,
1537
+ * logger-free, because this module is on the client side of the logger boundary.
1516
1538
  */
1517
1539
  export declare function pithyErrorHandler(err: Error, c: Context): Response;
1518
1540
  //# sourceMappingURL=http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/error/http.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAGpC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBA8BpB,CAAC;AAeH;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,GAAG,QAAQ,CAUlE"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/error/http.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAGpC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAA4B,UAAU,EAAmB,MAAM,cAAc,CAAC;AAErF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBA8BpB,CAAC;AAeH;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,KAAK,GAAG,UAAU,CAInD;AAED,gGAAgG;AAChG,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,OAAO,GAAG,QAAQ,CAKxE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,GAAG,QAAQ,CAElE"}
@@ -59,16 +59,40 @@ function fromHttpException(error) {
59
59
  });
60
60
  }
61
61
  /**
62
- * Hono `onError` handler. Register once on the root app (`app.onError(pithyErrorHandler)`): any
63
- * `PithyError` becomes `{ error: <public payload> }` at its declared status; a Hono `HTTPException`
64
- * 400 becomes `validation/invalid_input`; any other throw is wrapped as a `core/internal` 500
65
- * carrying the original as `cause` (kept internal) and a generic public message — mirroring the
66
- * CLI's "unexpected crash" path.
62
+ * Whatever was thrown, as the `PithyError` the response will be rendered from.
63
+ *
64
+ * A `PithyError` is itself; a Hono `HTTPException` 400 becomes `validation/invalid_input`; anything
65
+ * else is wrapped as a `core/internal` 500 carrying the original as `cause` (kept internal) and a
66
+ * generic public message — mirroring the CLI's "unexpected crash" path.
67
+ *
68
+ * Split out from {@link pithyErrorHandler} so a caller that wants to **read** the fault before it is
69
+ * encoded — the logging handler in `logger/errorHandler.ts` — works from the same object the response
70
+ * is built from, rather than translating a second time and logging a different instance of it. The
71
+ * split is what keeps this module free of the logger: the translation is exported, the log is written
72
+ * on the other side of the boundary. See `logger/boundary.test.ts`.
67
73
  */
68
- function pithyErrorHandler(err, c) {
69
- const translated = err instanceof HTTPException ? fromHttpException(err) : null;
70
- const pithy = err instanceof PithyError ? err : translated ?? new InternalError({ detail: err instanceof Error ? err.message : String(err) }, { cause: err });
74
+ function toPithyError(err) {
75
+ if (err instanceof PithyError) return err;
76
+ return (err instanceof HTTPException ? fromHttpException(err) : null) ?? new InternalError({ detail: err instanceof Error ? err.message : String(err) }, { cause: err });
77
+ }
78
+ /** Render an already-translated fault as its HTTP response — the client half, and only that. */
79
+ function renderPithyError(pithy, c) {
71
80
  return c.json({ error: HttpError.encode(pithy.payload) }, pithy.payload.status);
72
81
  }
82
+ /**
83
+ * Hono `onError` handler — the **encoder**, with no log of its own.
84
+ *
85
+ * Any `PithyError` becomes `{ error: <public payload> }` at its declared status; a Hono
86
+ * `HTTPException` 400 becomes `validation/invalid_input`; any other throw is wrapped as a
87
+ * `core/internal` 500.
88
+ *
89
+ * **Prefer `loggingErrorHandler` from `logger/errorHandler.ts`** — `createBackend` registers that one,
90
+ * and it is what makes a misconfiguration's `action` reach an operator instead of dying at the wire
91
+ * (#521). This one stays exported for an app assembled without the logger seam, and it stays here,
92
+ * logger-free, because this module is on the client side of the logger boundary.
93
+ */
94
+ function pithyErrorHandler(err, c) {
95
+ return renderPithyError(toPithyError(err), c);
96
+ }
73
97
  //#endregion
74
- export { HttpError, pithyErrorHandler };
98
+ export { HttpError, pithyErrorHandler, renderPithyError, toPithyError };
@@ -0,0 +1,28 @@
1
+ // SPDX-FileCopyrightText: 2026 Pithy
2
+ // SPDX-License-Identifier: MIT
3
+ import type { KitErrorCode } from "./payload";
4
+ /**
5
+ * The `params` a throw site **guarantees** for a kit error code — and therefore the only names a
6
+ * locale may write as a `{placeholder}` in that code's sentence.
7
+ *
8
+ * **Why a declaration exists at all.** `params` crosses the wire with `message` so a translating
9
+ * client can render its own wording for a code (CLAUDE.md §Errors), and `interpolate` leaves a
10
+ * placeholder nobody supplied written out as `{apiAnswer}`. So a locale writing a placeholder is
11
+ * making a claim about a *call site*, and a call is not a declaration — there was nothing in this
12
+ * repository for a catalog test to read, which is why `@pithy-sh/i18n` could only pin the absence of
13
+ * placeholders. This is that missing half: one table, in `core`, that both sides import.
14
+ *
15
+ * **Guaranteed means every throw, not most.** A name belongs here only when the code's throw sites
16
+ * pass it on **every** path, including the degraded one — a Cloudflare call that never reached
17
+ * Cloudflare still supplies `apiAnswer`, as the empty string. A param a throw site passes only
18
+ * sometimes is still useful to a client reading `payload.params` directly, and is still stripped from
19
+ * nothing; it simply may not be written into a sentence, because the sentence has to render on the
20
+ * path where it is missing.
21
+ *
22
+ * A code absent from this table guarantees nothing, which is the honest default and the state of all
23
+ * but one of them.
24
+ */
25
+ export declare const GUARANTEED_ERROR_PARAMS: Partial<Record<KitErrorCode, readonly string[]>>;
26
+ /** The names a locale may interpolate into `code`'s sentence. Empty when the code guarantees none. */
27
+ export declare function guaranteedErrorParams(code: string): readonly string[];
28
+ //# sourceMappingURL=messageParams.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messageParams.d.ts","sourceRoot":"","sources":["../../src/error/messageParams.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,uBAAuB,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC,CAMpF,CAAC;AAEF,sGAAsG;AACtG,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAErE"}
@@ -0,0 +1,31 @@
1
+ // SPDX-FileCopyrightText: 2026 Pithy
2
+ // SPDX-License-Identifier: MIT
3
+ //#region src/error/messageParams.ts
4
+ /**
5
+ * The `params` a throw site **guarantees** for a kit error code — and therefore the only names a
6
+ * locale may write as a `{placeholder}` in that code's sentence.
7
+ *
8
+ * **Why a declaration exists at all.** `params` crosses the wire with `message` so a translating
9
+ * client can render its own wording for a code (CLAUDE.md §Errors), and `interpolate` leaves a
10
+ * placeholder nobody supplied written out as `{apiAnswer}`. So a locale writing a placeholder is
11
+ * making a claim about a *call site*, and a call is not a declaration — there was nothing in this
12
+ * repository for a catalog test to read, which is why `@pithy-sh/i18n` could only pin the absence of
13
+ * placeholders. This is that missing half: one table, in `core`, that both sides import.
14
+ *
15
+ * **Guaranteed means every throw, not most.** A name belongs here only when the code's throw sites
16
+ * pass it on **every** path, including the degraded one — a Cloudflare call that never reached
17
+ * Cloudflare still supplies `apiAnswer`, as the empty string. A param a throw site passes only
18
+ * sometimes is still useful to a client reading `payload.params` directly, and is still stripped from
19
+ * nothing; it simply may not be written into a sentence, because the sentence has to render on the
20
+ * path where it is missing.
21
+ *
22
+ * A code absent from this table guarantees nothing, which is the honest default and the state of all
23
+ * but one of them.
24
+ */
25
+ const GUARANTEED_ERROR_PARAMS = { "cloudflare/request_failed": ["apiAnswer"] };
26
+ /** The names a locale may interpolate into `code`'s sentence. Empty when the code guarantees none. */
27
+ function guaranteedErrorParams(code) {
28
+ return GUARANTEED_ERROR_PARAMS[code] ?? [];
29
+ }
30
+ //#endregion
31
+ export { GUARANTEED_ERROR_PARAMS, guaranteedErrorParams };
@@ -3,11 +3,22 @@
3
3
  import type { ErrorPayload } from "./payload";
4
4
  import { PublicErrorPayload } from "./payload";
5
5
  /**
6
- * Render an error for the terminal: the public `message` becomes the problem line and the
7
- * optional `action` the action line — the two-line brand-voice shape `docs/CLI.md` §3.3 specifies.
8
- * This unifies the CLI's error output into the one `PithyError` family: the CLI catches a
9
- * `PithyError`, colorizes the first line via its `style.ts`, and prints this. `detail` is internal
10
- * and never rendered. The same payload that encodes to HTTP renders here — one error, two surfaces.
6
+ * Render an error for the terminal: the public `message` on top and the optional `action` last — the
7
+ * brand-voice shape `docs/CLI.md` §3.3 specifies. This unifies the CLI's error output into the one
8
+ * `PithyError` family: the CLI catches a `PithyError`, colorizes via its `style.ts`, and prints this.
9
+ * `detail` is internal and never rendered. The same payload that encodes to HTTP renders here — one
10
+ * error, two surfaces.
11
+ *
12
+ * **`message` is one line, and the newline this adds is the only one in the rendering.** #534 tried
13
+ * the other way — a problem line with an upstream's `errors[]` indented beneath it, which reads
14
+ * beautifully in a terminal and is unencodable everywhere else. The newline is a *field separator* in
15
+ * two places that matter more than the indent does. `../workflow/stepMessage` uses it to carry a
16
+ * terminal step's remedy across a durable boundary, so a multi-line `message` raised inside a Workflow
17
+ * step was declined whole and the operator got the platform's prose about durable execution instead of
18
+ * the refusal. And here, the action line is the one line after the message, so a `message` carrying a
19
+ * break puts upstream text where the remedy goes — a forged action line, from text a Worker we did not
20
+ * write can choose. Upstream words are marked with a word (`Cloudflare said:`), never with a line: a
21
+ * word survives a step record, a `--json` line and a browser.
11
22
  */
12
23
  export declare function renderTerminal(payload: ErrorPayload): string;
13
24
  /** An error as an operator's machine surface states it: the wire fields, plus the remedy. */
@@ -1 +1 @@
1
- {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/error/terminal.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAE5D;AAED,6FAA6F;AAC7F,MAAM,MAAM,aAAa,GAAG,kBAAkB,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAErE;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,aAAa,CAGlE"}
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/error/terminal.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAE5D;AAED,6FAA6F;AAC7F,MAAM,MAAM,aAAa,GAAG,kBAAkB,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAErE;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,aAAa,CAGlE"}
@@ -3,11 +3,22 @@
3
3
  import { PublicErrorPayload } from "./payload.js";
4
4
  //#region src/error/terminal.ts
5
5
  /**
6
- * Render an error for the terminal: the public `message` becomes the problem line and the
7
- * optional `action` the action line — the two-line brand-voice shape `docs/CLI.md` §3.3 specifies.
8
- * This unifies the CLI's error output into the one `PithyError` family: the CLI catches a
9
- * `PithyError`, colorizes the first line via its `style.ts`, and prints this. `detail` is internal
10
- * and never rendered. The same payload that encodes to HTTP renders here — one error, two surfaces.
6
+ * Render an error for the terminal: the public `message` on top and the optional `action` last — the
7
+ * brand-voice shape `docs/CLI.md` §3.3 specifies. This unifies the CLI's error output into the one
8
+ * `PithyError` family: the CLI catches a `PithyError`, colorizes via its `style.ts`, and prints this.
9
+ * `detail` is internal and never rendered. The same payload that encodes to HTTP renders here — one
10
+ * error, two surfaces.
11
+ *
12
+ * **`message` is one line, and the newline this adds is the only one in the rendering.** #534 tried
13
+ * the other way — a problem line with an upstream's `errors[]` indented beneath it, which reads
14
+ * beautifully in a terminal and is unencodable everywhere else. The newline is a *field separator* in
15
+ * two places that matter more than the indent does. `../workflow/stepMessage` uses it to carry a
16
+ * terminal step's remedy across a durable boundary, so a multi-line `message` raised inside a Workflow
17
+ * step was declined whole and the operator got the platform's prose about durable execution instead of
18
+ * the refusal. And here, the action line is the one line after the message, so a `message` carrying a
19
+ * break puts upstream text where the remedy goes — a forged action line, from text a Worker we did not
20
+ * write can choose. Upstream words are marked with a word (`Cloudflare said:`), never with a line: a
21
+ * word survives a step record, a `--json` line and a browser.
11
22
  */
12
23
  function renderTerminal(payload) {
13
24
  return payload.action ? `${payload.message}\n${payload.action}` : payload.message;