hono
Version:
Web framework built on Web Standards
453 lines (452 loc) • 16.3 kB
TypeScript
import { HonoRequest } from './request';
import type { Result } from './router';
import type { Env, FetchEventLike, H, Input, NotFoundHandler, RouterRoute, TypedResponse } from './types';
import type { RedirectStatusCode, StatusCode } from './utils/http-status';
import type { BaseMime } from './utils/mime';
import type { InvalidJSONValue, IsAny, JSONParsed, JSONValue, SimplifyDeepArray } from './utils/types';
type HeaderRecord = Record<"Content-Type", BaseMime> | Record<ResponseHeader, string | string[]> | Record<string, string | string[]>;
/**
* Data type can be a string, ArrayBuffer, or ReadableStream.
*/
export type Data = string | ArrayBuffer | ReadableStream;
/**
* Interface for the execution context in a web worker or similar environment.
*/
export interface ExecutionContext {
/**
* Extends the lifetime of the event callback until the promise is settled.
*
* @param promise - A promise to wait for.
*/
waitUntil(promise: Promise<unknown>): void;
/**
* Allows the event to be passed through to subsequent event listeners.
*/
passThroughOnException(): void;
}
/**
* Interface for context variable mapping.
*/
export interface ContextVariableMap {
}
/**
* Interface for context renderer.
*/
export interface ContextRenderer {
}
/**
* Interface representing a renderer for content.
*
* @interface DefaultRenderer
* @param {string | Promise<string>} content - The content to be rendered, which can be either a string or a Promise resolving to a string.
* @returns {Response | Promise<Response>} - The response after rendering the content, which can be either a Response or a Promise resolving to a Response.
*/
interface DefaultRenderer {
(content: string | Promise<string>): Response | Promise<Response>;
}
/**
* Renderer type which can either be a ContextRenderer or DefaultRenderer.
*/
export type Renderer = ContextRenderer extends Function ? ContextRenderer : DefaultRenderer;
/**
* Extracts the props for the renderer.
*/
export type PropsForRenderer = [
...Required<Parameters<Renderer>>
] extends [
unknown,
infer Props
] ? Props : unknown;
export type Layout<T = Record<string, any>> = (props: T) => any;
/**
* Interface for getting context variables.
*
* @template E - Environment type.
*/
interface Get<E extends Env> {
<Key extends keyof E["Variables"]>(key: Key): E["Variables"][Key];
<Key extends keyof ContextVariableMap>(key: Key): ContextVariableMap[Key];
}
/**
* Interface for setting context variables.
*
* @template E - Environment type.
*/
interface Set<E extends Env> {
<Key extends keyof E["Variables"]>(key: Key, value: E["Variables"][Key]): void;
<Key extends keyof ContextVariableMap>(key: Key, value: ContextVariableMap[Key]): void;
}
/**
* Interface for creating a new response.
*/
interface NewResponse {
(data: Data | null, status?: StatusCode, headers?: HeaderRecord): Response;
(data: Data | null, init?: ResponseInit): Response;
}
/**
* Interface for responding with a body.
*/
interface BodyRespond extends NewResponse {
}
/**
* Interface for responding with text.
*
* @interface TextRespond
* @template T - The type of the text content.
* @template U - The type of the status code.
*
* @param {T} text - The text content to be included in the response.
* @param {U} [status] - An optional status code for the response.
* @param {HeaderRecord} [headers] - An optional record of headers to include in the response.
*
* @returns {Response & TypedResponse<T, U, 'text'>} - The response after rendering the text content, typed with the provided text and status code types.
*/
interface TextRespond {
<T extends string, U extends StatusCode = StatusCode>(text: T, status?: U, headers?: HeaderRecord): Response & TypedResponse<T, U, "text">;
<T extends string, U extends StatusCode = StatusCode>(text: T, init?: ResponseInit): Response & TypedResponse<T, U, "text">;
}
/**
* Interface for responding with JSON.
*
* @interface JSONRespond
* @template T - The type of the JSON value or simplified unknown type.
* @template U - The type of the status code.
*
* @param {T} object - The JSON object to be included in the response.
* @param {U} [status] - An optional status code for the response.
* @param {HeaderRecord} [headers] - An optional record of headers to include in the response.
*
* @returns {JSONRespondReturn<T, U>} - The response after rendering the JSON object, typed with the provided object and status code types.
*/
interface JSONRespond {
<T extends JSONValue | SimplifyDeepArray<unknown> | InvalidJSONValue, U extends StatusCode = StatusCode>(object: T, status?: U, headers?: HeaderRecord): JSONRespondReturn<T, U>;
<T extends JSONValue | SimplifyDeepArray<unknown> | InvalidJSONValue, U extends StatusCode = StatusCode>(object: T, init?: ResponseInit): JSONRespondReturn<T, U>;
}
/**
* @template T - The type of the JSON value or simplified unknown type.
* @template U - The type of the status code.
*
* @returns {Response & TypedResponse<SimplifyDeepArray<T> extends JSONValue ? (JSONValue extends SimplifyDeepArray<T> ? never : JSONParsed<T>) : never, U, 'json'>} - The response after rendering the JSON object, typed with the provided object and status code types.
*/
type JSONRespondReturn<T extends JSONValue | SimplifyDeepArray<unknown> | InvalidJSONValue, U extends StatusCode> = Response & TypedResponse<SimplifyDeepArray<T> extends JSONValue ? JSONValue extends SimplifyDeepArray<T> ? never : JSONParsed<T> : never, U, "json">;
/**
* Interface representing a function that responds with HTML content.
*
* @param html - The HTML content to respond with, which can be a string or a Promise that resolves to a string.
* @param status - (Optional) The HTTP status code for the response.
* @param headers - (Optional) A record of headers to include in the response.
* @param init - (Optional) The response initialization object.
*
* @returns A Response object or a Promise that resolves to a Response object.
*/
interface HTMLRespond {
<T extends string | Promise<string>>(html: T, status?: StatusCode, headers?: HeaderRecord): T extends string ? Response : Promise<Response>;
<T extends string | Promise<string>>(html: T, init?: ResponseInit): T extends string ? Response : Promise<Response>;
}
/**
* Options for configuring the context.
*
* @template E - Environment type.
*/
type ContextOptions<E extends Env> = {
/**
* Bindings for the environment.
*/
env: E["Bindings"];
/**
* Execution context for the request.
*/
executionCtx?: FetchEventLike | ExecutionContext | undefined;
/**
* Handler for not found responses.
*/
notFoundHandler?: NotFoundHandler<E>;
matchResult?: Result<[
H,
RouterRoute
]>;
path?: string;
};
interface SetHeadersOptions {
append?: boolean;
}
type ResponseHeader = "Access-Control-Allow-Credentials" | "Access-Control-Allow-Headers" | "Access-Control-Allow-Methods" | "Access-Control-Allow-Origin" | "Access-Control-Expose-Headers" | "Access-Control-Max-Age" | "Age" | "Allow" | "Cache-Control" | "Clear-Site-Data" | "Content-Disposition" | "Content-Encoding" | "Content-Language" | "Content-Length" | "Content-Location" | "Content-Range" | "Content-Security-Policy" | "Content-Security-Policy-Report-Only" | "Content-Type" | "Cookie" | "Cross-Origin-Embedder-Policy" | "Cross-Origin-Opener-Policy" | "Cross-Origin-Resource-Policy" | "Date" | "ETag" | "Expires" | "Last-Modified" | "Location" | "Permissions-Policy" | "Pragma" | "Retry-After" | "Save-Data" | "Sec-CH-Prefers-Color-Scheme" | "Sec-CH-Prefers-Reduced-Motion" | "Sec-CH-UA" | "Sec-CH-UA-Arch" | "Sec-CH-UA-Bitness" | "Sec-CH-UA-Form-Factor" | "Sec-CH-UA-Full-Version" | "Sec-CH-UA-Full-Version-List" | "Sec-CH-UA-Mobile" | "Sec-CH-UA-Model" | "Sec-CH-UA-Platform" | "Sec-CH-UA-Platform-Version" | "Sec-CH-UA-WoW64" | "Sec-Fetch-Dest" | "Sec-Fetch-Mode" | "Sec-Fetch-Site" | "Sec-Fetch-User" | "Sec-GPC" | "Server" | "Server-Timing" | "Service-Worker-Navigation-Preload" | "Set-Cookie" | "Strict-Transport-Security" | "Timing-Allow-Origin" | "Trailer" | "Transfer-Encoding" | "Upgrade" | "Vary" | "WWW-Authenticate" | "Warning" | "X-Content-Type-Options" | "X-DNS-Prefetch-Control" | "X-Frame-Options" | "X-Permitted-Cross-Domain-Policies" | "X-Powered-By" | "X-Robots-Tag" | "X-XSS-Protection";
interface SetHeaders {
(name: "Content-Type", value?: BaseMime, options?: SetHeadersOptions): void;
(name: ResponseHeader, value?: string, options?: SetHeadersOptions): void;
(name: string, value?: string, options?: SetHeadersOptions): void;
}
type ResponseHeadersInit = [
string,
string
][] | Record<"Content-Type", BaseMime> | Record<ResponseHeader, string> | Record<string, string> | Headers;
interface ResponseInit {
headers?: ResponseHeadersInit;
status?: number;
statusText?: string;
}
export declare const TEXT_PLAIN = "text/plain; charset=UTF-8";
export declare class Context<E extends Env = any, P extends string = any, I extends Input = {}> {
/**
* `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers.
*
* @see {@link https://hono.dev/docs/api/context#env}
*
* @example
* ```ts
* // Environment object for Cloudflare Workers
* app.get('*', async c => {
* const counter = c.env.COUNTER
* })
* ```
*/
env: E["Bindings"];
finalized: boolean;
/**
* `.error` can get the error object from the middleware if the Handler throws an error.
*
* @see {@link https://hono.dev/docs/api/context#error}
*
* @example
* ```ts
* app.use('*', async (c, next) => {
* await next()
* if (c.error) {
* // do something...
* }
* })
* ```
*/
error: Error | undefined;
/**
* Creates an instance of the Context class.
*
* @param req - The Request object.
* @param options - Optional configuration options for the context.
*/
constructor(req: Request, options?: ContextOptions<E>);
/**
* `.req` is the instance of {@link HonoRequest}.
*/
get req(): HonoRequest<P, I["out"]>;
/**
* @see {@link https://hono.dev/docs/api/context#event}
* The FetchEvent associated with the current request.
*
* @throws Will throw an error if the context does not have a FetchEvent.
*/
get event(): FetchEventLike;
/**
* @see {@link https://hono.dev/docs/api/context#executionctx}
* The ExecutionContext associated with the current request.
*
* @throws Will throw an error if the context does not have an ExecutionContext.
*/
get executionCtx(): ExecutionContext;
/**
* @see {@link https://hono.dev/docs/api/context#res}
* The Response object for the current request.
*/
get res(): Response;
/**
* Sets the Response object for the current request.
*
* @param _res - The Response object to set.
*/
set res(_res: Response | undefined);
/**
* `.render()` can create a response within a layout.
*
* @see {@link https://hono.dev/docs/api/context#render-setrenderer}
*
* @example
* ```ts
* app.get('/', (c) => {
* return c.render('Hello!')
* })
* ```
*/
render: Renderer;
/**
* Sets the layout for the response.
*
* @param layout - The layout to set.
* @returns The layout function.
*/
setLayout: (layout: Layout<PropsForRenderer & {
Layout: Layout;
}>) => Layout<PropsForRenderer & {
Layout: Layout;
}>;
/**
* Gets the current layout for the response.
*
* @returns The current layout function.
*/
getLayout: () => Layout<PropsForRenderer & {
Layout: Layout;
}> | undefined;
/**
* `.setRenderer()` can set the layout in the custom middleware.
*
* @see {@link https://hono.dev/docs/api/context#render-setrenderer}
*
* @example
* ```tsx
* app.use('*', async (c, next) => {
* c.setRenderer((content) => {
* return c.html(
* <html>
* <body>
* <p>{content}</p>
* </body>
* </html>
* )
* })
* await next()
* })
* ```
*/
setRenderer: (renderer: Renderer) => void;
/**
* `.header()` can set headers.
*
* @see {@link https://hono.dev/docs/api/context#body}
*
* @example
* ```ts
* app.get('/welcome', (c) => {
* // Set headers
* c.header('X-Message', 'Hello!')
* c.header('Content-Type', 'text/plain')
*
* return c.body('Thank you for coming')
* })
* ```
*/
header: SetHeaders;
status: (status: StatusCode) => void;
/**
* `.set()` can set the value specified by the key.
*
* @see {@link https://hono.dev/docs/api/context#set-get}
*
* @example
* ```ts
* app.use('*', async (c, next) => {
* c.set('message', 'Hono is cool!!')
* await next()
* })
* ```
*/
set: Set<IsAny<E> extends true ? {
Variables: ContextVariableMap & Record<string, any>;
} : E>;
/**
* `.get()` can use the value specified by the key.
*
* @see {@link https://hono.dev/docs/api/context#set-get}
*
* @example
* ```ts
* app.get('/', (c) => {
* const message = c.get('message')
* return c.text(`The message is "${message}"`)
* })
* ```
*/
get: Get<IsAny<E> extends true ? {
Variables: ContextVariableMap & Record<string, any>;
} : E>;
/**
* `.var` can access the value of a variable.
*
* @see {@link https://hono.dev/docs/api/context#var}
*
* @example
* ```ts
* const result = c.var.client.oneMethod()
* ```
*/
get var(): Readonly<ContextVariableMap & (IsAny<E["Variables"]> extends true ? Record<string, any> : E["Variables"])>;
newResponse: NewResponse;
/**
* `.body()` can return the HTTP response.
* You can set headers with `.header()` and set HTTP status code with `.status`.
* This can also be set in `.text()`, `.json()` and so on.
*
* @see {@link https://hono.dev/docs/api/context#body}
*
* @example
* ```ts
* app.get('/welcome', (c) => {
* // Set headers
* c.header('X-Message', 'Hello!')
* c.header('Content-Type', 'text/plain')
* // Set HTTP status code
* c.status(201)
*
* // Return the response body
* return c.body('Thank you for coming')
* })
* ```
*/
body: BodyRespond;
/**
* `.text()` can render text as `Content-Type:text/plain`.
*
* @see {@link https://hono.dev/docs/api/context#text}
*
* @example
* ```ts
* app.get('/say', (c) => {
* return c.text('Hello!')
* })
* ```
*/
text: TextRespond;
/**
* `.json()` can render JSON as `Content-Type:application/json`.
*
* @see {@link https://hono.dev/docs/api/context#json}
*
* @example
* ```ts
* app.get('/api', (c) => {
* return c.json({ message: 'Hello!' })
* })
* ```
*/
json: JSONRespond;
html: HTMLRespond;
/**
* `.redirect()` can Redirect, default status code is 302.
*
* @see {@link https://hono.dev/docs/api/context#redirect}
*
* @example
* ```ts
* app.get('/redirect', (c) => {
* return c.redirect('/')
* })
* app.get('/redirect-permanently', (c) => {
* return c.redirect('/', 301)
* })
* ```
*/
redirect: <T extends RedirectStatusCode = 302>(location: string, status?: T) => Response & TypedResponse<undefined, T, "redirect">;
/**
* `.notFound()` can return the Not Found Response.
*
* @see {@link https://hono.dev/docs/api/context#notfound}
*
* @example
* ```ts
* app.get('/notfound', (c) => {
* return c.notFound()
* })
* ```
*/
notFound: () => Response | Promise<Response>;
}
export {};