Socket
Socket
Sign inDemoInstall

h3

Package Overview
Dependencies
Maintainers
1
Versions
98
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 0.4.2 to 0.5.0

253

dist/index.d.ts

@@ -1,16 +0,51 @@

import { IncomingMessage, ServerResponse } from 'http';
import http from 'http';
import { CookieSerializeOptions } from 'cookie-es';
import * as ufo from 'ufo';
declare type Encoding = false | 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'ucs2' | 'ucs-2' | 'base64' | 'latin1' | 'binary' | 'hex';
interface H3Event {
'__is_event__': true;
event: H3Event;
req: IncomingMessage;
res: ServerResponse;
/**
* Request params only filled with h3 Router handlers
*/
params?: Record<string, any>;
}
declare type CompatibilityEvent = H3Event | IncomingMessage | ServerResponse;
declare type _JSONValue<T = string | number | boolean> = T | T[] | Record<string, T>;
declare type JSONValue = _JSONValue<_JSONValue>;
declare type H3Response = void | JSONValue | Buffer;
interface EventHandler {
'__is_handler__'?: true;
(event: CompatibilityEvent): H3Response | Promise<H3Response>;
}
declare function defineEventHandler(handler: EventHandler): EventHandler;
declare function defineLazyEventHandler(factory: () => EventHandler | Promise<EventHandler>): EventHandler;
declare function isEventHandler(input: any): input is EventHandler;
declare type CompatibilityEventHandler = EventHandler | Handler | Middleware;
declare function toEventHandler(handler: CompatibilityEventHandler): EventHandler;
declare function createEvent(req: http.IncomingMessage, res: http.ServerResponse): CompatibilityEvent;
declare function isEvent(input: any): input is H3Event;
declare type Handle<T = any, ReqT = {}> = (req: IncomingMessage & ReqT, res: ServerResponse) => T;
declare type PHandle = Handle<Promise<any>>;
interface IncomingMessage extends http.IncomingMessage {
originalUrl?: string;
event: H3Event;
req: H3Event['req'];
res: H3Event['res'];
}
interface ServerResponse extends http.ServerResponse {
event: H3Event;
res: H3Event['res'];
req: http.ServerResponse['req'] & {
event: H3Event;
originalUrl?: string;
};
}
declare type Handler<T = any, ReqT = {}> = (req: IncomingMessage & ReqT, res: ServerResponse) => T;
declare type PromisifiedHandler = Handler<Promise<any>>;
declare type Middleware = (req: IncomingMessage, res: ServerResponse, next: (err?: Error) => any) => any;
declare type LazyHandle = () => Handle | Promise<Handle>;
declare const defineHandle: <T>(handler: Handle<T, {}>) => Handle<T, {}>;
declare const defineMiddleware: (middleware: Middleware) => Middleware;
declare function promisifyHandle(handle: Handle | Middleware): PHandle;
declare function callHandle(handle: Middleware, req: IncomingMessage, res: ServerResponse): Promise<unknown>;
declare function lazyHandle(handle: LazyHandle, promisify?: boolean): PHandle;
declare function useBase(base: string, handle: PHandle): PHandle;
declare type LazyHandler = () => Handler | Promise<Handler>;
declare type Encoding = false | 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'ucs2' | 'ucs-2' | 'base64' | 'latin1' | 'binary' | 'hex';
declare type HTTPMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE';

@@ -20,3 +55,3 @@ interface Layer {

match?: Matcher;
handle: Handle;
handler: EventHandler;
}

@@ -27,19 +62,20 @@ declare type Stack = Layer[];

