hono
Version:
Web framework built on Web Standards
443 lines (442 loc) • 16.2 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 { InvalidJSONValue, IsAny, JSONParsed, JSONValue, SimplifyDeepArray } from './utils/types';
import type { BaseMime } from './utils/mime';
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 = {}> {
#private;
/**
* `.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 | undefined) => 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 {};