Socket
Socket
Sign inDemoInstall

h3

Package Overview
Dependencies
Maintainers
1
Versions
97
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

h3 - npm Package Compare versions

Comparing version 1.10.2 to 1.11.0

500

dist/index.d.ts
import { QueryObject } from 'ufo';
import { Hooks, AdapterOptions } from 'crossws';
import { IncomingMessage, ServerResponse, OutgoingMessage } from 'node:http';

@@ -133,2 +134,6 @@ export { IncomingMessage as NodeIncomingMessage, ServerResponse as NodeServerResponse } from 'node:http';

}
/**
* Create a session manager for the current request.
*
*/
declare function useSession<T extends SessionDataT = SessionDataT>(event: H3Event, config: SessionConfig): Promise<{

@@ -140,7 +145,22 @@ readonly id: string | undefined;

}>;
/**
* Get the session for the current request.
*/
declare function getSession<T extends SessionDataT = SessionDataT>(event: H3Event, 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, config: SessionConfig): Promise<string>;
/**
* Decrypt and verify the session data for the current request.
*/
declare function unsealSession(_event: H3Event, 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>;

@@ -165,2 +185,5 @@

}
/**
* Create a new h3 router instance.
*/
declare function createRouter(opts?: CreateRouterOptions): Router;

@@ -191,4 +214,11 @@

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;

@@ -203,2 +233,4 @@ }

onBeforeResponse?: _ResponseMiddleware<Request, Response> | _ResponseMiddleware<Request, Response>[];
/** @experimental */
websocket?: Partial<Hooks>;
handler: EventHandler<Request, Response>;

@@ -284,2 +316,3 @@ };

}
type WebSocketOptions = AdapterOptions;
interface AppOptions {

@@ -295,2 +328,3 @@ debug?: boolean;

}) => void | Promise<void>;
websocket?: WebSocketOptions;
}

@@ -302,3 +336,8 @@ interface App {

use: AppUse;
resolve: EventHandlerResolver;
readonly websocket: WebSocketOptions;
}
/**
* Create a new H3 app instance.
*/
declare function createApp(options?: AppOptions): App;

@@ -310,2 +349,18 @@ declare function use(app: App, arg1: string | EventHandler | InputLayer | InputLayer[], arg2?: Partial<InputLayer> | EventHandler | EventHandler[], arg3?: Partial<InputLayer>): App;

* 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.

@@ -325,2 +380,8 @@ * @param handler The event handler to use with the adapted path.

* 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

@@ -334,2 +395,8 @@ * @param encoding {Encoding} encoding="utf-8" - The character encoding to use.