match?: Matcher;
handle: Handle | LazyHandle;
handler: Handler | LazyHandler;
lazy?: boolean;
/**
* @deprecated
*/
promisify?: boolean;
}
declare type InputStack = InputLayer[];
declare type Matcher = (url: string, req?: IncomingMessage) => boolean;
declare type Matcher = (url: string, event?: CompatibilityEvent) => boolean;
interface AppUse {
(route: string | string[], handle: Middleware | Middleware[], options?: Partial<InputLayer>): App;
(route: string | string[], handle: Handle | Handle[], options?: Partial<InputLayer>): App;
(handle: Middleware | Middleware[], options?: Partial<InputLayer>): App;
(handle: Handle | Handle[], options?: Partial<InputLayer>): App;
(route: string | string[], handler: CompatibilityEventHandler | CompatibilityEventHandler[], options?: Partial<InputLayer>): App;
(handler: CompatibilityEventHandler | CompatibilityEventHandler[], options?: Partial<InputLayer>): App;
(options: InputLayer): App;
}
interface App {
(req: IncomingMessage, res: ServerResponse): Promise<any>;
declare type NodeHandler = (req: http.IncomingMessage, res: http.ServerResponse) => void | Promise<void>;
interface App extends NodeHandler {
stack: Stack;
_handle: PHandle;
handler: EventHandler;
use: AppUse;

@@ -49,7 +85,7 @@ }

debug?: boolean;
onError?: (error: Error, req: IncomingMessage, res: ServerResponse) => any;
onError?: (error: Error, event: CompatibilityEvent) => any;
}
declare function createApp(options?: AppOptions): App;
declare function use(app: App, arg1: string | Handle | InputLayer | InputLayer[], arg2?: Handle | Partial<InputLayer> | Handle[] | Middleware | Middleware[], arg3?: Partial<InputLayer>): App;
declare function createHandle(stack: Stack, options: AppOptions): PHandle;
declare function use(app: App, arg1: string | Handler | InputLayer | InputLayer[], arg2?: Handler | Partial<InputLayer> | Handler[] | Middleware | Middleware[], arg3?: Partial<InputLayer>): App;
declare function createAppEventHandler(stack: Stack, options: AppOptions): EventHandler;

@@ -83,3 +119,3 @@ /**

*
* @param res {ServerResponse} The ServerResponse object is passed as the second parameter in the handler function
@param event {CompatibilityEvent} H3 event or req passed by h3 handler
* @param error {H3Error|Error} Raised error

@@ -89,13 +125,20 @@ * @param debug {Boolean} Whether application is in debug mode.<br>

*/
declare function sendError(res: ServerResponse, error: Error | H3Error, debug?: boolean): void;
declare function sendError(event: CompatibilityEvent, error: Error | H3Error, debug?: boolean): void;
declare const RawBodySymbol: unique symbol;
interface _IncomingMessage extends IncomingMessage {
[RawBodySymbol]?: Promise<Buffer>;
ParsedBodySymbol?: any;
body?: any;
}
declare const defineHandler: <T>(handler: Handler<T, {}>) => Handler<T, {}>;
/** @deprecated Use defineHandler */
declare const defineHandle: <T>(handler: Handler<T, {}>) => Handler<T, {}>;
declare const defineMiddleware: (middleware: Middleware) => Middleware;
declare function promisifyHandler(handler: Handler | Middleware): PromisifiedHandler;
/** @deprecated Use defineHandler */
declare const promisifyHandle: typeof promisifyHandler;
declare function callHandler(handler: Middleware, req: IncomingMessage, res: ServerResponse): Promise<unknown>;
declare function defineLazyHandler(handler: LazyHandler, promisify?: boolean): PromisifiedHandler;
/** @deprecated Use defineLazyHandler */
declare const lazyHandle: typeof defineLazyHandler;
declare function useBase(base: string, handler: PromisifiedHandler): PromisifiedHandler;
/**
* Reads body of the request and returns encoded raw string (default) or `Buffer` if encoding if falsy.
* @param req {IncomingMessage} An IncomingMessage object is created by [http.Server](https://nodejs.org/api/http.html#http_class_http_server)
* @param event {CompatibilityEvent} H3 event or req passed by h3 handler
* @param encoding {Encoding} encoding="utf-8" - The character encoding to use.

@@ -105,6 +148,6 @@ *

*/
declare function useRawBody(req: _IncomingMessage, encoding?: Encoding): Encoding extends false ? Buffer : Promise<string>;
declare function useRawBody(event: CompatibilityEvent, encoding?: Encoding): Encoding extends false ? Buffer : Promise<string | Buffer>;
/**
* Reads request body and try to safely parse using [destr](https://github.com/unjs/destr)
* @param req {IncomingMessage} An IncomingMessage object created by [http.Server](https://nodejs.org/api/http.html#http_class_http_server)
* @param event {CompatibilityEvent} H3 event or req passed by h3 handler
* @param encoding {Encoding} encoding="utf-8" - The character encoding to use.

@@ -118,3 +161,3 @@ *

*/
declare function useBody<T = any>(req: _IncomingMessage): Promise<T>;
declare function useBody<T = any>(event: CompatibilityEvent): Promise<T>;

