UNPKG

@withstudiocms/effect

Version:

Effect-TS Utilities for Astro

118 lines (117 loc) 5.56 kB
import type { APIContext, APIRoute } from 'astro'; import type { EffectAPIRouteHandler, EffectRouteOptions, ExtractDefinedRoutes, RouteHandlerConfig, RouteHandlers } from './types.js'; /** * Defines an API route handler for Astro using an effect-based approach. * * @param context - The API context provided by Astro for the current request. * @returns A function that takes an `EffectAPIRouteHandler`, executes it with the provided context, * and returns a `Promise<Response>` representing the HTTP response. * * @example * ```typescript * export const GET = defineAPIRoute(context)(async (ctx) => { * // Your effectful logic here * return new Response("Hello, world!"); * }); * ``` * * @deprecated Use `createEffectRoute` instead for better clarity and consistency. */ export declare const defineAPIRoute: (context: APIContext) => (fn: EffectAPIRouteHandler) => Promise<Response>; /** * Creates an Astro API route handler that executes the provided effectful handler function. * * @param fn - The effectful API route handler function to be executed. It should accept an `APIContext` and return an effect. * @returns An Astro `APIRoute` handler that runs the effect and returns a `Response`. */ export declare const createEffectAPIRoute: (fn: EffectAPIRouteHandler) => APIRoute; /** * Wraps an API route handler with effectful middleware, including CORS, validation, timeout, and custom hooks. * * @param fn - The main effectful API route handler function to execute. * @param options - Optional configuration for the route, including CORS, validation, timeout, and middleware hooks. * @returns An `APIRoute` function compatible with Astro's API routes. * * @remarks * This utility provides a standardized way to handle API routes with common concerns such as: * - Applying CORS headers and handling preflight requests. * - Running pre-effect middleware (`onBeforeEffect`). * - Validating incoming requests (`validate`). * - Enforcing a timeout for the effect execution. * - Running post-success (`onSuccess`) and error (`onError`) middleware. * - Ensuring CORS headers are present on all responses, including errors. * * @example * ```typescript * export const POST = withEffect(async (context) => { * // Your effect logic here * }, { * cors: { origin: '*' }, * validate: { body: z.object({ name: z.string() }) }, * timeout: 5000, * onSuccess: async (response, context) => response, * onError: async (error, context) => new Response('Error', { status: 500 }), * }); * ``` */ export declare const withEffectAPI: (fn: EffectAPIRouteHandler, options?: EffectRouteOptions) => APIRoute; /** * Creates API route handlers with effect support for each HTTP method provided. * * This function takes a set of route handlers and an optional configuration object, * then returns an object mapping HTTP methods to their corresponding API route handlers, * each wrapped with effect middleware and merged configuration. * * The return type is precisely typed to only include the methods that were provided * in the handlers parameter, eliminating undefined from the union types. * * @param handlers - An object containing route handlers keyed by HTTP method (e.g., 'GET', 'POST'). * @param config - Optional global configuration for all handlers. Can include method-specific overrides via the `methods` property. * @returns An object mapping each provided HTTP method to its configured API route handler. */ export declare const createEffectAPIRoutes: <T extends RouteHandlers>(handlers: T, config?: RouteHandlerConfig) => ExtractDefinedRoutes<T>; /** * A builder class for defining API route handlers with optional per-method and global configuration. * * Provides a fluent interface for registering HTTP method handlers (`get`, `post`, `put`, `delete`, `patch`, `all`) * and setting global or per-method options. Use `build()` to generate the final route configuration. * * Each method returns a new builder type that accumulates the added methods, ensuring precise typing * in the final built routes object. * * @example * ```typescript * const routes = new EffectRouteBuilder() * .withGlobalConfig({ cors: { origin: true } }) * .get(getHandler, { timeout: 3000 }) * .post(postHandler) * .build(); * // routes has type: { GET: APIRoute, POST: APIRoute } (no undefined!) * ``` */ export declare class EffectAPIRouteBuilder<T extends Partial<RouteHandlers> = {}> { private handlers; private config; constructor(handlers?: T); withGlobalConfig(config: EffectRouteOptions): EffectAPIRouteBuilder<T>; private addHandler; get<U extends EffectAPIRouteHandler>(handler: U, options?: Partial<EffectRouteOptions>): EffectAPIRouteBuilder<T & { GET: U; }>; post<U extends EffectAPIRouteHandler>(handler: U, options?: Partial<EffectRouteOptions>): EffectAPIRouteBuilder<T & { POST: U; }>; put<U extends EffectAPIRouteHandler>(handler: U, options?: Partial<EffectRouteOptions>): EffectAPIRouteBuilder<T & { PUT: U; }>; delete<U extends EffectAPIRouteHandler>(handler: U, options?: Partial<EffectRouteOptions>): EffectAPIRouteBuilder<T & { DELETE: U; }>; patch<U extends EffectAPIRouteHandler>(handler: U, options?: Partial<EffectRouteOptions>): EffectAPIRouteBuilder<T & { PATCH: U; }>; all<U extends EffectAPIRouteHandler>(handler: U, options?: Partial<EffectRouteOptions>): EffectAPIRouteBuilder<T & { ALL: U; }>; build(): ExtractDefinedRoutes<T>; }