@nwire/handler 0.7.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alex Gefter / 200apps Ltd.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # @nwire/handler
2
+
3
+ > Operation primitive — one shape for action / query / resolver, usable from any transport.
4
+
5
+ ## What it is
6
+
7
+ `defineHandler(name, config)` describes a single operation: input schema, response shape, the function. `execute(handler, input, ctx?)` runs one. Same shape whether the caller is HTTP, a queue worker, a CLI command, or an MCP tool. No framework lock-in — a foreign host (Express, Fastify, NestJS) can mount a handler with two lines of glue.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ pnpm add @nwire/handler
13
+ ```
14
+
15
+ ## Standalone use
16
+
17
+ For developers who want a portable operation primitive without pulling in the rest of Nwire. Define a handler once, run it from anywhere.
18
+
19
+ ```ts
20
+ import { defineHandler, execute, ok } from "@nwire/handler";
21
+ import { z } from "zod";
22
+
23
+ const createUser = defineHandler("createUser", {
24
+ input: z.object({ email: z.string().email() }),
25
+ handler: async ({ input }) => ok({ id: crypto.randomUUID(), email: input.email }),
26
+ });
27
+
28
+ // Run it directly:
29
+ const res = await execute(createUser, { email: "a@b.co" });
30
+
31
+ // Or mount in Express:
32
+ app.post("/users", async (req, res) => {
33
+ const out = await execute(createUser, req.body);
34
+ res.status(out.status).json(out.body);
35
+ });
36
+ ```
37
+
38
+ ## Within nwire-app
39
+
40
+ For developers using this package as part of the Nwire stack. Every Nwire transport (`@nwire/http`, `@nwire/queue`, `@nwire/mcp`) speaks this exact shape; `@nwire/forge`'s `defineAction` / `defineQuery` are flavored sugar over `defineHandler`.
41
+
42
+ ```ts
43
+ import { defineAction } from "@nwire/forge"; // sugar over defineHandler
44
+ import { httpInterface, post } from "@nwire/http";
45
+
46
+ const createUser = defineAction("createUser", {
47
+ input: z.object({ email: z.string().email() }),
48
+ handler: async ({ input }) => ({ id: crypto.randomUUID(), email: input.email }),
49
+ });
50
+
51
+ const api = httpInterface("api").wire(post("/users", createUser));
52
+ ```
53
+
54
+ ## API
55
+
56
+ - `defineHandler(name, config)` — declare an operation: `{ input, handler, returns?, errors?, summary?, policy?, emits? }`.
57
+ - `execute(handler, input, ctx?)` — run one; returns a response envelope.
58
+ - `defineResource(...)` / `defineError(...)` — REST resource + typed error definitions.
59
+ - Response factories: `ok` / `created` / `accepted` / `noContent` / `notFound` / etc.
60
+
61
+ ## See also
62
+
63
+ - [Architecture sketch §08 — Handler, the operation](../../architecture-sketch.html#handler)
64
+ - Sibling packages: [@nwire/hooks](../nwire-hooks), [@nwire/interface](../nwire-interface), [@nwire/http](../nwire-http)
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Smoke tests for the `@nwire/handler` standalone primitives.
3
+ *
4
+ * Verifies:
5
+ * - `defineHandler` produces a value-shaped definition + .run accessor
6
+ * - `execute` validates input against the schema, throws on bad input
7
+ * - `execute` invokes the handler with the parsed input
8
+ * - `defineError` / `NwireError` typed throwable contract
9
+ * - response factories (ok/created/accepted/noContent) return tagged instances
10
+ * - `defineResource` projects records through declared `public` fields
11
+ * - `pipe()` composes middleware + hooks in declaration order
12
+ *
13
+ * These are deliberately minimal — they document the standalone public
14
+ * surface. Full coverage of the chained DX (transports, runtime,
15
+ * middleware execution) lives in forge / http / queue test suites.
16
+ */
17
+ export {};
18
+ //# sourceMappingURL=define-handler.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-handler.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/define-handler.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Smoke tests for the `@nwire/handler` standalone primitives.
3
+ *
4
+ * Verifies:
5
+ * - `defineHandler` produces a value-shaped definition + .run accessor
6
+ * - `execute` validates input against the schema, throws on bad input
7
+ * - `execute` invokes the handler with the parsed input
8
+ * - `defineError` / `NwireError` typed throwable contract
9
+ * - response factories (ok/created/accepted/noContent) return tagged instances
10
+ * - `defineResource` projects records through declared `public` fields
11
+ * - `pipe()` composes middleware + hooks in declaration order
12
+ *
13
+ * These are deliberately minimal — they document the standalone public
14
+ * surface. Full coverage of the chained DX (transports, runtime,
15
+ * middleware execution) lives in forge / http / queue test suites.
16
+ */
17
+ import { describe, it, expect } from "vitest";
18
+ import { z } from "zod";
19
+ import { defineHandler, execute, defineError, NwireError, isNwireError, defineResource, defineMiddleware, defineHook, pipe, ok, created, accepted, noContent, isResponseInstance, } from "../handler-index.js";
20
+ describe("defineHandler", () => {
21
+ it("returns a value with $kind, name, config, .run", () => {
22
+ const h = defineHandler("noop", {
23
+ handler: async () => 42,
24
+ });
25
+ expect(h.$kind).toBe("handler");
26
+ expect(h.name).toBe("noop");
27
+ expect(typeof h.run).toBe("function");
28
+ });
29
+ it("execute() parses input against the declared schema", async () => {
30
+ const Echo = defineHandler("echo", {
31
+ input: z.object({ msg: z.string() }),
32
+ handler: async ({ input }) => input.msg,
33
+ });
34
+ const result = await execute(Echo, { msg: "hello" });
35
+ expect(result).toBe("hello");
36
+ });
37
+ it("execute() throws when input violates the schema", async () => {
38
+ const Echo = defineHandler("echo", {
39
+ input: z.object({ msg: z.string() }),
40
+ handler: async ({ input }) => input.msg,
41
+ });
42
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
+ await expect(execute(Echo, { msg: 123 })).rejects.toBeDefined();
44
+ });
45
+ it("execute() works without an input schema", async () => {
46
+ const Health = defineHandler("health", {
47
+ handler: async () => ({ status: "up" }),
48
+ });
49
+ expect(await execute(Health, undefined)).toEqual({ status: "up" });
50
+ });
51
+ });
52
+ describe("defineError + NwireError", () => {
53
+ it("produces a throwable that is both Error and NwireError", () => {
54
+ const Boom = defineError({ code: "BOOM", status: 418, summary: "boom" });
55
+ expect(Boom).toBeInstanceOf(Error);
56
+ expect(Boom).toBeInstanceOf(NwireError);
57
+ expect(isNwireError(Boom)).toBe(true);
58
+ expect(Boom.code).toBe("BOOM");
59
+ expect(Boom.status).toBe(418);
60
+ });
61
+ it(".with() returns a contextualized clone", () => {
62
+ const Boom = defineError({ code: "BOOM", status: 418, summary: "boom" });
63
+ const withCtx = Boom.with({ resourceId: "abc" });
64
+ expect(withCtx.code).toBe("BOOM");
65
+ expect(withCtx.context).toEqual({ resourceId: "abc" });
66
+ });
67
+ });
68
+ describe("response factories", () => {
69
+ it("ok() returns 200 instances; created() returns 201", () => {
70
+ const okI = ok()();
71
+ expect(okI.status).toBe(200);
72
+ expect(isResponseInstance(okI)).toBe(true);
73
+ const createdI = created()();
74
+ expect(createdI.status).toBe(201);
75
+ const acceptedI = accepted()();
76
+ expect(acceptedI.status).toBe(202);
77
+ const empty = noContent()();
78
+ expect(empty.status).toBe(204);
79
+ });
80
+ });
81
+ describe("defineResource", () => {
82
+ it("projects records through declared public fields", () => {
83
+ const Wash = defineResource("Wash", {
84
+ schema: z.object({ id: z.string(), secret: z.string(), name: z.string() }),
85
+ public: ["id", "name"],
86
+ });
87
+ const out = Wash.project({ id: "1", secret: "x", name: "Quick" });
88
+ expect(out).toEqual({ id: "1", name: "Quick" });
89
+ });
90
+ it("returns examples by name", () => {
91
+ const Wash = defineResource("Wash", {
92
+ schema: z.object({ id: z.string(), name: z.string() }),
93
+ examples: { quick: { id: "1", name: "Quick" } },
94
+ });
95
+ expect(Wash.example("quick")).toEqual({ id: "1", name: "Quick" });
96
+ expect(() => Wash.example("missing")).toThrow();
97
+ });
98
+ });
99
+ describe("pipe / defineMiddleware / defineHook", () => {
100
+ it("flattens nested pipes and tags steps", () => {
101
+ const a = defineMiddleware("a", async (_ctx, next) => { await next(); });
102
+ const b = defineMiddleware("b", async (_ctx, next) => { await next(); });
103
+ const after = defineHook("after", "audit", () => undefined);
104
+ const inner = pipe(a, b);
105
+ const outer = pipe(inner, after);
106
+ expect(outer.$kind).toBe("pipe");
107
+ expect(outer.steps).toHaveLength(3);
108
+ expect(outer.steps[0].$kind).toBe("middleware");
109
+ expect(outer.steps[2].$kind).toBe("hook");
110
+ });
111
+ });
112
+ //# sourceMappingURL=define-handler.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-handler.test.js","sourceRoot":"","sources":["../../src/__tests__/define-handler.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * `defineError` — a named, typed, throwable error value.
3
+ *
4
+ * const WashInProgress = defineError({
5
+ * code: "WASH_IN_PROGRESS",
6
+ * status: 409,
7
+ * summary: "Station already has an unfinished wash",
8
+ * });
9
+ *
10
+ * // In a resolver handler:
11
+ * if (active) throw WashInProgress;
12
+ *
13
+ * Each call site reuses the SAME instance (immutable). Transports detect
14
+ * `instanceof NwireError`, read `.code` + `.status` + `.summary`, render
15
+ * the right shape per medium:
16
+ * - REST → JSON body `{ code, message }` with the declared status
17
+ * - GraphQL → error with `extensions: { code }`
18
+ * - CLI → stderr message + exit status
19
+ */
20
+ export interface ErrorMeta {
21
+ readonly code: string;
22
+ readonly status: number;
23
+ readonly summary: string;
24
+ readonly description?: string;
25
+ readonly tags?: readonly string[];
26
+ }
27
+ export interface ErrorDefinition extends ErrorMeta {
28
+ readonly $kind: "error";
29
+ }
30
+ /**
31
+ * Concrete Error subclass — thrown by domain code, caught by transport.
32
+ * The `defineError(...)` result is an instance of this class.
33
+ */
34
+ export declare class NwireError extends Error implements ErrorDefinition {
35
+ readonly $kind: "error";
36
+ readonly code: string;
37
+ readonly status: number;
38
+ readonly summary: string;
39
+ readonly description?: string;
40
+ readonly tags?: readonly string[];
41
+ constructor(meta: ErrorMeta);
42
+ /**
43
+ * Build a fresh error instance with the same metadata but additional
44
+ * runtime context — e.g., the resource id that triggered it.
45
+ */
46
+ with(context: Record<string, unknown>): NwireError & {
47
+ readonly context: Record<string, unknown>;
48
+ };
49
+ }
50
+ export declare function defineError(meta: ErrorMeta): NwireError;
51
+ /** Type narrow. */
52
+ export declare function isNwireError(x: unknown): x is NwireError;
53
+ export declare const Unauthorized: NwireError;
54
+ export declare const Forbidden: NwireError;
55
+ export declare const NotFound: NwireError;
56
+ export declare const Gone: NwireError;
57
+ export declare const BadRequest: NwireError;
58
+ export declare const Conflict: NwireError;
59
+ //# sourceMappingURL=define-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-error.d.ts","sourceRoot":"","sources":["../src/define-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CAKzB;AAED;;;GAGG;AACH,qBAAa,UAAW,SAAQ,KAAM,YAAW,eAAe;IAC9D,QAAQ,CAAC,KAAK,EAAG,OAAO,CAAU;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;gBAEtB,IAAI,EAAE,SAAS;IAU3B;;;OAGG;IACH,IAAI,CACF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,UAAU,GAAG;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE;CAK9D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,UAAU,CAEvD;AAED,mBAAmB;AACnB,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,UAAU,CAExD;AAGD,eAAO,MAAM,YAAY,YAIvB,CAAC;AAEH,eAAO,MAAM,SAAS,YAIpB,CAAC;AAEH,eAAO,MAAM,QAAQ,YAInB,CAAC;AAEH,eAAO,MAAM,IAAI,YAIf,CAAC;AAEH,eAAO,MAAM,UAAU,YAIrB,CAAC;AAEH,eAAO,MAAM,QAAQ,YAInB,CAAC"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * `defineError` — a named, typed, throwable error value.
3
+ *
4
+ * const WashInProgress = defineError({
5
+ * code: "WASH_IN_PROGRESS",
6
+ * status: 409,
7
+ * summary: "Station already has an unfinished wash",
8
+ * });
9
+ *
10
+ * // In a resolver handler:
11
+ * if (active) throw WashInProgress;
12
+ *
13
+ * Each call site reuses the SAME instance (immutable). Transports detect
14
+ * `instanceof NwireError`, read `.code` + `.status` + `.summary`, render
15
+ * the right shape per medium:
16
+ * - REST → JSON body `{ code, message }` with the declared status
17
+ * - GraphQL → error with `extensions: { code }`
18
+ * - CLI → stderr message + exit status
19
+ */
20
+ /**
21
+ * Concrete Error subclass — thrown by domain code, caught by transport.
22
+ * The `defineError(...)` result is an instance of this class.
23
+ */
24
+ export class NwireError extends Error {
25
+ $kind = "error";
26
+ code;
27
+ status;
28
+ summary;
29
+ description;
30
+ tags;
31
+ constructor(meta) {
32
+ super(meta.summary);
33
+ this.name = meta.code;
34
+ this.code = meta.code;
35
+ this.status = meta.status;
36
+ this.summary = meta.summary;
37
+ this.description = meta.description;
38
+ this.tags = meta.tags;
39
+ }
40
+ /**
41
+ * Build a fresh error instance with the same metadata but additional
42
+ * runtime context — e.g., the resource id that triggered it.
43
+ */
44
+ with(context) {
45
+ const next = new NwireError(this);
46
+ Object.assign(next, { context });
47
+ return next;
48
+ }
49
+ }
50
+ export function defineError(meta) {
51
+ return new NwireError(meta);
52
+ }
53
+ /** Type narrow. */
54
+ export function isNwireError(x) {
55
+ return x instanceof NwireError;
56
+ }
57
+ // Built-in errors every transport should know.
58
+ export const Unauthorized = defineError({
59
+ code: "UNAUTHORIZED",
60
+ status: 401,
61
+ summary: "Authentication required.",
62
+ });
63
+ export const Forbidden = defineError({
64
+ code: "FORBIDDEN",
65
+ status: 403,
66
+ summary: "Caller is not authorized to perform this action.",
67
+ });
68
+ export const NotFound = defineError({
69
+ code: "NOT_FOUND",
70
+ status: 404,
71
+ summary: "Requested resource not found.",
72
+ });
73
+ export const Gone = defineError({
74
+ code: "GONE",
75
+ status: 410,
76
+ summary: "Resource is permanently gone (sunset endpoint).",
77
+ });
78
+ export const BadRequest = defineError({
79
+ code: "BAD_REQUEST",
80
+ status: 400,
81
+ summary: "Request shape is invalid (separate from zod-driven 400s on schema mismatch).",
82
+ });
83
+ export const Conflict = defineError({
84
+ code: "CONFLICT",
85
+ status: 409,
86
+ summary: "Request conflicts with the current state of the resource.",
87
+ });
88
+ //# sourceMappingURL=define-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-error.js","sourceRoot":"","sources":["../src/define-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAkBH;;;GAGG;AACH,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,KAAK,GAAG,OAAgB,CAAC;IACzB,IAAI,CAAS;IACb,MAAM,CAAS;IACf,OAAO,CAAS;IAChB,WAAW,CAAU;IACrB,IAAI,CAAqB;IAElC,YAAY,IAAe;QACzB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACxB,CAAC;IAED;;;OAGG;IACH,IAAI,CACF,OAAgC;QAEhC,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACjC,OAAO,IAAkE,CAAC;IAC5E,CAAC;CACF;AAED,MAAM,UAAU,WAAW,CAAC,IAAe;IACzC,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED,mBAAmB;AACnB,MAAM,UAAU,YAAY,CAAC,CAAU;IACrC,OAAO,CAAC,YAAY,UAAU,CAAC;AACjC,CAAC;AAED,+CAA+C;AAC/C,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC;IACtC,IAAI,EAAE,cAAc;IACpB,MAAM,EAAE,GAAG;IACX,OAAO,EAAE,0BAA0B;CACpC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,WAAW,CAAC;IACnC,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,GAAG;IACX,OAAO,EAAE,kDAAkD;CAC5D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,WAAW,CAAC;IAClC,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,GAAG;IACX,OAAO,EAAE,+BAA+B;CACzC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,IAAI,GAAG,WAAW,CAAC;IAC9B,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,GAAG;IACX,OAAO,EAAE,iDAAiD;CAC3D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,WAAW,CAAC;IACpC,IAAI,EAAE,aAAa;IACnB,MAAM,EAAE,GAAG;IACX,OAAO,EAAE,8EAA8E;CACxF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,WAAW,CAAC;IAClC,IAAI,EAAE,UAAU;IAChB,MAAM,EAAE,GAAG;IACX,OAAO,EAAE,2DAA2D;CACrE,CAAC,CAAC"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * `defineHandler(name, config)` — the operation primitive.
3
+ *
4
+ * const GetStation = defineHandler("GetStation", {
5
+ * input: z.object({ stationId: z.string() }),
6
+ * returns: Station,
7
+ * handler: async ({ input, db }) => db.stations.findById(input.stationId),
8
+ * });
9
+ *
10
+ * The shape is universal — same primitive whether the operation is exposed
11
+ * via HTTP, queue, MCP, CLI, or invoked directly via `execute(handler, input)`.
12
+ * Every transport binds via its own `(binding, handler, options)` signature;
13
+ * the binding narrows the input contract at the boundary, the handler is
14
+ * the lowest-common-denominator inside.
15
+ *
16
+ * See: architecture-sketch.html §08.
17
+ *
18
+ * Field placement follows the freq table:
19
+ * first-class — input, handler, returns, errors, summary, policy, emits
20
+ * meta — tags, description, version, deprecated, successor
21
+ * settings — retry, timeout, cache, idempotency
22
+ *
23
+ * `meta` + `settings` are open bags; adapters extend them via TS declaration
24
+ * merging without touching the core type.
25
+ *
26
+ * NOTE: forge has its own `defineHandler(action, fn)` that binds a handler
27
+ * to an existing `ActionDefinition`. That signature stays inside `@nwire/forge`
28
+ * because it depends on the action machinery. The standalone version lives
29
+ * here because every transport needs it without the forge surface.
30
+ */
31
+ import type { z } from "zod";
32
+ import type { ZodTypeAny } from "@nwire/messages";
33
+ import type { Container } from "@nwire/container";
34
+ import { type Logger } from "@nwire/logger";
35
+ import type { ErrorDefinition } from "./define-error.js";
36
+ import type { ResponseSpec, ListResponseSpec } from "./response.js";
37
+ import type { ResourceDefinition } from "./define-resource.js";
38
+ /** Bags extensible via TS declaration merging — adapters add fields here. */
39
+ export interface HandlerMeta {
40
+ readonly tags?: readonly string[];
41
+ readonly description?: string;
42
+ readonly version?: number;
43
+ readonly deprecated?: boolean;
44
+ readonly successor?: string;
45
+ }
46
+ export interface HandlerSettings {
47
+ readonly retry?: {
48
+ attempts: number;
49
+ backoff?: "linear" | "exponential";
50
+ };
51
+ readonly timeout?: number;
52
+ readonly cache?: {
53
+ ttl: number;
54
+ };
55
+ readonly idempotency?: (input: unknown) => string;
56
+ }
57
+ /**
58
+ * Context delivered to every handler. The shape is intentionally minimal —
59
+ * adapters supply richer context via the container (resolve any registered
60
+ * dep by name + destructure into the handler signature).
61
+ */
62
+ export interface HandlerContext<TInput = unknown> {
63
+ /** Parsed + validated input (drawn from `config.input` schema). */
64
+ readonly input: TInput;
65
+ /** Look up a dependency by name. Most handlers destructure instead. */
66
+ resolve<T = unknown>(name: string): T;
67
+ /** Per-execution container scope. */
68
+ readonly container: Container;
69
+ /** Logger scoped to this execution (correlation/causation already attached). */
70
+ readonly logger: Logger;
71
+ /** Free-form bag for transport-specific extras (raw request, MCP progress, …). */
72
+ readonly transport?: Record<string, unknown>;
73
+ }
74
+ /**
75
+ * `returns` may be a single resource, a single response spec, or an array
76
+ * of response specs (e.g. `[created(Station), accepted(StationHandle)]`).
77
+ */
78
+ export type HandlerReturnsSpec = ResourceDefinition | ResponseSpec | ListResponseSpec<ResourceDefinition> | ReadonlyArray<ResponseSpec | ListResponseSpec<ResourceDefinition>>;
79
+ /**
80
+ * Policy: a tag (`"admin"`), a list of tags (`["admin", "operator"]`), or
81
+ * a tuple of `[action, subject]` for RBAC-style policies. Adapters
82
+ * interpret the value per their authorization model.
83
+ */
84
+ export type HandlerPolicy = string | readonly string[] | readonly [string, string];
85
+ export interface HandlerConfig<TInputSchema extends ZodTypeAny | undefined = ZodTypeAny | undefined, TOutput = unknown> {
86
+ /** Input schema. Optional for zero-arg handlers (health checks, listings without filters). */
87
+ readonly input?: TInputSchema;
88
+ /** The implementation. Receives the typed input + context. */
89
+ readonly handler: (ctx: HandlerContext<TInputSchema extends ZodTypeAny ? z.output<TInputSchema> : undefined>) => TOutput | Promise<TOutput>;
90
+ /** Documented response shape(s). Drives OpenAPI + runtime body validation. */
91
+ readonly returns?: HandlerReturnsSpec;
92
+ /** Declared error values this handler may throw. */
93
+ readonly errors?: readonly ErrorDefinition[];
94
+ /** Events this handler may emit (action flavour). */
95
+ readonly emits?: readonly unknown[];
96
+ /** One-line intent. Surfaces in OpenAPI/MCP descriptions. */
97
+ readonly summary?: string;
98
+ /** Authorization policy. Adapters (rbac, authz) consume this. */
99
+ readonly policy?: HandlerPolicy;
100
+ /** Rare-field bag — tags, description, version, deprecated, …. */
101
+ readonly meta?: HandlerMeta;
102
+ /** Behavior-tuning bag — retry, timeout, cache, idempotency. */
103
+ readonly settings?: HandlerSettings;
104
+ }
105
+ export interface HandlerDefinition<TInputSchema extends ZodTypeAny | undefined = ZodTypeAny | undefined, TOutput = unknown> {
106
+ readonly $kind: "handler";
107
+ readonly name: string;
108
+ readonly config: HandlerConfig<TInputSchema, TOutput>;
109
+ /**
110
+ * Convenience accessor — equivalent to `config.handler`. Lets transports
111
+ * write `handler.run(ctx)` without reaching into `.config`.
112
+ */
113
+ run(ctx: HandlerContext<TInputSchema extends ZodTypeAny ? z.output<TInputSchema> : undefined>): TOutput | Promise<TOutput>;
114
+ }
115
+ /**
116
+ * Define a handler — the operation primitive.
117
+ *
118
+ * const ListTodos = defineHandler("listTodos", {
119
+ * input: z.object({ status: z.string().optional() }),
120
+ * handler: async ({ input, resolve }) => {
121
+ * const db = resolve<DB>("db");
122
+ * return db.todos.findMany(input);
123
+ * },
124
+ * });
125
+ *
126
+ * // Direct invocation:
127
+ * const todos = await execute(ListTodos, { status: "open" });
128
+ *
129
+ * // HTTP transport:
130
+ * api.wire(get("/todos"), ListTodos);
131
+ *
132
+ * // Queue transport (same handler):
133
+ * workers.wire(job("listTodos"), ListTodos);
134
+ */
135
+ export declare function defineHandler<TInputSchema extends ZodTypeAny | undefined, TOutput>(name: string, config: HandlerConfig<TInputSchema, TOutput>): HandlerDefinition<TInputSchema, TOutput>;
136
+ /** Type narrow. */
137
+ export declare function isHandlerDefinition(x: unknown): x is HandlerDefinition;
138
+ /**
139
+ * Options for `execute()` — transport-agnostic. Adapters can pass a
140
+ * container so the handler can `resolve()` its deps; if omitted, a
141
+ * minimal stub container is supplied that throws on resolve.
142
+ */
143
+ export interface ExecuteOptions {
144
+ readonly container?: Container;
145
+ readonly logger?: Logger;
146
+ readonly transport?: Record<string, unknown>;
147
+ }
148
+ /**
149
+ * Invoke a handler directly with input. The framework validates input
150
+ * against the handler's `input` schema (if declared), constructs the
151
+ * handler context, runs the handler, and returns its result.
152
+ *
153
+ * const todos = await execute(ListTodos, { status: "open" });
154
+ *
155
+ * This is the universal "any host can mount it" entry point. Transports
156
+ * call into `execute()` after parsing the binding's payload; tests call
157
+ * `execute()` directly to bypass transport machinery.
158
+ */
159
+ export declare function execute<TInputSchema extends ZodTypeAny | undefined, TOutput>(handler: HandlerDefinition<TInputSchema, TOutput>, input: TInputSchema extends ZodTypeAny ? z.input<TInputSchema> : any, options?: ExecuteOptions): Promise<TOutput>;
160
+ /**
161
+ * Type alias for a handler-or-callable. Transports `.wire()` accept either
162
+ * a full `HandlerDefinition` (typed, validated) or a bare async function
163
+ * (escape hatch for one-liners + health checks).
164
+ */
165
+ export type HandlerLike<TInput = unknown, TOutput = unknown> = HandlerDefinition<ZodTypeAny | undefined, TOutput> | ((input: TInput) => Promise<TOutput> | TOutput);
166
+ /** Re-exports for the public surface. */
167
+ export type { ResponseInstance } from "./response.js";
168
+ //# sourceMappingURL=define-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-handler.d.ts","sourceRoot":"","sources":["../src/define-handler.ts"],"names":[],"mappings":"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"}