ProvenPin Install

Elysia API with TypeBox validation and guards, tested via app.handle on Node: working versions (tested 2026-10-15)

An Elysia 1.4 app with TypeBox schemas for params, query, body and responses, a guard with an API key check and custom error mapping, tested on Node with web-standard Request objects through app.handle and no open port.

passed5 passed · 0 failed2026-10-15 14:57 UTC
Status
passed
Last passed
2026-10-15 14:57 UTC
Tests
5 / 5
Language
TypeScript
Runtime
node v22.23.3
pinned versions7
elysia@1.4.30@sinclair/typebox@0.34.52exact-mirror@1.2.6file-type@22.2.0openapi-types@12.1.3tsx@4.23.15@types/node@26.6.5
run it
npm install --no-audit --no-fund --ignore-scripts=false
npm test
test environment
node v22.23.3
linux 6.17.0-1022-azure
x64
runner: github-actions 38755782594

The code

Exactly the files that passed. Your agent can pull them with get_recipe("elysia-typebox-handle-tests") (install), or see them on GitHub.

package.json
{
  "name": "elysia-typebox-handle-tests",
  "private": true,
  "type": "module",
  "scripts": {
    "test": "node --import tsx --test test/*.test.ts"
  },
  "dependencies": {
    "elysia": "1.4.30",
    "@sinclair/typebox": "0.34.52",
    "exact-mirror": "1.2.6",
    "file-type": "22.2.0",
    "openapi-types": "12.1.3"
  },
  "devDependencies": {
    "tsx": "4.23.15",
    "@types/node": "26.6.5"
  }
}
src/app.ts
import { Elysia, t } from "elysia";

type Note = { id: number; title: string; body: string; tags: string[] };

export class NoteNotFound extends Error {
  status = 404;
}

/**
 * An Elysia app with TypeBox schemas on params, query, body and response. Tests call
 * app.handle(new Request(...)) with web-standard Request objects, so no port is opened
 * and the same code runs on Bun or Node.
 */
export function createApp(apiKey = "test-key") {
  const notes = new Map<number, Note>();
  let nextId = 1;

  const NoteSchema = t.Object({ id: t.Number(), title: t.String(), body: t.String(), tags: t.Array(t.String()) });

  return new Elysia()
    .error({ NOTE_NOT_FOUND: NoteNotFound }) // registered errors get their own onError code
    .onError(({ code, error, set }) => {
      if (code === "VALIDATION") { set.status = 422; return { error: "validation", detail: error.all.map((e) => ("path" in e ? e.path : "")) }; }
      if (code === "NOTE_NOT_FOUND") { set.status = 404; return { error: "note not found" }; }
    })
    .get("/health", () => ({ ok: true }))
    .guard({
      // Runs before every route in this group: a simple API key check.
      beforeHandle: ({ headers, set }) => {
        if (headers["x-api-key"] !== apiKey) { set.status = 401; return { error: "unauthorized" }; }
      },
    }, (app) => app
      .post("/notes", ({ body, set }) => {
        const note = { id: nextId++, ...body, tags: body.tags ?? [] };
        notes.set(note.id, note);
        set.status = 201;
        return note;
      }, {
        body: t.Object({ title: t.String({ minLength: 1, maxLength: 120 }), body: t.String(), tags: t.Optional(t.Array(t.String({ pattern: "^[a-z-]+$" }), { maxItems: 5 })) }),
        response: { 201: NoteSchema },
      })
      .get("/notes", ({ query }) => {
        const list = [...notes.values()].filter((n) => !query.tag || n.tags.includes(query.tag));
        return list.slice(0, query.limit);
      }, { query: t.Object({ tag: t.Optional(t.String()), limit: t.Number({ default: 10, minimum: 1, maximum: 50 }) }) })
      .get("/notes/:id", ({ params }) => {
        const n = notes.get(params.id);
        if (!n) throw new NoteNotFound(`note ${params.id}`);
        return n;
      }, { params: t.Object({ id: t.Numeric() }) }),
    );
}
test/app.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { createApp } from "../src/app.ts";

const KEY = { "x-api-key": "test-key", "content-type": "application/json" };
const req = (path: string, init: RequestInit = {}) => new Request(`http://localhost${path}`, init);

test("public route works without a key", async () => {
  const res = await createApp().handle(req("/health"));
  assert.equal(res.status, 200);
  assert.deepEqual(await res.json(), { ok: true });
});

test("guarded routes reject a missing API key", async () => {
  const res = await createApp().handle(req("/notes"));
  assert.equal(res.status, 401);
  assert.deepEqual(await res.json(), { error: "unauthorized" });
});

test("creates a note and coerces path and query params", async () => {
  const app = createApp();
  const created = await app.handle(req("/notes", { method: "POST", headers: KEY, body: JSON.stringify({ title: "Ship", body: "today", tags: ["work"] }) }));
  assert.equal(created.status, 201);
  assert.deepEqual(await created.json(), { id: 1, title: "Ship", body: "today", tags: ["work"] });
  await app.handle(req("/notes", { method: "POST", headers: KEY, body: JSON.stringify({ title: "Rest", body: "later" }) }));
  const one = await app.handle(req("/notes/1", { headers: KEY }));
  assert.equal((await one.json()).title, "Ship");
  const tagged = await (await app.handle(req("/notes?tag=work&limit=5", { headers: KEY }))).json();
  assert.deepEqual(tagged.map((n: { id: number }) => n.id), [1]);
  const limited = await (await app.handle(req("/notes?limit=1", { headers: KEY }))).json();
  assert.equal(limited.length, 1);
});

test("TypeBox validation failures map to 422 with paths", async () => {
  const app = createApp();
  const bad = await app.handle(req("/notes", { method: "POST", headers: KEY, body: JSON.stringify({ title: "", body: 3, tags: ["Bad Tag"] }) }));
  assert.equal(bad.status, 422);
  const { error, detail } = await bad.json();
  assert.equal(error, "validation");
  for (const p of ["/title", "/body", "/tags/0"]) assert.ok(detail.includes(p), `missing ${p} in ${detail}`);
  const badQuery = await app.handle(req("/notes?limit=500", { headers: KEY }));
  assert.equal(badQuery.status, 422);
  const badParam = await app.handle(req("/notes/abc", { headers: KEY }));
  assert.equal(badParam.status, 422);
});

test("unknown note ids return 404", async () => {
  const res = await createApp().handle(req("/notes/99", { headers: KEY }));
  assert.equal(res.status, 404);
  assert.deepEqual(await res.json(), { error: "note not found" });
});

Connect to ProvenPin

Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.

terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp

Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.