UNPKG

serverstruct

Version:

Type safe and modular servers with H3

237 lines (236 loc) 7.33 kB
import { Box, Constructor } from "getbox"; import * as h30 from "h3"; import { EventHandlerObject, EventHandlerRequest, H3, H3Event, Middleware, serve, serve as serve$1 } from "h3"; //#region src/index.d.ts type Server = ReturnType<typeof serve$1>; type ServeOptions = Parameters<typeof serve$1>[1]; type MaybePromise<T = unknown> = T | Promise<T>; /** * Creates an H3 application. * * @param setup - Function that configures the app. Receives a fresh H3 instance * and Box instance. Can add routes to the provided app, or create * and return a new H3 instance. * @param box - Optional Box instance. If not provided, creates a new one. * @returns H3 instance. * * @example * ```typescript * import { application, serve } from "serverstruct"; * * const app = application((app) => { * app.get("/", () => "Hello world!"); * }); * * serve(app, { port: 3000 }); * ``` * * @example With dependency injection * ```typescript * import { application, serve } from "serverstruct"; * * const app = application((app, box) => { * app.get("/ping", () => "pong"); * app.mount("/users", box.get(usersController)); * }); * * serve(app, { port: 3000 }); * ``` */ declare function application(setup: (app: H3, box: Box) => H3 | void, box?: Box): H3; /** * Creates an H3 app constructor. * * @param setup - Function that configures the app. * @returns A Constructor that produces an H3 app. Not cached by Box. * * @example * ```typescript * import { application, controller } from "serverstruct"; * * class Database { * getUsers() { return ["Alice", "Bob"]; } * } * * // Define a controller * const usersController = controller((app, box) => { * const db = box.get(Database); * app.get("/", () => db.getUsers()); * }); * * // Use it in your app * const app = application((app, box) => { * app.mount("/users", box.get(usersController)); * }); * ``` */ declare function controller(setup: (app: H3, box: Box) => H3 | void): Constructor<H3>; /** * Creates a handler constructor. * * @param setup - Handler function that receives the event and Box instance. * @returns A Constructor that produces an H3 handler. Not cached by Box. * * @example * ```typescript * import { application, handler } from "serverstruct"; * * class UserService { * getUser(id: string) { return { id, name: "Alice" }; } * } * * // Define a handler * const getUserHandler = handler((event, box) => { * const userService = box.get(UserService); * const id = event.context.params?.id; * return userService.getUser(id); * }); * * // Use it in your app * const app = application((app, box) => { * app.get("/users/:id", box.get(getUserHandler)); * }); * ``` */ declare function handler<Res = unknown, Req extends EventHandlerRequest = EventHandlerRequest>(setup: (event: H3Event<Req>, box: Box) => Res): Constructor<h30.EventHandlerWithFetch<Req, Res>>; /** * Creates an event handler constructor from a setup function. * * @param setup - Function that receives Box instance and returns an event handler object. * @returns A Constructor that produces an H3 event handler. Not cached by Box. * * @example * ```typescript * import { application, eventHandler } from "serverstruct"; * * class UserService { * getUser(id: string) { return { id, name: "Alice" }; } * } * * // Define an event handler * const getUserHandler = eventHandler((box) => ({ * handler(event) { * const userService = box.get(UserService); * const id = event.context.params?.id; * return userService.getUser(id); * }, * meta: { auth: true } * })); * * // Use it in your app * const app = application((app, box) => { * app.get("/users/:id", box.get(getUserHandler)); * }); * ``` */ declare function eventHandler<Res = unknown, Req extends EventHandlerRequest = EventHandlerRequest>(setup: (box: Box) => EventHandlerObject<Req, Res>): Constructor<h30.EventHandlerWithFetch<Req, Res>>; /** * Creates a middleware constructor. * * @param setup - Middleware function that receives the event, next function, and Box instance. * @returns A Constructor that produces an H3 middleware. Not cached by Box. * * @example * ```typescript * import { application, middleware } from "serverstruct"; * * class AuthService { * validateToken(token: string) { return token === "valid"; } * } * * // Define a middleware * const authMiddleware = middleware((event, next, box) => { * const authService = box.get(AuthService); * const token = event.headers.get("authorization"); * if (!token || !authService.validateToken(token)) { * throw new Error("Unauthorized"); * } * }); * * // Use it in your app * const app = application((app, box) => { * app.use(box.get(authMiddleware)); * app.get("/", () => "Hello world!"); * }); * ``` */ declare function middleware(setup: (event: H3Event, next: () => MaybePromise<unknown | undefined>, box: Box) => MaybePromise<unknown | undefined>): Constructor<Middleware>; /** * A request-scoped context store for associating values with H3 events. * * Each request gets its own isolated context that is automatically cleaned up * when the request completes. Uses a WeakMap internally to ensure values are * garbage collected with their events. * * @example * ```typescript * import { application, Context } from "serverstruct"; * * const userContext = new Context<User>(); * * const app = application((app) => { * app.use((event) => { * userContext.set(event, { id: "123", name: "Alice" }); * }); * app.get("/user", (event) => { * const user = userContext.get(event); * return user; * }); * }); * ``` */ declare class Context<T> { #private; private options?; /** * @param options.onError - Custom error message thrown by `get()` when no value is set for the event. */ constructor(options?: { onError?: string; } | undefined); /** * Sets a value for the given event. */ set(event: H3Event<any>, value: T): void; /** * Gets the value for the given event. * @throws Error if no value is set for the event. */ get(event: H3Event<any>): T; /** * Gets the value for the given event, or undefined if not set. */ lookup(event: H3Event<any>): T | undefined; } /** * Creates a request-scoped context store for associating values with H3 events. * * Each request gets its own isolated context that is automatically cleaned up * when the request completes. Uses a WeakMap internally to ensure values are * garbage collected with their events. * * @param options.onError - Custom error message thrown by `get()` when no value is set for the event. * @returns A Context instance. * * @example * ```typescript * import { application, context } from "serverstruct"; * * const userContext = context<User>(); * * const app = application((app) => { * app.use((event) => { * userContext.set(event, { id: "123", name: "Alice" }); * }); * app.get("/user", (event) => { * const user = userContext.get(event); * return user; * }); * }); * ``` */ declare function context<T>(options?: { onError?: string; }): Context<T>; //#endregion export { Context, ServeOptions, Server, application, context, controller, eventHandler, handler, middleware, serve };