1398 lines
123 KiB
TypeScript
Raw Normal View History

2025-09-05 14:59:21 +08:00
import { QueryObject } from 'ufo';
import { Hooks, AdapterOptions } from 'crossws';
import { IncomingMessage, ServerResponse } from 'node:http';
export { IncomingMessage as NodeIncomingMessage, ServerResponse as NodeServerResponse } from 'node:http';
import { CookieSerializeOptions } from 'cookie-es';
import { SealOptions } from 'iron-webcrypto';
import { Readable } from 'node:stream';
type NodeListener = (req: IncomingMessage, res: ServerResponse) => void;
type NodePromisifiedHandler = (req: IncomingMessage, res: ServerResponse) => Promise<any>;
type NodeMiddleware = (req: IncomingMessage, res: ServerResponse, next: (err?: Error) => any) => any;
declare const defineNodeListener: (handler: NodeListener) => NodeListener;
declare const defineNodeMiddleware: (middleware: NodeMiddleware) => NodeMiddleware;
declare function fromNodeMiddleware(handler: NodeListener | NodeMiddleware): EventHandler;
declare function toNodeListener(app: App): NodeListener;
declare function promisifyNodeListener(handler: NodeListener | NodeMiddleware): NodePromisifiedHandler;
declare function callNodeListener(handler: NodeMiddleware, req: IncomingMessage, res: ServerResponse): Promise<unknown>;
interface NodeEventContext {
req: IncomingMessage & {
originalUrl?: string;
};
res: ServerResponse;
}
interface WebEventContext {
request?: Request;
url?: URL;
}
declare class H3Event<_RequestT extends EventHandlerRequest = EventHandlerRequest> implements Pick<FetchEvent, "respondWith"> {
"__is_event__": boolean;
node: NodeEventContext;
web?: WebEventContext;
context: H3EventContext;
_method?: HTTPMethod;
_path?: string;
_headers?: Headers;
_requestBody?: BodyInit;
_handled: boolean;
_onBeforeResponseCalled: boolean | undefined;
_onAfterResponseCalled: boolean | undefined;
constructor(req: IncomingMessage, res: ServerResponse);
get method(): HTTPMethod;
get path(): string;
get headers(): Headers;
get handled(): boolean;
respondWith(response: Response | PromiseLike<Response>): Promise<void>;
toString(): string;
toJSON(): string;
/** @deprecated Please use `event.node.req` instead. */
get req(): IncomingMessage & {
originalUrl?: string;
};
/** @deprecated Please use `event.node.res` instead. */
get res(): ServerResponse<IncomingMessage>;
}
/**
* Checks if the input is an H3Event object.
* @param input - The input to check.
* @returns True if the input is an H3Event object, false otherwise.
* @see H3Event
*/
declare function isEvent(input: any): input is H3Event;
/**
* Creates a new H3Event instance from the given Node.js request and response objects.
* @param req - The NodeIncomingMessage object.
* @param res - The NodeServerResponse object.
* @returns A new H3Event instance.
* @see H3Event
*/
declare function createEvent(req: IncomingMessage, res: ServerResponse): H3Event;
declare function defineEventHandler<Request extends EventHandlerRequest = EventHandlerRequest, Response = EventHandlerResponse>(handler: EventHandler<Request, Response> | EventHandlerObject<Request, Response>): EventHandler<Request, Response>;
declare function defineEventHandler<Request = EventHandlerRequest, Response = EventHandlerResponse>(handler: EventHandler<Request extends EventHandlerRequest ? Request : EventHandlerRequest, Request extends EventHandlerRequest ? Response : Request>): EventHandler<Request extends EventHandlerRequest ? Request : EventHandlerRequest, Request extends EventHandlerRequest ? Response : Request>;
declare const eventHandler: typeof defineEventHandler;
declare function defineRequestMiddleware<Request extends EventHandlerRequest = EventHandlerRequest>(fn: _RequestMiddleware<Request>): _RequestMiddleware<Request>;
declare function defineResponseMiddleware<Request extends EventHandlerRequest = EventHandlerRequest>(fn: _ResponseMiddleware<Request>): _ResponseMiddleware<Request>;
/**
* Checks if any kind of input is an event handler.
* @param input The input to check.
* @returns True if the input is an event handler, false otherwise.
*/
declare function isEventHandler(input: any): input is EventHandler;
declare function toEventHandler(input: any, _?: any, _route?: string): EventHandler;
interface DynamicEventHandler extends EventHandler {
set: (handler: EventHandler) => void;
}
declare function dynamicEventHandler(initial?: EventHandler): DynamicEventHandler;
declare function defineLazyEventHandler<T extends LazyEventHandler>(factory: T): Awaited<ReturnType<T>>;
declare const lazyEventHandler: typeof defineLazyEventHandler;
/**
* @deprecated Please use native web Headers
* https://developer.mozilla.org/en-US/docs/Web/API/Headers
*/
declare const H3Headers: {
new (init?: HeadersInit): Headers;
prototype: Headers;
};
/**
* @deprecated Please use native web Response
* https://developer.mozilla.org/en-US/docs/Web/API/Response
*/
declare const H3Response: {
new (body?: BodyInit | null, init?: ResponseInit): Response;
prototype: Response;
error(): Response;
json(data: any, init?: ResponseInit): Response;
redirect(url: string | URL, status?: number): Response;
};
type SessionDataT = Record<string, any>;
type SessionData<T extends SessionDataT = SessionDataT> = T;
declare const getSessionPromise: unique symbol;
interface Session<T extends SessionDataT = SessionDataT> {
id: string;
createdAt: number;
data: SessionData<T>;
[getSessionPromise]?: Promise<Session<T>>;
}
interface SessionManager<T extends SessionDataT = SessionDataT> {
readonly id: string | undefined;
readonly data: SessionData<T>;
update: (update: SessionUpdate<T>) => Promise<SessionManager<T>>;
clear: () => Promise<SessionManager<T>>;
}
interface SessionConfig {
/** Private key used to encrypt session tokens */
password: string;
/** Session expiration time in seconds */
maxAge?: number;
/** default is h3 */
name?: string;
/** Default is secure, httpOnly, / */
cookie?: false | CookieSerializeOptions;
/** Default is x-h3-session / x-{name}-session */
sessionHeader?: false | string;
seal?: SealOptions;
crypto?: Crypto;
/** Default is Crypto.randomUUID */
generateId?: () => string;
}
type CompatEvent = {
request: {
headers: Headers;
};
context: any;
} | {
headers: Headers;
context: any;
};
/**
* Create a session manager for the current request.
*/
declare function useSession<T extends SessionDataT = SessionDataT>(event: H3Event | CompatEvent, config: SessionConfig): Promise<SessionManager<T>>;
/**
* Get the session for the current request.
*/
declare function getSession<T extends SessionDataT = SessionDataT>(event: H3Event | CompatEvent, config: SessionConfig): Promise<Session<T>>;
type SessionUpdate<T extends SessionDataT = SessionDataT> = Partial<SessionData<T>> | ((oldData: SessionData<T>) => Partial<SessionData<T>> | undefined);
/**
* Update the session data for the current request.
*/
declare function updateSession<T extends SessionDataT = SessionDataT>(event: H3Event, config: SessionConfig, update?: SessionUpdate<T>): Promise<Session<T>>;
/**
* Encrypt and sign the session data for the current request.
*/
declare function sealSession<T extends SessionDataT = SessionDataT>(event: H3Event | CompatEvent, config: SessionConfig): Promise<string>;
/**
* Decrypt and verify the session data for the current request.
*/
declare function unsealSession(_event: H3Event | CompatEvent, config: SessionConfig, sealed: string): Promise<Partial<Session<SessionDataT>>>;
/**
* Clear the session data for the current request.
*/
declare function clearSession(event: H3Event, config: Partial<SessionConfig>): Promise<void>;
type RouterMethod = Lowercase<HTTPMethod>;
type RouterUse = (path: string, handler: EventHandler, method?: RouterMethod | RouterMethod[]) => Router;
type AddRouteShortcuts = Record<RouterMethod, RouterUse>;
interface Router extends AddRouteShortcuts {
add: RouterUse;
use: RouterUse;
handler: EventHandler;
}
interface RouteNode {
handlers: Partial<Record<RouterMethod | "all", EventHandler>>;
path: string;
}
interface CreateRouterOptions {
/** @deprecated Please use `preemptive` instead. */
preemtive?: boolean;
preemptive?: boolean;
}
/**
* Create a new h3 router instance.
*/
declare function createRouter(opts?: CreateRouterOptions): Router;
type AnyString = string & {};
type AnyNumber = number & {};
type ValidateResult<T> = T | true | false | void;
type ValidateFunction<T> = (data: unknown) => ValidateResult<T> | Promise<ValidateResult<T>>;
type MimeType = 'application/1d-interleaved-parityfec' | 'application/3gpdash-qoe-report+xml' | 'application/3gppHal+json' | 'application/3gppHalForms+json' | 'application/3gpp-ims+xml' | 'application/A2L' | 'application/ace+cbor' | 'application/ace+json' | 'application/activemessage' | 'application/activity+json' | 'application/aif+cbor' | 'application/aif+json' | 'application/alto-cdni+json' | 'application/alto-cdnifilter+json' | 'application/alto-costmap+json' | 'application/alto-costmapfilter+json' | 'application/alto-directory+json' | 'application/alto-endpointprop+json' | 'application/alto-endpointpropparams+json' | 'application/alto-endpointcost+json' | 'application/alto-endpointcostparams+json' | 'application/alto-error+json' | 'application/alto-networkmapfilter+json' | 'application/alto-networkmap+json' | 'application/alto-propmap+json' | 'application/alto-propmapparams+json' | 'application/alto-tips+json' | 'application/alto-tipsparams+json' | 'application/alto-updatestreamcontrol+json' | 'application/alto-updatestreamparams+json' | 'application/AML' | 'application/andrew-inset' | 'application/applefile' | 'application/at+jwt' | 'application/ATF' | 'application/ATFX' | 'application/atom+xml' | 'application/atomcat+xml' | 'application/atomdeleted+xml' | 'application/atomicmail' | 'application/atomsvc+xml' | 'application/atsc-dwd+xml' | 'application/atsc-dynamic-event-message' | 'application/atsc-held+xml' | 'application/atsc-rdt+json' | 'application/atsc-rsat+xml' | 'application/ATXML' | 'application/auth-policy+xml' | 'application/automationml-aml+xml' | 'application/automationml-amlx+zip' | 'application/bacnet-xdd+zip' | 'application/batch-SMTP' | 'application/beep+xml' | 'application/c2pa' | 'application/calendar+json' | 'application/calendar+xml' | 'application/call-completion' | 'application/CALS-1840' | 'application/captive+json' | 'application/cbor' | 'application/cbor-seq' | 'application/cccex' | 'application/ccmp+xml' | 'application/ccxml+xml' | 'application/cda+xml' | 'application/CDFX+XML' | 'application/cdmi-capability' | 'application/cdmi-container' | 'application/cdmi-domain' | 'application/cdmi-object' | 'application/cdmi-queue' | 'application/cdni' | 'application/CEA' | 'application/cea-2018+xml' | 'application/cellml+xml' | 'application/cfw' | 'application/cid-edhoc+cbor-seq' | 'application/city+json' | 'application/clr' | 'application/clue_info+xml' | 'application/clue+xml' | 'application/cms' | 'application/cnrp+xml' | 'application/coap-group+json' | 'application/coap-payload' | 'application/commonground' | 'application/concise-problem-details+cbor' | 'application/conference-info+xml' | 'application/cpl+xml' | 'application/cose' | 'application/cose-key' | 'application/cose-key-set' | 'application/cose-x509' | 'application/csrattrs' | 'application/csta+xml' | 'application/CSTAdata+xml' | 'application/csvm+json' | 'application/cwl' | 'application/cwl+json' | 'application/cwt' | 'application/cybercash' | 'application/dash+xml' | 'application/dash-patch+xml' | 'application/dashdelta' | 'application/davmount+xml' | 'application/dca-rft' | 'application/DCD' | 'application/dec-dx' | 'application/dialog-info+xml' | 'application/dicom' | 'application/dicom+json' | 'application/dicom+xml' | 'application/DII' | 'application/DIT' | 'application/dns' | 'application/dns+json' | 'application/dns-message' | 'application/dots+cbor' | 'application/dpop+jwt' | 'application/dskpp+xml' | 'application/dssc+der' | 'application/dssc+xml' | 'application/dvcs' | 'application/ecmascript' | 'application/edhoc+cbor-seq' | 'application/EDI-consent' | 'application/EDIFACT' | 'application/EDI-X12' | 'application/efi' | 'application/elm+json' | 'application/elm+xml' | 'application/EmergencyCallData.cap+xml' | 'application/EmergencyCallData.Comment+xml' | 'application/EmergencyCallData.Control+xml' | 'application/EmergencyCallData.DeviceInfo+xml' | 'application/EmergencyCallData.eCall.MSD' | 'application/EmergencyCallData.LegacyESN+json' | 'application/EmergencyCallData.ProviderInfo+xml' | 'application/EmergencyCallData.Servi
type RequestHeaders = Partial<Record<HTTPHeaderName, string | undefined>>;
type _HTTPHeaderName = "WWW-Authenticate" | "Authorization" | "Proxy-Authenticate" | "Proxy-Authorization" | "Age" | "Cache-Control" | "Clear-Site-Data" | "Expires" | "Pragma" | "Accept-CH" | "Critical-CH" | "Sec-CH-UA" | "Sec-CH-UA-Arch" | "Sec-CH-UA-Bitness" | "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-Prefers-Color-Scheme" | "Sec-CH-UA-Prefers-Reduced-Motion" | "Downlink" | "ECT" | "RTT" | "Save-Data" | "Last-Modified" | "ETag" | "If-Match" | "If-None-Match" | "If-Modified-Since" | "If-Unmodified-Since" | "Vary" | "Connection" | "Keep-Alive" | "Accept" | "Accept-Encoding" | "Accept-Language" | "Expect" | "Max-Forwards" | "Cookie" | "Set-Cookie" | "Access-Control-Allow-Origin" | "Access-Control-Allow-Credentials" | "Access-Control-Allow-Headers" | "Access-Control-Allow-Methods" | "Access-Control-Expose-Headers" | "Access-Control-Max-Age" | "Access-Control-Request-Headers" | "Access-Control-Request-Method" | "Origin" | "Timing-Allow-Origin" | "Content-Disposition" | "Content-Length" | "Content-Type" | "Content-Encoding" | "Content-Language" | "Content-Location" | "Forwarded" | "X-Forwarded-For" | "X-Forwarded-Host" | "X-Forwarded-Proto" | "Via" | "Location" | "Refresh" | "From" | "Host" | "Referer" | "Referrer-Policy" | "User-Agent" | "Allow" | "Server" | "Accept-Ranges" | "Range" | "If-Range" | "Content-Range" | "Cross-Origin-Embedder-Policy" | "Cross-Origin-Opener-Policy" | "Cross-Origin-Resource-Policy" | "Content-Security-Policy" | "Content-Security-Policy-Report-Only" | "Expect-CT" | "Origin-Isolation" | "Permissions-Policy" | "Strict-Transport-Security" | "Upgrade-Insecure-Requests" | "X-Content-Type-Options" | "X-Frame-Options" | "X-Permitted-Cross-Domain-Policies" | "X-Powered-By" | "X-XSS-Protection" | "Sec-Fetch-Site" | "Sec-Fetch-Mode" | "Sec-Fetch-User" | "Sec-Fetch-Dest" | "Sec-Purpose" | "Service-Worker-Navigation-Preload" | "Last-Event-ID" | "NEL" | "Ping-From" | "Ping-To" | "Report-To" | "Transfer-Encoding" | "TE" | "Trailer" | "Sec-WebSocket-Key" | "Sec-WebSocket-Extensions" | "Sec-WebSocket-Accept" | "Sec-WebSocket-Protocol" | "Sec-WebSocket-Version" | "Accept-Push-Policy" | "Accept-Signature" | "Alt-Svc" | "Alt-Used" | "Date" | "Early-Data" | "Link" | "Push-Policy" | "Retry-After" | "Signature" | "Signed-Headers" | "Server-Timing" | "Service-Worker-Allowed" | "SourceMap" | "Upgrade" | "X-DNS-Prefetch-Control" | "X-Pingback" | "X-Requested-With" | "X-Robots-Tag";
type HTTPHeaderName = _HTTPHeaderName | Lowercase<_HTTPHeaderName> | (string & {});
type ClientHint = "Sec-CH-UA" | "Sec-CH-UA-Arch" | "Sec-CH-UA-Bitness" | "Sec-CH-UA-Full-Version-List" | "Sec-CH-UA-Full-Version" | "Sec-CH-UA-Mobile" | "Sec-CH-UA-Model" | "Sec-CH-UA-Platform" | "Sec-CH-UA-Platform-Version" | "Sec-CH-Prefers-Reduced-Motion" | "Sec-CH-Prefers-Color-Scheme" | "Device-Memory" | "Width" | "Viewport-Width" | "Save-Data" | "Downlink" | "ECT" | "RTT" | AnyString;
type TypedHeaders = Partial<Record<HTTPHeaderName, unknown>> & Partial<{
host: string;
location: string;
referrer: string;
origin: "null" | AnyString;
from: string;
"alt-used": string;
"content-location": string;
sourcemap: string;
"content-length": number;
"access-control-max-age": number;
"retry-after": number;
rtt: number;
age: number;
"max-forwards": number;
downlink: number;
"device-memory": 0.25 | 0.5 | 1 | 2 | 4 | 8 | AnyNumber;
accept: MimeType | MimeType[] | `${MimeType};q=${number}`[];
"content-type": MimeType;
"accept-ch": ClientHint | ClientHint[];
"keep-alive": `timeout=${number}, max=${number}` | AnyString;
"access-control-allow-credentials": "true" | AnyString;
"access-control-allow-headers": "*" | HTTPHeaderName[] | AnyString;
"access-control-allow-methods": "*" | HTTPMethod[] | AnyString;
"access-control-allow-origin": "*" | "null" | AnyString;
"access-control-expose-headers": "*" | HTTPHeaderName[] | AnyString;
"access-control-request-headers": HTTPHeaderName[] | AnyString;
"access-control-request-method": HTTPMethod | AnyString;
"early-data": 1;
"upgrade-insecure-requests": 1;
"accept-ranges": "bytes" | "none" | AnyString;
connection: "keep-alive" | "close" | "upgrade" | AnyString;
ect: "slow-2g" | "2g" | "3g" | "4g" | AnyString;
expect: "100-continue" | AnyString;
"save-data": `on` | `off` | AnyString;
"sec-ch-prefers-reduced-motion": "no-preference" | "reduce" | AnyString;
"sec-ch-prefers-reduced-transparency": "no-preference" | "reduce" | AnyString;
"sec-ch-ua-mobile": `?1` | `?0` | AnyString;
"origin-agent-cluster": `?1` | `?0` | AnyString;
"sec-fetch-user": "?1" | AnyString;
"sec-purpose": "prefetch" | AnyString;
"x-content-type-options": "nosniff" | AnyString;
"x-dns-prefetch-control": "on" | "off" | AnyString;
"x-frame-options": "DENY" | "SAMEORIGIN" | AnyString;
"sec-ch-ua-arch": "x86" | "ARM" | "[arm64-v8a, armeabi-v7a, armeabi]" | AnyString;
"sec-fetch-site": "cross-site" | "same-origin" | "same-site" | "none" | AnyString;
"sec-ch-prefers-color-scheme": "dark" | "light" | AnyString;
"sec-ch-ua-bitness": "64" | "32" | AnyString;
"sec-fetch-mode": "cors" | "navigate" | "no-cors" | "same-origin" | "websocket" | AnyString;
"cross-origin-embedder-policy": "unsafe-none" | "require-corp" | "credentialless" | AnyString;
"cross-origin-opener-policy": "unsafe-none" | "same-origin-allow-popups" | "same-origin" | AnyString;
"cross-origin-resource-policy": "same-site" | "same-origin" | "cross-origin" | AnyString;
"sec-ch-ua-platform": "Android" | "Chrome OS" | "Chromium OS" | "iOS" | "Linux" | "macOS" | "Windows" | "Unknown" | AnyString;
"referrer-policy": "no-referrer" | "no-referrer-when-downgrade" | "origin" | "origin-when-cross-origin" | "same-origin" | "strict-origin" | "strict-origin-when-cross-origin" | "unsafe-url" | AnyString;
"sec-fetch-dest": "audio" | "audioworklet" | "document" | "embed" | "empty" | "font" | "frame" | "iframe" | "image" | "manifest" | "object" | "paintworklet" | "report" | "script" | "serviceworker" | "sharedworker" | "style" | "track" | "video" | "worker" | "xslt" | AnyString;
}>;
type HTTPMethod = "GET" | "HEAD" | "PATCH" | "POST" | "PUT" | "DELETE" | "CONNECT" | "OPTIONS" | "TRACE";
type Encoding = false | "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex";
type StatusCode = 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 304 | 305 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 444 | 450 | 451 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 506 | 507 | 508 | 509 | 510 | 511 | 521 | 522 | 523 | 525 | 530 | 599 | AnyNumber;
interface H3EventContext extends Record<string, any> {
params?: Record<string, string>;
/**
* Matched router Node
*
* @experimental The object structure may change in non-major version.
*/
matchedRoute?: RouteNode;
sessions?: Record<string, Session>;
clientAddress?: string;
}
type EventHandlerResponse<T = any> = T | Promise<T>;
interface EventHandlerRequest {
body?: any;
query?: QueryObject;
routerParams?: Record<string, string>;
}
type InferEventInput<Key extends keyof EventHandlerRequest, Event extends H3Event, T> = void extends T ? (Event extends H3Event<infer E> ? E[Key] : never) : T;
type MaybePromise<T> = T | Promise<T>;
type EventHandlerResolver = (path: string) => MaybePromise<undefined | {
route?: string;
handler: EventHandler;
}>;
interface EventHandler<Request extends EventHandlerRequest = EventHandlerRequest, Response extends EventHandlerResponse = EventHandlerResponse> {
__is_handler__?: true;
__resolve__?: EventHandlerResolver;
__websocket__?: Partial<Hooks>;
(event: H3Event<Request>): Response;
}
type _RequestMiddleware<Request extends EventHandlerRequest = EventHandlerRequest> = (event: H3Event<Request>) => void | Promise<void>;
type _ResponseMiddleware<Request extends EventHandlerRequest = EventHandlerRequest, Response extends EventHandlerResponse = EventHandlerResponse> = (event: H3Event<Request>, response: {
body?: Awaited<Response>;
}) => void | Promise<void>;
type EventHandlerObject<Request extends EventHandlerRequest = EventHandlerRequest, Response extends EventHandlerResponse = EventHandlerResponse> = {
onRequest?: _RequestMiddleware<Request> | _RequestMiddleware<Request>[];
onBeforeResponse?: _ResponseMiddleware<Request, Response> | _ResponseMiddleware<Request, Response>[];
/** @experimental */
websocket?: Partial<Hooks>;
handler: EventHandler<Request, Response>;
};
type LazyEventHandler = () => EventHandler | Promise<EventHandler>;
/**
* H3 Runtime Error
* @class
* @extends Error
* @property {number} statusCode - An integer indicating the HTTP response status code.
* @property {string} statusMessage - A string representing the HTTP status message.
* @property {boolean} fatal - Indicates if the error is a fatal error.
* @property {boolean} unhandled - Indicates if the error was unhandled and auto captured.
* @property {DataT} data - An extra data that will be included in the response.
* This can be used to pass additional information about the error.
*/
declare class H3Error<DataT = unknown> extends Error {
static __h3_error__: boolean;
statusCode: number;
fatal: boolean;
unhandled: boolean;
statusMessage?: string;
data?: DataT;
cause?: unknown;
constructor(message: string, opts?: {
cause?: unknown;
});
toJSON(): Pick<H3Error<DataT>, "message" | "statusCode" | "statusMessage" | "data">;
}
/**
* Creates a new `Error` that can be used to handle both internal and runtime errors.
*
* @param input {string | (Partial<H3Error> & { status?: number; statusText?: string })} - The error message or an object containing error properties.
* If a string is provided, it will be used as the error `message`.
*
* @example
* // String error where `statusCode` defaults to `500`
* throw createError("An error occurred");
* // Object error
* throw createError({
* statusCode: 400,
* statusMessage: "Bad Request",
* message: "Invalid input",
* data: { field: "email" }
* });
*
*
* @return {H3Error} - An instance of H3Error.
*
* @remarks
* - Typically, `message` contains a brief, human-readable description of the error, while `statusMessage` is specific to HTTP responses and describes
* the status text related to the response status code.
* - In a client-server context, using a short `statusMessage` is recommended because it can be accessed on the client side. Otherwise, a `message`
* passed to `createError` on the server will not propagate to the client.
* - Consider avoiding putting dynamic user input in the `message` to prevent potential security issues.
*/
declare function createError<DataT = unknown>(input: string | (Partial<H3Error<DataT>> & {
status?: number;
statusText?: string;
})): H3Error<DataT>;
/**
* Receives an error and returns the corresponding response.
* H3 internally uses this function to handle unhandled errors.
* Note that calling this function will close the connection and no other data will be sent to the client afterwards.
*
* @param event {H3Event} - H3 event or req passed by h3 handler.
* @param error {Error | H3Error} - The raised error.
* @param debug {boolean} - Whether the application is in debug mode.
* In the debug mode, the stack trace of errors will be returned in the response.
*/
declare function sendError(event: H3Event, error: Error | H3Error, debug?: boolean): void;
/**
* Checks if the given input is an instance of H3Error.
*
* @param input {*} - The input to check.
* @return {boolean} - Returns true if the input is an instance of H3Error, false otherwise.
*/
declare function isError<DataT = unknown>(input: any): input is H3Error<DataT>;
interface Layer {
route: string;
match?: Matcher;
handler: EventHandler;
}
type Stack = Layer[];
interface InputLayer {
route?: string;
match?: Matcher;
handler: EventHandler;
lazy?: boolean;
}
type InputStack = InputLayer[];
type Matcher = (url: string, event?: H3Event) => boolean;
interface AppUse {
(route: string | string[], handler: EventHandler | EventHandler[], options?: Partial<InputLayer>): App;
(handler: EventHandler | EventHandler[], options?: Partial<InputLayer>): App;
(options: InputLayer): App;
}
type WebSocketOptions = AdapterOptions;
interface AppOptions {
debug?: boolean;
onError?: (error: H3Error, event: H3Event) => any;
onRequest?: (event: H3Event) => void | Promise<void>;
onBeforeResponse?: (event: H3Event, response: {
body?: unknown;
}) => void | Promise<void>;
onAfterResponse?: (event: H3Event, response?: {
body?: unknown;
}) => void | Promise<void>;
websocket?: WebSocketOptions;
}
interface App {
stack: Stack;
handler: EventHandler;
options: AppOptions;
use: AppUse;
resolve: EventHandlerResolver;
readonly websocket: WebSocketOptions;
}
/**
* Create a new H3 app instance.
*/
declare function createApp(options?: AppOptions): App;
declare function use(app: App, arg1: string | EventHandler | InputLayer | InputLayer[], arg2?: Partial<InputLayer> | EventHandler | EventHandler[], arg3?: Partial<InputLayer>): App;
declare function createAppEventHandler(stack: Stack, options: AppOptions): EventHandler<EventHandlerRequest, Promise<void>>;
/**
* Prefixes and executes a handler with a base path.
*
* @example
* const app = createApp();
* const router = createRouter();
*
* const apiRouter = createRouter().get(
* "/hello",
* defineEventHandler((event) => {
* return "Hello API!";
* }),
* );
*
* router.use("/api/**", useBase("/api", apiRouter.handler));
*
* app.use(router.handler);
*
* @param base The base path to prefix. When set to an empty string, the handler will be run as is.
* @param handler The event handler to use with the adapted path.
*/
declare function useBase(base: string, handler: EventHandler): EventHandler;
interface MultiPartData {
data: Buffer;
name?: string;
filename?: string;
type?: string;
}
/**
* Reads body of the request and returns encoded raw string (default), or `Buffer` if encoding is falsy.
*
* @example
* export default defineEventHandler(async (event) => {
* const body = await readRawBody(event, "utf-8");
* });
*
* @param event {H3Event} H3 event or req passed by h3 handler
* @param encoding {Encoding} encoding="utf-8" - The character encoding to use.
*
* @return {String|Buffer} Encoded raw string or raw Buffer of the body
*/
declare function readRawBody<E extends Encoding = "utf8">(event: H3Event, encoding?: E): E extends false ? Promise<Buffer | undefined> : Promise<string | undefined>;
/**
* Reads request body and tries to safely parse using [destr](https://github.com/unjs/destr).
*
* Be aware that this utility is not restricted to `application/json` and will parse `application/x-www-form-urlencoded` content types.
* Because of this, authenticated `GET`/`POST` handlers may be at risk of a [CSRF](https://owasp.org/www-community/attacks/csrf) attack, and must check the `content-type` header manually.
*
* @example
* export default defineEventHandler(async (event) => {
* const body = await readBody(event);
* });
*
* @param event H3 event passed by h3 handler
* @param encoding The character encoding to use, defaults to 'utf-8'.
*
* @return {*} The `Object`, `Array`, `String`, `Number`, `Boolean`, or `null` value corresponding to the request JSON body
*/
declare function readBody<T, Event extends H3Event = H3Event, _T = InferEventInput<"body", Event, T>>(event: Event, options?: {
strict?: boolean;
}): Promise<_T>;
/**
* Tries to read the request body via `readBody`, then uses the provided validation function and either throws a validation error or returns the result.
*
* You can use a simple function to validate the body or use a library like `zod` to define a schema.
*
* @example
* export default defineEventHandler(async (event) => {
* const body = await readValidatedBody(event, (body) => {
* return typeof body === "object" && body !== null;
* });
* });
* @example
* import { z } from "zod";
*
* export default defineEventHandler(async (event) => {
* const objectSchema = z.object();
* const body = await readValidatedBody(event, objectSchema.safeParse);
* });
*
* @param event The H3Event passed by the handler.
* @param validate The function to use for body validation. It will be called passing the read request body. If the result is not false, the parsed body will be returned.
* @throws If the validation function returns `false` or throws, a validation error will be thrown.
* @return {*} The `Object`, `Array`, `String`, `Number`, `Boolean`, or `null` value corresponding to the request JSON body.
* @see {readBody}
*/
declare function readValidatedBody<T, Event extends H3Event = H3Event, _T = InferEventInput<"body", Event, T>>(event: Event, validate: ValidateFunction<_T>): Promise<_T>;
/**
* Tries to read and parse the body of an H3Event as multipart form.
*
* @example
* export default defineEventHandler(async (event) => {
* const formData = await readMultipartFormData(event);
* // The result could look like:
* // [
* // {
* // "data": "other",
* // "name": "baz",
* // },
* // {
* // "data": "something",
* // "name": "some-other-data",
* // },
* // ];
* });
*
* @param event The H3Event object to read multipart form from.
*
* @return The parsed form data. If no form could be detected because the content type is not multipart/form-data or no boundary could be found.
*/
declare function readMultipartFormData(event: H3Event): Promise<MultiPartData[] | undefined>;
/**
* Constructs a FormData object from an event, after converting it to a a web request.
*
* @example
* export default defineEventHandler(async (event) => {
* const formData = await readFormData(event);
* const email = formData.get("email");
* const password = formData.get("password");
* });
*
* @param event The H3Event object to read the form data from.
*/
declare function readFormData(event: H3Event): Promise<FormData>;
/**
* Captures a stream from a request.
* @param event The H3Event object containing the request information.
* @returns Undefined if the request can't transport a payload, otherwise a ReadableStream of the request body.
*/
declare function getRequestWebStream(event: H3Event): undefined | ReadableStream;
interface CacheConditions {
modifiedTime?: string | Date;
maxAge?: number;
etag?: string;
cacheControls?: string[];
}
/**
* Check request caching headers (`If-Modified-Since`) and add caching headers (Last-Modified, Cache-Control)
* Note: `public` cache control will be added by default
* @returns `true` when cache headers are matching. When `true` is returned, no response should be sent anymore
*/
declare function handleCacheHeaders(event: H3Event, opts: CacheConditions): boolean;
declare const MIMES: {
readonly html: "text/html";
readonly json: "application/json";
};
interface H3CorsOptions {
origin?: "*" | "null" | (string | RegExp)[] | ((origin: string) => boolean);
methods?: "*" | HTTPMethod[];
allowHeaders?: "*" | string[];
exposeHeaders?: "*" | string[];
credentials?: boolean;
maxAge?: string | false;
preflight?: {
statusCode?: number;
};
}
/**
* Handle CORS for the incoming request.
*
* If the incoming request is a CORS preflight request, it will append the CORS preflight headers and send a 204 response.
*
* If return value is `true`, the request is handled and no further action is needed.
*
* @example
* const app = createApp();
* const router = createRouter();
* router.use('/',
* defineEventHandler(async (event) => {
* const didHandleCors = handleCors(event, {
* origin: '*',
* preflight: {
* statusCode: 204,
* },
* methods: '*',
* });
* if (didHandleCors) {
* return;
* }
* // Your code here
* })
* );
*/
declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
/**
* Get the query params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io).
*
* @example
* export default defineEventHandler((event) => {
* const query = getQuery(event); // { key: "value", key2: ["value1", "value2"] }
* });
*/
declare function getQuery<T, Event extends H3Event = H3Event, _T = Exclude<InferEventInput<"query", Event, T>, undefined>>(event: Event): _T;
/**
* Get the query params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io) and validated with validate function.
*
* You can use a simple function to validate the query object or a library like `zod` to define a schema.
*
* @example
* export default defineEventHandler((event) => {
* const query = getValidatedQuery(event, (data) => {
* return "key" in data && typeof data.key === "string";
* });
* });
* @example
* import { z } from "zod";
*
* export default defineEventHandler((event) => {
* const query = getValidatedQuery(
* event,
* z.object({
* key: z.string(),
* }),
* );
* });
*/
declare function getValidatedQuery<T, Event extends H3Event = H3Event, _T = InferEventInput<"query", Event, T>>(event: Event, validate: ValidateFunction<_T>): Promise<_T>;
/**
* Get matched route params.
*
* If `decode` option is `true`, it will decode the matched route params using `decodeURI`.
*
* @example
* export default defineEventHandler((event) => {
* const params = getRouterParams(event); // { key: "value" }
* });
*/
declare function getRouterParams(event: H3Event, opts?: {
decode?: boolean;
}): NonNullable<H3Event["context"]["params"]>;
/**
* Get matched route params and validate with validate function.
*
* If `decode` option is `true`, it will decode the matched route params using `decodeURI`.
*
* You can use a simple function to validate the params object or a library like `zod` to define a schema.
*
* @example
* export default defineEventHandler((event) => {
* const params = getValidatedRouterParams(event, (data) => {
* return "key" in data && typeof data.key === "string";
* });
* });
* @example
* import { z } from "zod";
*
* export default defineEventHandler((event) => {
* const params = getValidatedRouterParams(
* event,
* z.object({
* key: z.string(),
* }),
* );
* });
*/
declare function getValidatedRouterParams<T, Event extends H3Event = H3Event, _T = InferEventInput<"routerParams", Event, T>>(event: Event, validate: ValidateFunction<_T>, opts?: {
decode?: boolean;
}): Promise<_T>;
/**
* Get a matched route param by name.
*
* If `decode` option is `true`, it will decode the matched route param using `decodeURI`.
*
* @example
* export default defineEventHandler((event) => {
* const param = getRouterParam(event, "key");
* });
*/
declare function getRouterParam(event: H3Event, name: string, opts?: {
decode?: boolean;
}): string | undefined;
/**
* @deprecated Directly use `event.method` instead.
*/
declare function getMethod(event: H3Event, defaultMethod?: HTTPMethod): HTTPMethod;
/**
*
* Checks if the incoming request method is of the expected type.
*
* If `allowHead` is `true`, it will allow `HEAD` requests to pass if the expected method is `GET`.
*
* @example
* export default defineEventHandler((event) => {
* if (isMethod(event, "GET")) {
* // Handle GET request
* } else if (isMethod(event, ["POST", "PUT"])) {
* // Handle POST or PUT request
* }
* });
*/
declare function isMethod(event: H3Event, expected: HTTPMethod | HTTPMethod[], allowHead?: boolean): boolean;
/**
* Asserts that the incoming request method is of the expected type using `isMethod`.
*
* If the method is not allowed, it will throw a 405 error with the message "HTTP method is not allowed".
*
* If `allowHead` is `true`, it will allow `HEAD` requests to pass if the expected method is `GET`.
*
* @example
* export default defineEventHandler((event) => {
* assertMethod(event, "GET");
* // Handle GET request, otherwise throw 405 error
* });
*/
declare function assertMethod(event: H3Event, expected: HTTPMethod | HTTPMethod[], allowHead?: boolean): void;
/**
* Get the request headers object.
*
* Array headers are joined with a comma.
*
* @example
* export default defineEventHandler((event) => {
* const headers = getRequestHeaders(event); // { "content-type": "application/json", "x-custom-header": "value" }
* });
*/
declare function getRequestHeaders(event: H3Event): RequestHeaders;
/**
* Alias for `getRequestHeaders`.
*/
declare const getHeaders: typeof getRequestHeaders;
/**
* Get a request header by name.
*
* @example
* export default defineEventHandler((event) => {
* const contentType = getRequestHeader(event, "content-type"); // "application/json"
* });
*/
declare function getRequestHeader(event: H3Event, name: HTTPHeaderName): RequestHeaders[string];
/**
* Alias for `getRequestHeader`.
*/
declare const getHeader: typeof getRequestHeader;
/**
* Get the request hostname.
*
* If `xForwardedHost` is `true`, it will use the `x-forwarded-host` header if it exists.
*
* If no host header is found, it will default to "localhost".
*
* @example
* export default defineEventHandler((event) => {
* const host = getRequestHost(event); // "example.com"
* });
*/
declare function getRequestHost(event: H3Event, opts?: {
xForwardedHost?: boolean;
}): string;
/**
* Get the request protocol.
*
* If `x-forwarded-proto` header is set to "https", it will return "https". You can disable this behavior by setting `xForwardedProto` to `false`.
*
* If protocol cannot be determined, it will default to "http".
*
* @example
* export default defineEventHandler((event) => {
* const protocol = getRequestProtocol(event); // "https"
* });
*/
declare function getRequestProtocol(event: H3Event, opts?: {
xForwardedProto?: boolean;
}): "https" | "http";
/** @deprecated Use `event.path` instead */
declare function getRequestPath(event: H3Event): string;
/**
* Generate the full incoming request URL using `getRequestProtocol`, `getRequestHost` and `event.path`.
*
* If `xForwardedHost` is `true`, it will use the `x-forwarded-host` header if it exists.
*
* If `xForwardedProto` is `false`, it will not use the `x-forwarded-proto` header.
*
* @example
* export default defineEventHandler((event) => {
* const url = getRequestURL(event); // "https://example.com/path"
* });
*/
declare function getRequestURL(event: H3Event, opts?: {
xForwardedHost?: boolean;
xForwardedProto?: boolean;
}): URL;
/**
* Convert the H3Event to a WebRequest object.
*
* **NOTE:** This function is not stable and might have edge cases that are not handled properly.
*/
declare function toWebRequest(event: H3Event): Request;
/**
* Try to get the client IP address from the incoming request.
*
* If `xForwardedFor` is `true`, it will use the `x-forwarded-for` header set by proxies if it exists.
*
* Note: Make sure that this header can be trusted (your application running behind a CDN or reverse proxy) before enabling.
*
* If IP cannot be determined, it will default to `undefined`.
*
* @example
* export default defineEventHandler((event) => {
* const ip = getRequestIP(event); // "192.0.2.0"
* });
*/
declare function getRequestIP(event: H3Event, opts?: {
xForwardedFor?: boolean;
}): string | undefined;
/**
* Check if the incoming request is a CORS preflight request.
*/
declare function isPreflightRequest(event: H3Event): boolean;
/**
* Check if the incoming request is a CORS request.
*/
declare function isCorsOriginAllowed(origin: ReturnType<typeof getRequestHeaders>["origin"], options: H3CorsOptions): boolean;
/**
* Append CORS preflight headers to the response.
*/
declare function appendCorsPreflightHeaders(event: H3Event, options: H3CorsOptions): void;
/**
* Append CORS headers to the response.
*/
declare function appendCorsHeaders(event: H3Event, options: H3CorsOptions): void;
/**
* Parse the request to get HTTP Cookie header string and return an object of all cookie name-value pairs.
* @param event {H3Event} H3 event or req passed by h3 handler
* @returns Object of cookie name-value pairs
* ```ts
* const cookies = parseCookies(event)
* ```
*/
declare function parseCookies(event: H3Event): Record<string, string>;
/**
* Get a cookie value by name.
* @param event {H3Event} H3 event or req passed by h3 handler
* @param name Name of the cookie to get
* @returns {*} Value of the cookie (String or undefined)
* ```ts
* const authorization = getCookie(request, 'Authorization')
* ```
*/
declare function getCookie(event: H3Event, name: string): string | undefined;
/**
* Set a cookie value by name.
* @param event {H3Event} H3 event or res passed by h3 handler
* @param name Name of the cookie to set
* @param value Value of the cookie to set
* @param serializeOptions {CookieSerializeOptions} Options for serializing the cookie
* ```ts
* setCookie(res, 'Authorization', '1234567')
* ```
*/
declare function setCookie(event: H3Event, name: string, value: string, serializeOptions?: CookieSerializeOptions): void;
/**
* Remove a cookie by name.
* @param event {H3Event} H3 event or res passed by h3 handler
* @param name Name of the cookie to delete
* @param serializeOptions {CookieSerializeOptions} Cookie options
* ```ts
* deleteCookie(res, 'SessionId')
* ```
*/
declare function deleteCookie(event: H3Event, name: string, serializeOptions?: CookieSerializeOptions): void;
/**
* Set-Cookie header field-values are sometimes comma joined in one string.
*
* This splits them without choking on commas that are within a single set-cookie field-value, such as in the Expires portion.
* This is uncommon, but explicitly allowed - see https://tools.ietf.org/html/rfc2616#section-4.2
* Node.js does this for every header _except_ set-cookie - see https://github.com/nodejs/node/blob/d5e363b77ebaf1caf67cd7528224b651c86815c1/lib/_http_incoming.js#L128
* Based on: https://github.com/google/j2objc/commit/16820fdbc8f76ca0c33472810ce0cb03d20efe25
* Credits to: https://github.com/tomball for original and https://github.com/chrusart for JavaScript implementation
* @source https://github.com/nfriedly/set-cookie-parser/blob/3eab8b7d5d12c8ed87832532861c1a35520cf5b3/lib/set-cookie.js#L144
*
* @internal
*/
declare function splitCookiesString(cookiesString: string | string[]): string[];
interface RequestFingerprintOptions {
/** @default SHA-1 */
hash?: false | "SHA-1";
/** @default `true` */
ip?: boolean;
/** @default `false` */
xForwardedFor?: boolean;
/** @default `false` */
method?: boolean;
/** @default `false` */
path?: boolean;
/** @default `false` */
userAgent?: boolean;
}
/**
*
* Get a unique fingerprint for the incoming request.
*
* @experimental Behavior of this utility might change in the future versions
*/
declare function getRequestFingerprint(event: H3Event, opts?: RequestFingerprintOptions): Promise<string | null>;
type Duplex = "half" | "full";
interface ProxyOptions {
headers?: RequestHeaders | HeadersInit;
fetchOptions?: RequestInit & {
duplex?: Duplex;
} & {
ignoreResponseError?: boolean;
};
fetch?: typeof fetch;
sendStream?: boolean;
streamRequest?: boolean;
cookieDomainRewrite?: string | Record<string, string>;
cookiePathRewrite?: string | Record<string, string>;
onResponse?: (event: H3Event, response: Response) => void;
}
/**
* Proxy the incoming request to a target URL.
*/
declare function proxyRequest(event: H3Event, target: string, opts?: ProxyOptions): Promise<any>;
/**
* Make a proxy request to a target URL and send the response back to the client.
*/
declare function sendProxy(event: H3Event, target: string, opts?: ProxyOptions): Promise<any>;
/**
* Get the request headers object without headers known to cause issues when proxying.
*/
declare function getProxyRequestHeaders(event: H3Event, opts?: {
host?: boolean;
}): any;
/**
* Make a fetch request with the event's context and headers.
*/
declare function fetchWithEvent<T = unknown, _R = any, F extends (req: RequestInfo | URL, opts?: any) => any = typeof fetch>(event: H3Event, req: RequestInfo | URL, init?: RequestInit & {
context?: H3EventContext;
}, options?: {
fetch: F;
}): unknown extends T ? ReturnType<F> : T;
type IterationSource<Val, Ret = Val> = Iterable<Val> | AsyncIterable<Val> | Iterator<Val, Ret | undefined> | AsyncIterator<Val, Ret | undefined> | (() => Iterator<Val, Ret | undefined> | AsyncIterator<Val, Ret | undefined>);
type SendableValue = string | Buffer | Uint8Array;
type IteratorSerializer<Value> = (value: Value) => SendableValue | undefined;
/**
* Directly send a response to the client.
*
* **Note:** This function should be used only when you want to send a response directly without using the `h3` event.
* Normally you can directly `return` a value inside event handlers.
*/
declare function send(event: H3Event, data?: any, type?: MimeType): Promise<void>;
/**
* Respond with an empty payload.
*
* Note that calling this function will close the connection and no other data can be sent to the client afterwards.
*
* @example
* export default defineEventHandler((event) => {
* return sendNoContent(event);
* });
* @example
* export default defineEventHandler((event) => {
* sendNoContent(event); // Close the connection
* console.log("This will not be executed");
* });
*
* @param event H3 event
* @param code status code to be send. By default, it is `204 No Content`.
*/
declare function sendNoContent(event: H3Event, code?: StatusCode): void;
/**
* Set the response status code and message.
*
* @example
* export default defineEventHandler((event) => {
* setResponseStatus(event, 404, "Not Found");
* return "Not Found";
* });
*/
declare function setResponseStatus(event: H3Event, code?: StatusCode, text?: string): void;
/**
* Get the current response status code.
*
* @example
* export default defineEventHandler((event) => {
* const status = getResponseStatus(event);
* return `Status: ${status}`;
* });
*/
declare function getResponseStatus(event: H3Event): number;
/**
* Get the current response status message.
*
* @example
* export default defineEventHandler((event) => {
* const statusText = getResponseStatusText(event);
* return `Status: ${statusText}`;
* });
*/
declare function getResponseStatusText(event: H3Event): string;
/**
* Set the response status code and message.
*/
declare function defaultContentType(event: H3Event, type?: MimeType): void;
/**
* Send a redirect response to the client.
*
* It adds the `location` header to the response and sets the status code to 302 by default.
*
* In the body, it sends a simple HTML page with a meta refresh tag to redirect the client in case the headers are ignored.
*
* @example
* export default defineEventHandler((event) => {
* return sendRedirect(event, "https://example.com");
* });
*
* @example
* export default defineEventHandler((event) => {
* return sendRedirect(event, "https://example.com", 301); // Permanent redirect
* });
*/
declare function sendRedirect(event: H3Event, location: string, code?: StatusCode): Promise<void>;
/**
* Get the response headers object.
*
* @example
* export default defineEventHandler((event) => {
* const headers = getResponseHeaders(event);
* });
*/
declare function getResponseHeaders(event: H3Event): ReturnType<H3Event["node"]["res"]["getHeaders"]>;
/**
* Get a response header by name.
*
* @example
* export default defineEventHandler((event) => {
* const contentType = getResponseHeader(event, "content-type"); // Get the response content-type header
* });
*/
declare function getResponseHeader(event: H3Event, name: HTTPHeaderName): ReturnType<H3Event["node"]["res"]["getHeader"]>;
/**
* Set the response headers.
*
* @example
* export default defineEventHandler((event) => {
* setResponseHeaders(event, {
* "content-type": "text/html",
* "cache-control": "no-cache",
* });
* });
*/
declare function setResponseHeaders(event: H3Event, headers: TypedHeaders): void;
/**
* Alias for `setResponseHeaders`.
*/
declare const setHeaders: typeof setResponseHeaders;
/**
* Set a response header by name.
*
* @example
* export default defineEventHandler((event) => {
* setResponseHeader(event, "content-type", "text/html");
* });
*/
declare function setResponseHeader<T extends HTTPHeaderName>(event: H3Event, name: T, value: TypedHeaders[Lowercase<T>]): void;
/**
* Alias for `setResponseHeader`.
*/
declare const setHeader: typeof setResponseHeader;
/**
* Append the response headers.
*
* @example
* export default defineEventHandler((event) => {
* appendResponseHeaders(event, {
* "content-type": "text/html",
* "cache-control": "no-cache",
* });
* });
*/
declare function appendResponseHeaders(event: H3Event, headers: TypedHeaders): void;
/**
* Alias for `appendResponseHeaders`.
*/
declare const appendHeaders: typeof appendResponseHeaders;
/**
* Append a response header by name.
*
* @example
* export default defineEventHandler((event) => {
* appendResponseHeader(event, "content-type", "text/html");
* });
*/
declare function appendResponseHeader<T extends HTTPHeaderName>(event: H3Event, name: T, value: TypedHeaders[Lowercase<T>]): void;
/**
* Alias for `appendResponseHeader`.
*/
declare const appendHeader: typeof appendResponseHeader;
/**
* Remove all response headers, or only those specified in the headerNames array.
*
* @example
* export default defineEventHandler((event) => {
* clearResponseHeaders(event, ["content-type", "cache-control"]); // Remove content-type and cache-control headers
* });
*
* @param event H3 event
* @param headerNames Array of header names to remove
*/
declare function clearResponseHeaders(event: H3Event, headerNames?: HTTPHeaderName[]): void;
/**
* Remove a response header by name.
*
* @example
* export default defineEventHandler((event) => {
* removeResponseHeader(event, "content-type"); // Remove content-type header
* });
*/
declare function removeResponseHeader(event: H3Event, name: HTTPHeaderName): void;
/**
* Checks if the data is a stream (Node.js Readable Stream, React Pipeable Stream, or Web Stream).
*/
declare function isStream(data: any): data is Readable | ReadableStream;
/**
* Checks if the data is a Response object.
*/
declare function isWebResponse(data: any): data is Response;
/**
* Send a stream response to the client.
*
* Note: You can directly `return` a stream value inside event handlers alternatively which is recommended.
*/
declare function sendStream(event: H3Event, stream: Readable | ReadableStream): Promise<void>;
/**
* Write `HTTP/1.1 103 Early Hints` to the client.
*/
declare function writeEarlyHints(event: H3Event, hints: string | string[] | Record<string, string | string[]>, cb?: () => void): void;
/**
* Send a Response object to the client.
*/
declare function sendWebResponse(event: H3Event, response: Response): void | Promise<void>;
/**
* Iterate a source of chunks and send back each chunk in order.
* Supports mixing async work together with emitting chunks.
*
* Each chunk must be a string or a buffer.
*
* For generator (yielding) functions, the returned value is treated the same as yielded values.
*
* @param event - H3 event
* @param iterable - Iterator that produces chunks of the response.
* @param serializer - Function that converts values from the iterable into stream-compatible values.
* @template Value - Test
*
* @example
* sendIterable(event, work());
* async function* work() {
* // Open document body
* yield "<!DOCTYPE html>\n<html><body><h1>Executing...</h1><ol>\n";
* // Do work ...
* for (let i = 0; i < 1000) {
* await delay(1000);
* // Report progress
* yield `<li>Completed job #`;
* yield i;
* yield `</li>\n`;
* }
* // Close out the report
* return `</ol></body></html>`;
* }
* async function delay(ms) {
* return new Promise(resolve => setTimeout(resolve, ms));
* }
*/
declare function sendIterable<Value = unknown, Return = unknown>(event: H3Event, iterable: IterationSource<Value, Return>, options?: {
serializer: IteratorSerializer<Value | Return>;
}): Promise<void>;
/**
* Make sure the status message is safe to use in a response.
*
* Allowed characters: horizontal tabs, spaces or visible ascii characters: https://www.rfc-editor.org/rfc/rfc7230#section-3.1.2
*/
declare function sanitizeStatusMessage(statusMessage?: string): string;
/**
* Make sure the status code is a valid HTTP status code.
*/
declare function sanitizeStatusCode(statusCode?: string | number, defaultStatusCode?: number): number;
interface EventStreamOptions {
/**
* Automatically close the writable stream when the request is closed
*
* Default is `true`
*/
autoclose?: boolean;
}
/**
* See https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#fields
*/
interface EventStreamMessage {
id?: string;
event?: string;
retry?: number;
data: string;
}
/**
* A helper class for [server sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#event_stream_format)
*/
declare class EventStream$1 {
private readonly _h3Event;
private readonly _transformStream;
private readonly _writer;
private readonly _encoder;
private _writerIsClosed;
private _paused;
private _unsentData;
private _disposed;
private _handled;
constructor(event: H3Event, opts?: EventStreamOptions);
/**
* Publish new event(s) for the client
*/
push(message: string): Promise<void>;
push(message: string[]): Promise<void>;
push(message: EventStreamMessage): Promise<void>;
push(message: EventStreamMessage[]): Promise<void>;
private _sendEvent;
private _sendEvents;
pause(): void;
get isPaused(): boolean;
resume(): Promise<void>;
flush(): Promise<void>;
/**
* Close the stream and the connection if the stream is being sent to the client
*/
close(): Promise<void>;
/**
* Triggers callback when the writable stream is closed.
* It is also triggered after calling the `close()` method.
*/
onClosed(cb: () => any): void;
send(): Promise<void>;
}
/**
* Initialize an EventStream instance for creating [server sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)
*
* @experimental This function is experimental and might be unstable in some environments.
*
* @example
*
* ```ts
* import { createEventStream, sendEventStream } from "h3";
*
* eventHandler((event) => {
* const eventStream = createEventStream(event);
*
* // Send a message every second
* const interval = setInterval(async () => {
* await eventStream.push("Hello world");
* }, 1000);
*
* // cleanup the interval and close the stream when the connection is terminated
* eventStream.onClosed(async () => {
* console.log("closing SSE...");
* clearInterval(interval);
* await eventStream.close();
* });
*
* return eventStream.send();
* });
* ```
*/
declare function createEventStream(event: H3Event, opts?: EventStreamOptions): EventStream$1;
type EventStream = ReturnType<typeof createEventStream>;
interface StaticAssetMeta {
type?: string;
etag?: string;
mtime?: number | string | Date;
path?: string;
size?: number;
encoding?: string;
}
interface ServeStaticOptions {
/**
* This function should resolve asset meta
*/
getMeta: (id: string) => StaticAssetMeta | undefined | Promise<StaticAssetMeta | undefined>;
/**
* This function should resolve asset content
*/
getContents: (id: string) => unknown | Promise<unknown>;
/**
* Map of supported encodings (compressions) and their file extensions.
*
* Each extension will be appended to the asset path to find the compressed version of the asset.
*
* @example { gzip: ".gz", br: ".br" }
*/
encodings?: Record<string, string>;
/**
* Default index file to serve when the path is a directory
*
* @default ["/index.html"]
*/
indexNames?: string[];
/**
* When set to true, the function will not throw 404 error when the asset meta is not found or meta validation failed
*/
fallthrough?: boolean;
}
/**
* Dynamically serve static assets based on the request path.
*/
declare function serveStatic(event: H3Event, options: ServeStaticOptions): Promise<void | false>;
/**
* Define WebSocket hooks.
*
* @see https://h3.unjs.io/guide/websocket
*/
declare function defineWebSocket(hooks: Partial<Hooks>): Partial<Hooks>;
/**
* Define WebSocket event handler.
*
* @see https://h3.unjs.io/guide/websocket
*/
declare function defineWebSocketHandler(hooks: Partial<Hooks>): EventHandler<EventHandlerRequest, never>;
/** @experimental */
type WebHandler = (request: Request, context?: Record<string, unknown>) => Promise<Response>;
/** @experimental */
declare function toWebHandler(app: App): WebHandler;
/** @experimental */
declare function fromWebHandler(handler: WebHandler): EventHandler<EventHandlerRequest, Promise<Response>>;
interface PlainRequest {
_eventOverrides?: Partial<H3Event>;
context?: Record<string, unknown>;
method: string;
path: string;
headers: HeadersInit;
body?: null | BodyInit;
}
interface PlainResponse {
status: number;
statusText: string;
headers: [string, string][];
body?: unknown;
}
type PlainHandler = (request: PlainRequest) => Promise<PlainResponse>;
/** @experimental */
declare function toPlainHandler(app: App): PlainHandler;
/** @experimental */
declare function fromPlainHandler(handler: PlainHandler): EventHandler<EventHandlerRequest, Promise<unknown>>;
export { H3Error, H3Event, H3Headers, H3Response, MIMES, appendCorsHeaders, appendCorsPreflightHeaders, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearResponseHeaders, clearSession, createApp, createAppEventHandler, createError, createEvent, createEventStream, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, defineRequestMiddleware, defineResponseMiddleware, defineWebSocket, defineWebSocketHandler, deleteCookie, dynamicEventHandler, eventHandler, fetchWithEvent, fromNodeMiddleware, fromPlainHandler, fromWebHandler, getCookie, getHeader, getHeaders, getMethod, getProxyRequestHeaders, getQuery, getRequestFingerprint, getRequestHeader, getRequestHeaders, getRequestHost, getRequestIP, getRequestPath, getRequestProtocol, getRequestURL, getRequestWebStream, getResponseHeader, getResponseHeaders, getResponseStatus, getResponseStatusText, getRouterParam, getRouterParams, getSession, getValidatedQuery, getValidatedRouterParams, handleCacheHeaders, handleCors, isCorsOriginAllowed, isError, isEvent, isEventHandler, isMethod, isPreflightRequest, isStream, isWebResponse, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readFormData, readMultipartFormData, readRawBody, readValidatedBody, removeResponseHeader, sanitizeStatusCode, sanitizeStatusMessage, sealSession, send, sendError, sendIterable, sendNoContent, sendProxy, sendRedirect, sendStream, sendWebResponse, serveStatic, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, setResponseStatus, splitCookiesString, toEventHandler, toNodeListener, toPlainHandler, toWebHandler, toWebRequest, unsealSession, updateSession, use, useBase, useSession, writeEarlyHints };
export type { AddRouteShortcuts, App, AppOptions, AppUse, CacheConditions, CreateRouterOptions, Duplex, DynamicEventHandler, Encoding, EventHandler, EventHandlerObject, EventHandlerRequest, EventHandlerResolver, EventHandlerResponse, EventStream, EventStreamMessage, EventStreamOptions, H3CorsOptions, H3EventContext, HTTPHeaderName, HTTPMethod, InferEventInput, InputLayer, InputStack, Layer, LazyEventHandler, Matcher, MimeType, MultiPartData, NodeEventContext, NodeListener, NodeMiddleware, NodePromisifiedHandler, PlainHandler, PlainRequest, PlainResponse, ProxyOptions, RequestFingerprintOptions, RequestHeaders, RouteNode, Router, RouterMethod, RouterUse, ServeStaticOptions, Session, SessionConfig, SessionData, SessionManager, Stack, StaticAssetMeta, StatusCode, TypedHeaders, ValidateFunction, ValidateResult, WebEventContext, WebHandler, WebSocketOptions, _RequestMiddleware, _ResponseMiddleware };