* Reads request body and tries to safely parse using [destr](https://github.com/unjs/destr).
*
* @example
* export default defineEventHandler(async (event) => {
* const body = await readBody(event);
* });
*
* @param event H3 event passed by h3 handler

@@ -339,6 +406,2 @@ * @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
*
* ```ts
* const body = await readBody(event)
* ```
*/

@@ -350,2 +413,19 @@ declare function readBody<T, Event extends H3Event = H3Event, _T = InferEventInput<"body", Event, T>>(event: Event, options?: {

* 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.

@@ -356,14 +436,2 @@ * @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.

* @see {readBody}
*
* ```ts
* // With a custom validation function
* const body = await readValidatedBody(event, (body) => {
* return typeof body === "object" && body !== null
* })
*
* // With a zod schema
* import { z } from 'zod'
* const objectSchema = z.object()
* const body = await readValidatedBody(event, objectSchema.safeParse)
* ```
*/

@@ -373,20 +441,22 @@ 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 a 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.
*
* ```ts
* const formData = await readMultipartFormData(event)
* // The result could look like:
* // [
* // {
* // "data": "other",
* // "name": "baz",
* // },
* // {
* // "data": "something",
* // "name": "some-other-data",
* // },
* // ]
* ```
*/

@@ -396,11 +466,11 @@ 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.
*
* ```ts
* const eventHandler = event => {
* const formData = await readFormData(event)
* const email = formData.get("email")
* const password = formData.get("password")
* }
* ```
*/

@@ -445,12 +515,36 @@ declare function readFormData(event: H3Event): Promise<FormData>;

/**
* 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.
*/
declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
/**
* Get query the params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io).
*/
declare function getQuery<T, Event extends H3Event = H3Event, _T = Exclude<InferEventInput<"query", Event, T>, undefined>>(event: Event): _T;
/**
* Get the query param from the request URL parsed with [unjs/ufo](https://ufo.unjs.io) and validated with validate function.
*/
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`.
*/
declare function getRouterParams(event: H3Event, opts?: {
decode?: boolean;
}): NonNullable<H3Event["context"]["params"]>;
/**
* Get matched route params and validate with validate function.
*/
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.
*/
declare function getRouterParam(event: H3Event, name: string, opts?: {

@@ -463,11 +557,51 @@ decode?: boolean;

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`.
*
*/
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".
*/
declare function assertMethod(event: H3Event, expected: HTTPMethod | HTTPMethod[], allowHead?: boolean): void;
/**
* Get the request headers object.
*
* Array headers are joined with a comma.
*/
declare function getRequestHeaders(event: H3Event): RequestHeaders;
/**
* Alias for `getRequestHeaders`.
*/
declare const getHeaders: typeof getRequestHeaders;
/**
* Get a request header by name.
*/
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".
*/
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".
*/
declare function getRequestProtocol(event: H3Event, opts?: {

@@ -478,2 +612,9 @@ xForwardedProto?: boolean;

declare function getRequestPath(event: H3Event): string;
/**
* Generated 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.
*/
declare function getRequestURL(event: H3Event, opts?: {

@@ -483,3 +624,13 @@ xForwardedHost?: 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 if it exists.
*/
declare function getRequestIP(event: H3Event, opts?: {

@@ -494,5 +645,17 @@ /**

/**
* 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;

@@ -541,9 +704,12 @@

/**
* 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.
* 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
* 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
*/

@@ -566,3 +732,8 @@ declare function splitCookiesString(cookiesString: string | string[]): string[];

}
/** @experimental Behavior of this utility might change in the future versions */
/**
*
* 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>;

@@ -585,5 +756,17 @@

}
/**
* 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): 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 & {

@@ -595,5 +778,16 @@ context?: H3EventContext;

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.
* Normaly you can directly `return` a value inside event handlers.
*/
declare function send(event: H3Event, data?: any, type?: string): Promise<void>;
/**
* Respond with an empty payload.<br>
*
* Note that calling this function will close the connection and no other data can be sent to the client afterwards.

@@ -605,16 +799,65 @@ *

declare function sendNoContent(event: H3Event, code?: number): void;
/**
* Set the response status code and message.
*/
declare function setResponseStatus(event: H3Event, code?: number, text?: string): void;
/**
* Get the current response status code.
*/
declare function getResponseStatus(event: H3Event): number;
/**
* Get the current response status message.
*/
declare function getResponseStatusText(event: H3Event): string;
/**
* Set the response status code and message.
*/
declare function defaultContentType(event: H3Event, type?: string): 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.
*/
declare function sendRedirect(event: H3Event, location: string, code?: number): Promise<void>;
/**
* Get the response headers object.
*/
declare function getResponseHeaders(event: H3Event): ReturnType<H3Event["node"]["res"]["getHeaders"]>;
/**
* Alias for `getResponseHeaders`.
*/
declare function getResponseHeader(event: H3Event, name: HTTPHeaderName): ReturnType<H3Event["node"]["res"]["getHeader"]>;
/**
* Set the response headers.
*/
declare function setResponseHeaders(event: H3Event, headers: Partial<Record<HTTPHeaderName, Parameters<OutgoingMessage["setHeader"]>[1]>>): void;
/**
* Alias for `setResponseHeaders`.
*/
declare const setHeaders: typeof setResponseHeaders;
/**
* Set a response header by name.
*/
declare function setResponseHeader(event: H3Event, name: HTTPHeaderName, value: Parameters<OutgoingMessage["setHeader"]>[1]): void;
/**
* Alias for `setResponseHeader`.
*/
declare const setHeader: typeof setResponseHeader;
/**
* Append the response headers.
*/
declare function appendResponseHeaders(event: H3Event, headers: Record<string, string>): void;
/**
* Alias for `appendResponseHeaders`.
*/
declare const appendHeaders: typeof appendResponseHeaders;
/**
* Append a response header by name.
*/
declare function appendResponseHeader(event: H3Event, name: HTTPHeaderName, value: string): void;
/**
* Alias for `appendResponseHeader`.
*/
declare const appendHeader: typeof appendResponseHeader;

@@ -627,12 +870,165 @@ /**

declare function clearResponseHeaders(event: H3Event, headerNames?: string[]): void;
/**
* Remove a response header by name.
*/
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 toghether 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 {
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.
* It also triggers when the request connection has been closed by either the client or the server.
*/
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;
interface StaticAssetMeta {

@@ -674,4 +1070,20 @@ type?: string;

}
/**
* 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 */

@@ -704,2 +1116,2 @@ type WebHandler = (request: Request, context?: Record<string, unknown>) => Promise<Response>;

export { type AddRouteShortcuts, type App, type AppOptions, type AppUse, type CacheConditions, type CreateRouterOptions, type Duplex, type DynamicEventHandler, type Encoding, type EventHandler, type EventHandlerObject, type EventHandlerRequest, type EventHandlerResponse, type H3CorsOptions, H3Error, H3Event, type H3EventContext, H3Headers, H3Response, type HTTPHeaderName, type HTTPMethod, type InferEventInput, type InputLayer, type InputStack, type Layer, type LazyEventHandler, MIMES, type Matcher, type MultiPartData, type NodeEventContext, type NodeListener, type NodeMiddleware, type NodePromisifiedHandler, type PlainHandler, type PlainRequest, type PlainResponse, type ProxyOptions, type RequestFingerprintOptions, type RequestHeaders, type RouteNode, type Router, type RouterMethod, type RouterUse, type ServeStaticOptions, type Session, type SessionConfig, type SessionData, type Stack, type StaticAssetMeta, type ValidateFunction, type ValidateResult, type WebEventContext, type WebHandler, type _RequestMiddleware, type _ResponseMiddleware, appendCorsHeaders, appendCorsPreflightHeaders, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearResponseHeaders, clearSession, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, defineRequestMiddleware, defineResponseMiddleware, 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, 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, type App, type AppOptions, type AppUse, type CacheConditions, type CreateRouterOptions, type Duplex, type DynamicEventHandler, type Encoding, type EventHandler, type EventHandlerObject, type EventHandlerRequest, type EventHandlerResolver, type EventHandlerResponse, type H3CorsOptions, H3Error, H3Event, type H3EventContext, H3Headers, H3Response, type HTTPHeaderName, type HTTPMethod, type InferEventInput, type InputLayer, type InputStack, type Layer, type LazyEventHandler, MIMES, type Matcher, type MultiPartData, type NodeEventContext, type NodeListener, type NodeMiddleware, type NodePromisifiedHandler, type PlainHandler, type PlainRequest, type PlainResponse, type ProxyOptions, type RequestFingerprintOptions, type RequestHeaders, type RouteNode, type Router, type RouterMethod, type RouterUse, type ServeStaticOptions, type Session, type SessionConfig, type SessionData, type Stack, type StaticAssetMeta, type ValidateFunction, type ValidateResult, type WebEventContext, type WebHandler, type WebSocketOptions, type _RequestMiddleware, type _ResponseMiddleware, 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 };

28

package.json
{
"name": "h3",
"version": "1.10.2",
"version": "1.11.0",
"description": "Minimal H(TTP) framework built for high performance and portability.",

@@ -24,8 +24,9 @@ "repository": "unjs/h3",

"cookie-es": "^1.0.0",
"crossws": "^0.2.0",
"defu": "^6.1.4",
"destr": "^2.0.2",
"destr": "^2.0.3",
"iron-webcrypto": "^1.0.0",
"ohash": "^1.1.3",
"radix3": "^1.1.0",
"ufo": "^1.3.2",
"ufo": "^1.4.0",
"uncrypto": "^0.1.3",

@@ -37,6 +38,7 @@ "unenv": "^1.9.0"

"@types/express": "^4.17.21",
"@types/node": "^20.11.6",
"@types/node": "^20.11.19",
"@types/supertest": "^6.0.2",
"@vitest/coverage-v8": "^1.2.1",
"autocannon": "^7.14.0",
"@vitest/coverage-v8": "^1.3.1",
"autocannon": "^7.15.0",
"automd": "^0.3.5",
"changelogen": "^0.5.5",

@@ -49,5 +51,5 @@ "connect": "^3.7.0",

"jiti": "^1.21.0",
"listhen": "^1.5.6",
"node-fetch-native": "^1.6.1",
"prettier": "^3.2.4",
"listhen": "^1.7.2",
"node-fetch-native": "^1.6.2",
"prettier": "^3.2.5",
"react": "^18.2.0",

@@ -58,11 +60,11 @@ "react-dom": "^18.2.0",

"unbuild": "^2.0.0",
"vitest": "^1.2.1",
"vitest": "^1.3.1",
"zod": "^3.22.4"
},
"packageManager": "pnpm@8.14.3",
"packageManager": "pnpm@8.15.3",
"scripts": {
"build": "unbuild",
"dev": "vitest",
"lint": "eslint --cache --ext .ts,.js,.mjs,.cjs . && prettier -c src test playground examples",
"lint:fix": "eslint --cache --ext .ts,.js,.mjs,.cjs . --fix && prettier -c src test playground examples -w",
"lint": "eslint --cache --ext .ts,.js,.mjs,.cjs . && prettier -c src test playground examples docs",
"lint:fix": "eslint --cache --ext .ts,.js,.mjs,.cjs . --fix && prettier -c src test playground examples docs -w",
"play": "listhen -w ./playground/app.ts",

@@ -69,0 +71,0 @@ "profile": "0x -o -D .profile -P 'autocannon -c 100 -p 10 -d 40 http://localhost:$PORT' ./playground/server.cjs",

# H3
[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![bundle][bundle-src]][bundle-href]
[![Codecov][codecov-src]][codecov-href]
[![License][license-src]][license-href]
[![JSDocs][jsdocs-src]][jsdocs-href]
<!-- automd:badges -->
H3 (pronounced as /eɪtʃθriː/, like h-3) is a minimal h(ttp) framework built for high performance and portability.
[![npm version](https://flat.badgen.net/npm/v/h3)](https://npmjs.com/package/h3)
[![npm downloads](https://flat.badgen.net/npm/dm/h3)](https://npmjs.com/package/h3)
👉 [Online Playground](https://stackblitz.com/github/unjs/h3/tree/main/playground)
<!-- /automd -->
👉 [Online Examples Playground](https://stackblitz.com/github/unjs/h3/tree/main/examples)
H3 (pronounced as /eɪtʃθriː/, like h-3) is a minimal h(ttp) framework built for high performance and portability.
## Features
👉 [Documentation](https://h3.unjs.io)
✔️ &nbsp;**Portable:** Works perfectly in Serverless, Workers, and Node.js
## Contribution
✔️ &nbsp;**Minimal:** Small and tree-shakable
✔️ &nbsp;**Modern:** Native promise support
✔️ &nbsp;**Extendable:** Ships with a set of composable utilities but can be extended
✔️ &nbsp;**Router:** Super fast route matching using [unjs/radix3](https://github.com/unjs/radix3)
✔️ &nbsp;**Compatible:** Compatibility layer with node/connect/express middleware
## Install
```bash
# Using npm
npm install h3
# Using yarn
yarn add h3
# Using pnpm
pnpm add h3
```
<details>
<summary>Using Nightly Releases</summary>
<summary>Local development</summary>
If you are directly using `h3` as a dependency:
- Clone this repository
- Install the latest LTS version of [Node.js](https://nodejs.org/en/)
- Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable`
- Install dependencies using `pnpm install`
- Run tests using `pnpm dev` or `pnpm test`
```json
{
"dependencies": {
"h3": "npm:h3-nightly@latest"
}
}
```
If you are using a framework ([Nuxt](https://nuxt.com/) or [Nitro](https://nitro.unjs.io/)) that is using `h3`:
pnpm and yarn:
```json
{
"resolutions": {
"h3": "npm:h3-nightly@latest"
}
}
```
npm:
```json
{
"overrides": {
"h3": "npm:h3-nightly@latest"
}
}
```
**Note:** Make sure to recreate lockfile and `node_modules` after reinstall to avoid hoisting issues.
</details>
## Usage
<!-- /automd -->
```ts
import { createServer } from "node:http";
import { createApp, eventHandler, toNodeListener } from "h3";
## License
const app = createApp();
app.use(
"/",
eventHandler(() => "Hello world!"),
);
<!-- automd:contributors license=MIT author="pi0" -->
createServer(toNodeListener(app)).listen(process.env.PORT || 3000);
```
Published under the [MIT](https://github.com/unjs/h3/blob/main/LICENSE) license.
Made by [@pi0](https://github.com/pi0) and [community](https://github.com/unjs/h3/graphs/contributors) 💛
<br><br>
<a href="https://github.com/unjs/h3/graphs/contributors">
<img src="https://contrib.rocks/image?repo=unjs/h3" />
</a>
Example using <a href="https://github.com/unjs/listhen">listhen</a> for an elegant listener:
<!-- /automd -->
```ts
import { createApp, eventHandler, toNodeListener } from "h3";
import { listen } from "listhen";
<!-- automd:with-automd -->
const app = createApp();
app.use(
"/",
eventHandler(() => "Hello world!"),
);
---
listen(toNodeListener(app));
```
_🤖 auto updated with [automd](https://automd.unjs.io)_
## Router
The `app` instance created by `h3` uses a middleware stack (see [how it works](./src/app.ts)) with the ability to match route prefix and apply matched middleware.
To opt-in using a more advanced and convenient routing system, we can create a router instance and register it to app instance.
```ts
import { createApp, eventHandler, createRouter } from "h3";
const app = createApp();
const router = createRouter()
.get(
"/",
eventHandler(() => "Hello World!"),
)
.get(
"/hello/:name",
eventHandler((event) => `Hello ${event.context.params.name}!`),
);
app.use(router);
```
**Tip:** We can register the same route more than once with different methods.
Routes are internally stored in a [Radix Tree](https://en.wikipedia.org/wiki/Radix_tree) and matched using [unjs/radix3](https://github.com/unjs/radix3).
For using nested routers, see [this example](./examples/nested-router.ts)
## More app usage examples
```js
// Handle can directly return object or Promise<object> for JSON response
app.use(
"/api",
eventHandler((event) => ({ url: event.node.req.url })),
);
// We can have better matching other than quick prefix match
app.use(
"/odd",
eventHandler(() => "Is odd!"),
{ match: (url) => url.substr(1) % 2 },
);
// Handle can directly return string for HTML response
app.use(eventHandler(() => "<h1>Hello world!</h1>"));
// We can chain calls to .use()
app
.use(
"/1",
eventHandler(() => "<h1>Hello world!</h1>"),
)
.use(
"/2",
eventHandler(() => "<h1>Goodbye!</h1>"),
);
// We can proxy requests and rewrite cookie's domain and path
app.use(
"/api",
eventHandler((event) =>
proxyRequest(event, "https://example.com", {
// f.e. keep one domain unchanged, rewrite one domain and remove other domains
cookieDomainRewrite: {
"example.com": "example.com",
"example.com": "somecompany.co.uk",
"*": "",
},
cookiePathRewrite: {
"/": "/api",
},
}),
),
);
// Legacy middleware with 3rd argument are automatically promisified
app.use(
fromNodeMiddleware((req, res, next) => {
req.setHeader("x-foo", "bar");
next();
}),
);
// Lazy loaded routes using { lazy: true }
app.use("/big", () => import("./big-handler"), { lazy: true });
```
## Utilities
H3 has a concept of composable utilities that accept `event` (from `eventHandler((event) => {})`) as their first argument. This has several performance benefits over injecting them to `event` or `app` instances in global middleware commonly used in Node.js frameworks, such as Express. This concept means only required code is evaluated and bundled, and the rest of the utilities can be tree-shaken when not used.
👉 You can check list of exported built-in utils from [JSDocs Documentation](https://www.jsdocs.io/package/h3#package-functions).
#### Body
- `readRawBody(event, encoding?)`
- `readBody(event)`
- `readValidatedBody(event, validate)`
- `readMultipartFormData(event)`
#### Request
- `getQuery(event)`
- `getValidatedQuery(event, validate)`
- `getRouterParams(event, { decode? })`
- `getRouterParam(event, name, { decode? })`
- `getValidatedRouterParams(event, validate, { decode? })`
- `getMethod(event, default?)`
- `isMethod(event, expected, allowHead?)`
- `assertMethod(event, expected, allowHead?)`
- `getRequestHeaders(event)` (alias: `getHeaders`)
- `getRequestHeader(event, name)` (alias: `getHeader`)
- `getRequestURL(event)`
- `getRequestHost(event)`
- `getRequestProtocol(event)`
- `getRequestPath(event)`
- `getRequestIP(event, { xForwardedFor: boolean })`
#### Response
- `send(event, data, type?)`
- `sendNoContent(event, code = 204)`
- `setResponseStatus(event, status)`
- `getResponseStatus(event)`
- `getResponseStatusText(event)`
- `getResponseHeaders(event)`
- `getResponseHeader(event, name)`
- `setResponseHeaders(event, headers)` (alias: `setHeaders`)
- `setResponseHeader(event, name, value)` (alias: `setHeader`)
- `appendResponseHeaders(event, headers)` (alias: `appendHeaders`)
- `appendResponseHeader(event, name, value)` (alias: `appendHeader`)
- `defaultContentType(event, type)`
- `sendRedirect(event, location, code=302)`
- `isStream(data)`
- `sendStream(event, data)`
- `writeEarlyHints(event, links, callback)`
#### Sanitize
- `sanitizeStatusMessage(statusMessage)`
- `sanitizeStatusCode(statusCode, default = 200)`
#### Error
- `sendError(event, error, debug?)`
- `createError({ statusCode, statusMessage, data? })`
#### Route
- `useBase(base, handler)`
#### Proxy
- `sendProxy(event, { target, ...options })`
- `proxyRequest(event, { target, ...options })`
- `fetchWithEvent(event, req, init, { fetch? }?)`
- `getProxyRequestHeaders(event)`
#### Cookie
- `parseCookies(event)`
- `getCookie(event, name)`
- `setCookie(event, name, value, opts?)`
- `deleteCookie(event, name, opts?)`
- `splitCookiesString(cookiesString)`
#### Session
- `useSession(event, config = { password, maxAge?, name?, cookie?, seal?, crypto? })`
- `getSession(event, config)`
- `updateSession(event, config, update)`
- `sealSession(event, config)`
- `unsealSession(event, config, sealed)`
- `clearSession(event, config)`
#### Cache
- `handleCacheHeaders(event, opts)`
#### Cors
- `handleCors(options)` (see [h3-cors](https://github.com/NozomuIkuta/h3-cors) for more detail about options)
- `isPreflightRequest(event)`
- `isCorsOriginAllowed(event)`
- `appendCorsHeaders(event, options)` (see [h3-cors](https://github.com/NozomuIkuta/h3-cors) for more detail about options)
- `appendCorsPreflightHeaders(event, options)` (see [h3-cors](https://github.com/NozomuIkuta/h3-cors) for more detail about options)
## Community Packages
You can use more H3 event utilities made by the community.
Please check their READMEs for more details.
PRs are welcome to add your packages.
- [h3-typebox](https://github.com/kevinmarrec/h3-typebox)
- `validateBody(event, schema)`
- `validateQuery(event, schema)`
- [h3-zod](https://github.com/wobsoriano/h3-zod)
- `useValidatedBody(event, schema)`
- `useValidatedQuery(event, schema)`
- [h3-valibot](https://github.com/intevel/h3-valibot)
- `useValidateBody(event, schema)`
- `useValidateParams(event, schema)`
- [h3-compression](https://github.com/CodeDredd/h3-compression)
- `useGZipCompression(event, response)`
- `useDeflateCompression(event, response)`
- `useBrotliCompression(event, response)`
- `useCompression(event, response)`
- `useGZipCompressionStream(event, response)`
- `useDeflateCompressionStream(event, response)`
- `useCompressionStream(event, response)`
- [@intlify/h3](https://github.com/intlify/h3)
- `defineI18nMiddleware(options)`
- `useTranslation(event)`
- `getHeaderLocale(event, options)`
- `getHeaderLocales(event, options)`
- `getCookieLocale(event, options)`
- `setCookieLocale(event, options)`
- `getPathLocale(event, options)`
- `getQueryLocale(event, options)`
## License
MIT
<!-- Badges -->
[npm-version-src]: https://img.shields.io/npm/v/h3?style=flat&colorA=18181B&colorB=F0DB4F
[npm-version-href]: https://npmjs.com/package/h3
[npm-downloads-src]: https://img.shields.io/npm/dm/h3?style=flat&colorA=18181B&colorB=F0DB4F
[npm-downloads-href]: https://npmjs.com/package/h3
[codecov-src]: https://img.shields.io/codecov/c/gh/unjs/h3/main?style=flat&colorA=18181B&colorB=F0DB4F
[codecov-href]: https://codecov.io/gh/unjs/h3
[bundle-src]: https://img.shields.io/bundlephobia/minzip/h3?style=flat&colorA=18181B&colorB=F0DB4F
[bundle-href]: https://bundlephobia.com/result?p=h3
[license-src]: https://img.shields.io/github/license/unjs/h3.svg?style=flat&colorA=18181B&colorB=F0DB4F
[license-href]: https://github.com/unjs/h3/blob/main/LICENSE
[jsdocs-src]: https://img.shields.io/badge/jsDocs.io-reference-18181B?style=flat&colorA=18181B&colorB=F0DB4F
[jsdocs-href]: https://www.jsdocs.io/package/h3
<!-- /automd -->

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc