@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.
@@ -0,0 +1,69 @@
1
+ /**
2
+ * `response(status, Resource)` — typed response builder.
3
+ *
4
+ * const washCreated = response(201, Wash);
5
+ * const washAccepted = response(202);
6
+ * const washList = response.list(200, Wash);
7
+ *
8
+ * // In a resolver handler:
9
+ * return washCreated(wash);
10
+ * return washAccepted();
11
+ * return washList([wash1, wash2]);
12
+ *
13
+ * Each response spec is BOTH metadata (status + body resource — used by
14
+ * OpenAPI/GraphQL schema generation + response validation) AND a builder
15
+ * (callable to produce a typed response instance). When the spec carries
16
+ * a `ResourceDefinition` with declared `public` fields, the body is run
17
+ * through `resource.project(...)` so non-public fields never leak — the
18
+ * builder owns the shaping, handlers don't hand-map.
19
+ */
20
+ function singleSpec(status, resource) {
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
+ const builder = (data) => {
23
+ const body = resource && data !== undefined ? resource.project(data) : data;
24
+ return { $kind: "response-instance", status, body };
25
+ };
26
+ Object.assign(builder, {
27
+ $kind: "response",
28
+ status,
29
+ kind: resource ? "single" : "empty",
30
+ resource,
31
+ });
32
+ return builder;
33
+ }
34
+ function listSpec(status, resource) {
35
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
+ const builder = (items) => {
37
+ const stripped = items.map((it) => resource.project(it));
38
+ return { $kind: "response-instance", status, body: stripped };
39
+ };
40
+ Object.assign(builder, {
41
+ $kind: "response",
42
+ status,
43
+ kind: "list",
44
+ resource,
45
+ });
46
+ return builder;
47
+ }
48
+ /**
49
+ * `response(status, Resource?)` — single-body response spec (or empty body).
50
+ * Has `.list(status, Resource)` for array responses.
51
+ */
52
+ export const response = Object.assign(singleSpec, { list: listSpec });
53
+ // ─── Semantic response factories ───────────────────────────────────
54
+ // The app's vocabulary for outcomes. Handlers never type a raw status
55
+ // code; they `return created(Station, state)` / `return accepted()` /
56
+ // `return ok.list(Station, items)`. Transports translate the semantic
57
+ // into wire-shape (HTTP status, GraphQL union resolution, CLI exit).
58
+ export const ok = Object.assign((resource) => response(200, resource), {
59
+ list: (resource) => response.list(200, resource),
60
+ });
61
+ export const created = (resource) => response(201, resource);
62
+ export const accepted = (resource) => response(202, resource);
63
+ export const noContent = () => response(204);
64
+ export const notModified = () => response(304);
65
+ export const gone = () => response(410);
66
+ /** Type narrows. */
67
+ export const isResponseSpec = (x) => typeof x === "object" && x !== null && x.$kind === "response";
68
+ export const isResponseInstance = (x) => typeof x === "object" && x !== null && x.$kind === "response-instance";
69
+ //# sourceMappingURL=response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.js","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@nwire/handler",
3
+ "version": "0.7.0",
4
+ "description": "Nwire — the operation primitive. defineHandler / defineError / defineResource / defineMiddleware / pipe / response factories / typed framework errors. Standalone — depend on this without pulling forge. Every transport (HTTP, queue, MCP, …) speaks the same handler shape.",
5
+ "keywords": [
6
+ "execute",
7
+ "handler",
8
+ "nwire",
9
+ "operation"
10
+ ],
11
+ "files": [
12
+ "dist",
13
+ "README.md"
14
+ ],
15
+ "type": "module",
16
+ "main": "./dist/handler-index.js",
17
+ "types": "./dist/handler-index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "import": "./dist/handler-index.js",
21
+ "types": "./dist/handler-index.d.ts"
22
+ }
23
+ },
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "dependencies": {
28
+ "zod": "^4.0.0",
29
+ "@nwire/container": "0.7.0",
30
+ "@nwire/envelope": "0.7.0",
31
+ "@nwire/logger": "0.7.0",
32
+ "@nwire/messages": "0.7.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^22.19.9",
36
+ "typescript": "^5.9.3",
37
+ "vitest": "^4.0.18"
38
+ },
39
+ "scripts": {
40
+ "build": "tsc && node ../../scripts/fix-dist-extensions.mjs dist",
41
+ "dev": "tsc --watch",
42
+ "typecheck": "tsc --noEmit"
43
+ }
44
+ }