🧰 Utilities

Minimal API Helpers

Tirne doesn't ship batteries-included utilities — but writing them is trivial. Here are 4 tiny but powerful functions to help you build faster.

json(), redirect(), parseQuery(), parseBody() — that's all you need to simplify responses.

1. json() — JSON Response Helper

export function json(data: unknown, status = 200, headers: HeadersInit = {}) {
  return new Response(JSON.stringify(data), {
    status,
    headers: {
      "Content-Type": "application/json",
      ...headers,
    },
  });
}
handler: () => json({ hello: "world" })

2. redirect() — Simple Redirect Response

export function redirect(location: string, status: 302 | 301 = 302) {
  return new Response(null, {
    status,
    headers: {
      Location: location,
    },
  });
}
handler: () => redirect("/login")

3. parseQuery() — Easy Access to Query Params

export function parseQuery(req: Request): URLSearchParams {
  return new URL(req.url).searchParams;
}
const query = parseQuery(req);
const q = query.get("q");

4. parseBody() — Safe Body Parsing

export async function parseBody(req: Request): Promise<unknown> {
  const contentType = req.headers.get("content-type") || "";
  if (contentType.includes("application/json")) {
    return await req.json();
  }
  if (contentType.includes("application/x-www-form-urlencoded")) {
    const text = await req.text();
    return Object.fromEntries(new URLSearchParams(text));
  }
  return await req.text(); // fallback
}

✨ Example: All Together

import type { Route } from "tirne";
import { Server, json, redirect, parseQuery, parseBody } from "tirne";

const routes: Route[] = [
  {
    method: "GET",
    path: "/",
    handler: (req) => {
      const name = parseQuery(req).get("name") || "stranger";
      return json({ message: `Hello, ${name}!` });
    },
  },
  {
    method: "POST",
    path: "/echo",
    handler: async (req) => {
      const body = await parseBody(req);
      return json({ received: body });
    },
  },
  {
    method: "GET",
    path: "/go",
    handler: () => redirect("/"),
  },
];

const server = new Server(routes);

export default {
  fetch: (req: Request) => server.fetch(req),
};

✅ Functionality Check (Examples)

Try the following curl commands to verify the behavior of each route.

1. Access/

curl http://localhost:3000/
{ "message": "Hello, stranger!" }

2. POST to/echo

curl -X POST http://localhost:3000/echo -H "Content-Type: application/json" -d '{"msg":"hi"}'
{ "received": { "msg": "hi" } }

3. Access/go

curl -i http://localhost:3000/go
HTTP/1.1 302 Found
Location: /