@@ -127,90 +170,4 @@ declare const MIMES: {

/**
* Additional serialization options
*/
interface CookieSerializeOptions {
/**
* Specifies the value for the {@link https://tools.ietf.org/html/rfc6265#section-5.2.3|Domain Set-Cookie attribute}. By default, no
* domain is set, and most clients will consider the cookie to apply to only
* the current domain.
*/
domain?: string;
/**
* Specifies a function that will be used to encode a cookie's value. Since
* value of a cookie has a limited character set (and must be a simple
* string), this function can be used to encode a value into a string suited
* for a cookie's value.
*
* The default function is the global `encodeURIComponent`, which will
* encode a JavaScript string into UTF-8 byte sequences and then URL-encode
* any that fall outside of the cookie range.
*/
encode?(value: string): string;
/**
* Specifies the `Date` object to be the value for the {@link https://tools.ietf.org/html/rfc6265#section-5.2.1|`Expires` `Set-Cookie` attribute}. By default,
* no expiration is set, and most clients will consider this a "non-persistent cookie" and will delete
* it on a condition like exiting a web browser application.
*
* *Note* the {@link https://tools.ietf.org/html/rfc6265#section-5.3|cookie storage model specification}
* states that if both `expires` and `maxAge` are set, then `maxAge` takes precedence, but it is
* possible not all clients by obey this, so if both are set, they should
* point to the same date and time.
*/
expires?: Date;
/**
* Specifies the boolean value for the {@link https://tools.ietf.org/html/rfc6265#section-5.2.6|`HttpOnly` `Set-Cookie` attribute}.
* When truthy, the `HttpOnly` attribute is set, otherwise it is not. By
* default, the `HttpOnly` attribute is not set.
*
* *Note* be careful when setting this to true, as compliant clients will
* not allow client-side JavaScript to see the cookie in `document.cookie`.
*/
httpOnly?: boolean;
/**
* Specifies the number (in seconds) to be the value for the `Max-Age`
* `Set-Cookie` attribute. The given number will be converted to an integer
* by rounding down. By default, no maximum age is set.
*
* *Note* the {@link https://tools.ietf.org/html/rfc6265#section-5.3|cookie storage model specification}
* states that if both `expires` and `maxAge` are set, then `maxAge` takes precedence, but it is
* possible not all clients by obey this, so if both are set, they should
* point to the same date and time.
*/
maxAge?: number;
/**
* Specifies the value for the {@link https://tools.ietf.org/html/rfc6265#section-5.2.4|`Path` `Set-Cookie` attribute}.
* By default, the path is considered the "default path".
*/
path?: string;
/**
* Specifies the boolean or string to be the value for the {@link https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7|`SameSite` `Set-Cookie` attribute}.
*
* - `true` will set the `SameSite` attribute to `Strict` for strict same
* site enforcement.
* - `false` will not set the `SameSite` attribute.
* - `'lax'` will set the `SameSite` attribute to Lax for lax same site
* enforcement.
* - `'strict'` will set the `SameSite` attribute to Strict for strict same
* site enforcement.
* - `'none'` will set the SameSite attribute to None for an explicit
* cross-site cookie.
*
* More information about the different enforcement levels can be found in {@link https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7|the specification}.
*
* *note* This is an attribute that has not yet been fully standardized, and may change in the future. This also means many clients may ignore this attribute until they understand it.
*/
sameSite?: true | false | 'lax' | 'strict' | 'none';
/**
* Specifies the boolean value for the {@link https://tools.ietf.org/html/rfc6265#section-5.2.5|`Secure` `Set-Cookie` attribute}. When truthy, the
* `Secure` attribute is set, otherwise it is not. By default, the `Secure` attribute is not set.
*
* *Note* be careful when setting this to `true`, as compliant clients will
* not send the cookie back to the server in the future if the browser does
* not have an HTTPS connection.
*/
secure?: boolean;
}
/**
* Parse the request to get HTTP Cookie header string and returning an object of all cookie name-value pairs.
* @param req {IncomingMessage} An IncomingMessage object created by [http.Server](https://nodejs.org/api/http.html#http_class_http_server)
* @param event {CompatibilityEvent} H3 event or req passed by h3 handler
* @returns Object of cookie name-value pairs

@@ -221,6 +178,6 @@ * ```ts

*/
declare function useCookies(req: IncomingMessage): Record<string, string>;
declare function useCookies(event: CompatibilityEvent): Record<string, string>;
/**
* Get a cookie value by name.
* @param req {IncomingMessage} An IncomingMessage object created by [http.Server](https://nodejs.org/api/http.html#http_class_http_server)
* @param event {CompatibilityEvent} H3 event or req passed by h3 handler
* @param name Name of the cookie to get

@@ -232,6 +189,6 @@ * @returns {*} Value of the cookie (String or undefined)

*/
declare function useCookie(req: IncomingMessage, name: string): string | undefined;
declare function useCookie(event: CompatibilityEvent, name: string): string | undefined;
/**
* Set a cookie value by name.
* @param res {ServerResponse} A ServerResponse object created by [http.Server](https://nodejs.org/api/http.html#http_class_http_server)
* @param event {CompatibilityEvent} H3 event or res passed by h3 handler
* @param name Name of the cookie to set

@@ -244,6 +201,6 @@ * @param value Value of the cookie to set

*/
declare function setCookie(res: ServerResponse, name: string, value: string, serializeOptions?: CookieSerializeOptions): void;
declare function setCookie(event: CompatibilityEvent, name: string, value: string, serializeOptions?: CookieSerializeOptions): void;
/**
* Set a cookie value by name.
* @param res {ServerResponse} A ServerResponse object created by [http.Server](https://nodejs.org/api/http.html#http_class_http_server)
* @param event {CompatibilityEvent} H3 event or res passed by h3 handler
* @param name Name of the cookie to delete

@@ -255,30 +212,26 @@ * @param serializeOptions {CookieSerializeOptions} Cookie options

*/
declare function deleteCookie(res: ServerResponse, name: string, serializeOptions?: CookieSerializeOptions): void;
declare function deleteCookie(event: CompatibilityEvent, name: string, serializeOptions?: CookieSerializeOptions): void;
declare type HTTPMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE';
declare function useQuery(event: CompatibilityEvent): ufo.QueryObject;
declare function useMethod(event: CompatibilityEvent, defaultMethod?: HTTPMethod): HTTPMethod;
declare function isMethod(event: CompatibilityEvent, expected: HTTPMethod | HTTPMethod[], allowHead?: boolean): boolean;
declare function assertMethod(event: CompatibilityEvent, expected: HTTPMethod | HTTPMethod[], allowHead?: boolean): void;
declare function useQuery(req: IncomingMessage): ufo.QueryObject;
declare function useMethod(req: IncomingMessage, defaultMethod?: HTTPMethod): HTTPMethod;
declare function isMethod(req: IncomingMessage, expected: HTTPMethod | HTTPMethod[], allowHead?: boolean): boolean;
declare function assertMethod(req: IncomingMessage, expected: HTTPMethod | HTTPMethod[], allowHead?: boolean): void;
declare function send(event: CompatibilityEvent, data: any, type?: string): Promise<void>;
declare function defaultContentType(event: CompatibilityEvent, type?: string): void;
declare function sendRedirect(event: CompatibilityEvent, location: string, code?: number): Promise<void>;
declare function appendHeader(event: CompatibilityEvent, name: string, value: string): void;
declare function isStream(data: any): any;
declare function sendStream(event: CompatibilityEvent, data: any): Promise<void>;
declare function send(res: ServerResponse, data: any, type?: string): Promise<void>;
declare function defaultContentType(res: ServerResponse, type?: string): void;
declare function sendRedirect(res: ServerResponse, location: string, code?: number): Promise<void>;
declare function appendHeader(res: ServerResponse, name: string, value: string): void;
declare function isStream(data: any): boolean;
declare function sendStream(res: ServerResponse, data: any): Promise<unknown>;
declare type RouterMethod = Lowercase<HTTPMethod>;
declare type HandleWithParams = Handle<any, {
params: Record<string, string>;
}>;
declare type AddWithMethod = (path: string, handle: HandleWithParams) => Router;
declare type AddRouteShortcuts = Record<Lowercase<HTTPMethod>, AddWithMethod>;
declare type RouterUse = (path: string, handler: CompatibilityEventHandler, method?: RouterMethod) => Router;
declare type AddRouteShortcuts = Record<RouterMethod, RouterUse>;
interface Router extends AddRouteShortcuts {
add: (path: string, handle: HandleWithParams, method?: RouterMethod | 'all') => Router;
handle: Handle;
add: RouterUse;
use: RouterUse;
handler: EventHandler;
}
declare function createRouter(): Router;
export { AddRouteShortcuts, AddWithMethod, App, AppOptions, AppUse, H3Error, Handle, HandleWithParams, InputLayer, InputStack, Layer, LazyHandle, MIMES, Matcher, Middleware, PHandle, Router, RouterMethod, Stack, appendHeader, assertMethod, callHandle, createApp, createError, createHandle, createRouter, defaultContentType, defineHandle, defineMiddleware, deleteCookie, isMethod, isStream, lazyHandle, promisifyHandle, send, sendError, sendRedirect, sendStream, setCookie, use, useBase, useBody, useCookie, useCookies, useMethod, useQuery, useRawBody };
export { AddRouteShortcuts, App, AppOptions, AppUse, CompatibilityEvent, CompatibilityEventHandler, EventHandler, H3Error, H3Event, H3Response, InputLayer, InputStack, JSONValue, Layer, MIMES, Matcher, NodeHandler, Router, RouterMethod, RouterUse, Stack, _JSONValue, appendHeader, assertMethod, callHandler, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineHandle, defineHandler, defineLazyEventHandler, defineLazyHandler, defineMiddleware, deleteCookie, isEvent, isEventHandler, isMethod, isStream, lazyHandle, promisifyHandle, promisifyHandler, send, sendError, sendRedirect, sendStream, setCookie, toEventHandler, use, useBase, useBody, useCookie, useCookies, useMethod, useQuery, useRawBody };
{
"name": "h3",
"version": "0.4.2",
"version": "0.5.0",
"description": "Tiny JavaScript Server",

@@ -50,4 +50,5 @@ "repository": "unjs/h3",

"build": "unbuild",
"dev": "jiti ./playground/index.ts",
"dev": "vitest",
"lint": "eslint --ext ts,mjs,cjs .",
"play": "jiti ./playground/index.ts",
"profile": "0x -o -D .profile -P 'autocannon -c 100 -p 10 -d 40 http://localhost:$PORT' ./playground/server.cjs",

@@ -57,3 +58,3 @@ "release": "pnpm lint && pnpm test && pnpm build && standard-version && pnpm publish && git push --follow-tags",

},
"readme": "[![npm downloads](https://img.shields.io/npm/dm/h3.svg?style=flat-square)](https://npmjs.com/package/h3)\n[![version](https://img.shields.io/npm/v/h3/latest.svg?style=flat-square)](https://npmjs.com/package/h3)\n[![bundlephobia](https://img.shields.io/bundlephobia/min/h3/latest.svg?style=flat-square)](https://bundlephobia.com/result?p=h3)\n[![build status](https://img.shields.io/github/workflow/status/unjs/h3/ci/main?style=flat-square)](https://github.com/unjs/h3/actions)\n[![coverage](https://img.shields.io/codecov/c/gh/unjs/h3/main?style=flat-square)](https://codecov.io/gh/unjs/h3)\n[![jsDocs.io](https://img.shields.io/badge/jsDocs.io-reference-blue?style=flat-square)](https://www.jsdocs.io/package/h3)\n\n> H3 is a minimal h(ttp) framework built for high performance and portability\n\n<!-- ![h3 - Tiny JavaScript Server](.github/banner.svg) -->\n\n## Features\n\n✔️ &nbsp;**Portable:** Works perfectly in Serverless, Workers, and Node.js\n\n✔️ &nbsp;**Compatible:** Support connect/express middleware\n\n✔️ &nbsp;**Minimal:** Small, tree-shakable and zero-dependency\n\n✔️ &nbsp;**Modern:** Native promise support\n\n✔️ &nbsp;**Extendable:** Ships with a set of composable utilities but can be extended\n\n✔️ &nbsp;**Router:** Super fast route matching using [unjs/radix3](https://github.com/unjs/radix3)\n\n## Install\n\n```bash\n# Using npm\nnpm install h3\n\n# Using pnpm\npnpm add h3\n\n# Using pnpm\npnpm add h3\n```\n\n## Usage\n\n```ts\nimport { createServer } from 'http'\nimport { createApp } from 'h3'\n\nconst app = createApp()\napp.use('/', () => 'Hello world!')\n\ncreateServer(app).listen(process.env.PORT || 3000)\n```\n\n<details>\n <summary>Example using <a href=\"https://github.com/unjs/listhen\">listhen</a> for an elegant listener.</summary>\n\n```ts\nimport { createApp } from 'h3'\nimport { listen } from 'listhen'\n\nconst app = createApp()\napp.use('/', () => 'Hello world!')\n\nlisten(app)\n```\n</details>\n\n## Router\n\nThe `app` instance created by `h3` uses a middleware stack (see [how it works](#how-it-works)) with the ability to match route prefix and apply matched middleware.\n\nTo opt-in using a more advanced and convenient routing system, we can create a router instance and register it to app instance.\n\n```ts\nimport { createApp, createRouter } from 'h3'\n\nconst app = createApp()\n\nconst router = createRouter()\n .get('/', () => 'Hello World!')\n .get('/hello/:name', req => `Hello ${req.params.name}!`)\n\napp.use(router)\n```\n\n**Tip:** We can register same route more than once with different methods.\n\nRoutes are internally stored in a [Radix Tree](https://en.wikipedia.org/wiki/Radix_tree) and matched using [unjs/radix3](https://github.com/unjs/radix3).\n\n## More usage examples\n\n```js\n// Handle can directly return object or Promise<object> for JSON response\napp.use('/api', (req) => ({ url: req.url }))\n\n// We can have better matching other than quick prefix match\napp.use('/odd', () => 'Is odd!', { match: url => url.substr(1) % 2 })\n\n// Handle can directly return string for HTML response\napp.use(() => '<h1>Hello world!</h1>')\n\n// We can chain calls to .use()\napp.use('/1', () => '<h1>Hello world!</h1>')\n .use('/2', () => '<h1>Goodbye!</h1>')\n\n// Legacy middleware with 3rd argument are automatically promisified\napp.use((req, res, next) => { req.setHeader('X-Foo', 'bar'); next() })\n\n// Force promisify a legacy middleware\n// app.use(someMiddleware, { promisify: true })\n\n// Lazy loaded routes using { lazy: true }\n// app.use('/big', () => import('./big'), { lazy: true })\n```\n\n## Utilities\n\nInstead of adding helpers to `req` and `res`, h3 exposes them as composable utilities.\n\n- `useRawBody(req, encoding?)`\n- `useBody(req)`\n- `useCookies(req)`\n- `useCookie(req, name)`\n- `setCookie(res, name, value, opts?)`\n- `deleteCookie(res, name, opts?)`\n- `useQuery(req)`\n- `send(res, data, type?)`\n- `sendRedirect(res, location, code=302)`\n- `appendHeader(res, name, value)`\n- `createError({ statusCode, statusMessage, data? })`\n- `sendError(res, error, debug?)`\n- `defineHandle(handle)`\n- `defineMiddleware(middlware)`\n- `useMethod(req, default?)`\n- `isMethod(req, expected, allowHead?)`\n- `assertMethod(req, expected, allowHead?)`\n\n👉 You can learn more about usage in [JSDocs Documentation](https://www.jsdocs.io/package/h3#package-functions).\n\n## How it works?\n\nUsing `createApp`, it returns a standard `(req, res)` handler function and internally an array called middleware stack. using`use()` method we can add an item to this internal stack.\n\nWhen a request comes, each stack item that matches the route will be called and resolved until [`res.writableEnded`](https://nodejs.org/api/http.html#http_response_writableended) flag is set, which means the response is sent. If `writableEnded` is not set after all middleware, a `404` error will be thrown. And if one of the stack items resolves to a value, it will be serialized and sent as response as a shorthand method to sending responses.\n\nFor maximum compatibility with connect/express middleware (`req, res, next?` signature), h3 converts classic middleware into a promisified version ready to use with stack runner:\n\n- If middleware has 3rd next/callback param, the promise will `resolve/reject` when called\n- If middleware returns a promise, it will be **chained** to the main promise\n- If calling middleware throws an immediate error, the promise will be rejected\n- On `close` and `error` events of res, the promise will `resolve/reject` (to ensure if middleware simply calls `res.end`)\n\n## License\n\nMIT\n"
"readme": "[![npm downloads](https://img.shields.io/npm/dm/h3.svg?style=flat-square)](https://npmjs.com/package/h3)\n[![version](https://img.shields.io/npm/v/h3/latest.svg?style=flat-square)](https://npmjs.com/package/h3)\n[![bundlephobia](https://img.shields.io/bundlephobia/min/h3/latest.svg?style=flat-square)](https://bundlephobia.com/result?p=h3)\n[![build status](https://img.shields.io/github/workflow/status/unjs/h3/ci/main?style=flat-square)](https://github.com/unjs/h3/actions)\n[![coverage](https://img.shields.io/codecov/c/gh/unjs/h3/main?style=flat-square)](https://codecov.io/gh/unjs/h3)\n[![jsDocs.io](https://img.shields.io/badge/jsDocs.io-reference-blue?style=flat-square)](https://www.jsdocs.io/package/h3)\n\n> H3 is a minimal h(ttp) framework built for high performance and portability\n\n<!-- ![h3 - Tiny JavaScript Server](.github/banner.svg) -->\n\n## Features\n\n✔️ &nbsp;**Portable:** Works perfectly in Serverless, Workers, and Node.js\n\n✔️ &nbsp;**Compatible:** Support connect/express middleware\n\n✔️ &nbsp;**Minimal:** Small, tree-shakable and zero-dependency\n\n✔️ &nbsp;**Modern:** Native promise support\n\n✔️ &nbsp;**Extendable:** Ships with a set of composable utilities but can be extended\n\n✔️ &nbsp;**Router:** Super fast route matching using [unjs/radix3](https://github.com/unjs/radix3)\n\n## Install\n\n```bash\n# Using npm\nnpm install h3\n\n# Using yarn\nyarn add h3\n\n# Using pnpm\npnpm add h3\n```\n\n## Usage\n\n```ts\nimport { createServer } from 'http'\nimport { createApp } from 'h3'\n\nconst app = createApp()\napp.use('/', () => 'Hello world!')\n\ncreateServer(app).listen(process.env.PORT || 3000)\n```\n\n<details>\n <summary>Example using <a href=\"https://github.com/unjs/listhen\">listhen</a> for an elegant listener.</summary>\n\n```ts\nimport { createApp } from 'h3'\nimport { listen } from 'listhen'\n\nconst app = createApp()\napp.use('/', () => 'Hello world!')\n\nlisten(app)\n```\n</details>\n\n## Router\n\nThe `app` instance created by `h3` uses a middleware stack (see [how it works](#how-it-works)) with the ability to match route prefix and apply matched middleware.\n\nTo opt-in using a more advanced and convenient routing system, we can create a router instance and register it to app instance.\n\n```ts\nimport { createApp, createRouter } from 'h3'\n\nconst app = createApp()\n\nconst router = createRouter()\n .get('/', () => 'Hello World!')\n .get('/hello/:name', req => `Hello ${req.params.name}!`)\n\napp.use(router)\n```\n\n**Tip:** We can register same route more than once with different methods.\n\nRoutes are internally stored in a [Radix Tree](https://en.wikipedia.org/wiki/Radix_tree) and matched using [unjs/radix3](https://github.com/unjs/radix3).\n\n## More usage examples\n\n```js\n// Handle can directly return object or Promise<object> for JSON response\napp.use('/api', (req) => ({ url: req.url }))\n\n// We can have better matching other than quick prefix match\napp.use('/odd', () => 'Is odd!', { match: url => url.substr(1) % 2 })\n\n// Handle can directly return string for HTML response\napp.use(() => '<h1>Hello world!</h1>')\n\n// We can chain calls to .use()\napp.use('/1', () => '<h1>Hello world!</h1>')\n .use('/2', () => '<h1>Goodbye!</h1>')\n\n// Legacy middleware with 3rd argument are automatically promisified\napp.use((req, res, next) => { req.setHeader('X-Foo', 'bar'); next() })\n\n// Force promisify a legacy middleware\n// app.use(someMiddleware, { promisify: true })\n\n// Lazy loaded routes using { lazy: true }\n// app.use('/big', () => import('./big'), { lazy: true })\n```\n\n## Utilities\n\nInstead of adding helpers to `req` and `res`, h3 exposes them as composable utilities.\n\n- `useRawBody(req, encoding?)`\n- `useBody(req)`\n- `useCookies(req)`\n- `useCookie(req, name)`\n- `setCookie(res, name, value, opts?)`\n- `deleteCookie(res, name, opts?)`\n- `useQuery(req)`\n- `send(res, data, type?)`\n- `sendRedirect(res, location, code=302)`\n- `appendHeader(res, name, value)`\n- `createError({ statusCode, statusMessage, data? })`\n- `sendError(res, error, debug?)`\n- `defineHandle(handle)`\n- `defineMiddleware(middlware)`\n- `useMethod(req, default?)`\n- `isMethod(req, expected, allowHead?)`\n- `assertMethod(req, expected, allowHead?)`\n\n👉 You can learn more about usage in [JSDocs Documentation](https://www.jsdocs.io/package/h3#package-functions).\n\n## How it works?\n\nUsing `createApp`, it returns a standard `(req, res)` handler function and internally an array called middleware stack. using`use()` method we can add an item to this internal stack.\n\nWhen a request comes, each stack item that matches the route will be called and resolved until [`res.writableEnded`](https://nodejs.org/api/http.html#http_response_writableended) flag is set, which means the response is sent. If `writableEnded` is not set after all middleware, a `404` error will be thrown. And if one of the stack items resolves to a value, it will be serialized and sent as response as a shorthand method to sending responses.\n\nFor maximum compatibility with connect/express middleware (`req, res, next?` signature), h3 converts classic middleware into a promisified version ready to use with stack runner:\n\n- If middleware has 3rd next/callback param, the promise will `resolve/reject` when called\n- If middleware returns a promise, it will be **chained** to the main promise\n- If calling middleware throws an immediate error, the promise will be rejected\n- On `close` and `error` events of res, the promise will `resolve/reject` (to ensure if middleware simply calls `res.end`)\n\n## License\n\nMIT\n"
}

@@ -32,4 +32,4 @@ [![npm downloads](https://img.shields.io/npm/dm/h3.svg?style=flat-square)](https://npmjs.com/package/h3)

# Using pnpm
pnpm add h3
# Using yarn
yarn add h3

@@ -36,0 +36,0 @@ # Using pnpm

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