h3 1.10.2 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,354 +1,48 @@
1
1
  # H3
2
2
 
3
- [![npm version][npm-version-src]][npm-version-href]
4
- [![npm downloads][npm-downloads-src]][npm-downloads-href]
5
- [![bundle][bundle-src]][bundle-href]
6
- [![Codecov][codecov-src]][codecov-href]
7
- [![License][license-src]][license-href]
8
- [![JSDocs][jsdocs-src]][jsdocs-href]
3
+ <!-- automd:badges -->
9
4
 
10
- H3 (pronounced as /eɪtʃθriː/, like h-3) is a minimal h(ttp) framework built for high performance and portability.
11
-
12
- 👉 [Online Playground](https://stackblitz.com/github/unjs/h3/tree/main/playground)
13
-
14
- 👉 [Online Examples Playground](https://stackblitz.com/github/unjs/h3/tree/main/examples)
15
-
16
- ## Features
17
-
18
- ✔️ &nbsp;**Portable:** Works perfectly in Serverless, Workers, and Node.js
19
-
20
- ✔️ &nbsp;**Minimal:** Small and tree-shakable
21
-
22
- ✔️ &nbsp;**Modern:** Native promise support
23
-
24
- ✔️ &nbsp;**Extendable:** Ships with a set of composable utilities but can be extended
25
-
26
- ✔️ &nbsp;**Router:** Super fast route matching using [unjs/radix3](https://github.com/unjs/radix3)
5
+ [![npm version](https://flat.badgen.net/npm/v/h3)](https://npmjs.com/package/h3)
6
+ [![npm downloads](https://flat.badgen.net/npm/dm/h3)](https://npmjs.com/package/h3)
27
7
 
28
- ✔️ &nbsp;**Compatible:** Compatibility layer with node/connect/express middleware
8
+ <!-- /automd -->
29
9
 
30
- ## Install
31
-
32
- ```bash
33
- # Using npm
34
- npm install h3
10
+ H3 (pronounced as /eɪtʃθriː/, like h-3) is a minimal h(ttp) framework built for high performance and portability.
35
11
 
36
- # Using yarn
37
- yarn add h3
12
+ 👉 [Documentation](https://h3.unjs.io)
38
13
 
39
- # Using pnpm
40
- pnpm add h3
41
- ```
14
+ ## Contribution
42
15
 
43
16
  <details>
44
- <summary>Using Nightly Releases</summary>
45
-
46
- If you are directly using `h3` as a dependency:
47
-
48
- ```json
49
- {
50
- "dependencies": {
51
- "h3": "npm:h3-nightly@latest"
52
- }
53
- }
54
- ```
55
-
56
- If you are using a framework ([Nuxt](https://nuxt.com/) or [Nitro](https://nitro.unjs.io/)) that is using `h3`:
57
-
58
- pnpm and yarn:
59
-
60
- ```json
61
- {
62
- "resolutions": {
63
- "h3": "npm:h3-nightly@latest"
64
- }
65
- }
66
- ```
67
-
68
- npm:
69
-
70
- ```json
71
- {
72
- "overrides": {
73
- "h3": "npm:h3-nightly@latest"
74
- }
75
- }
76
- ```
17
+ <summary>Local development</summary>
77
18
 
78
- **Note:** Make sure to recreate lockfile and `node_modules` after reinstall to avoid hoisting issues.
19
+ - Clone this repository
20
+ - Install the latest LTS version of [Node.js](https://nodejs.org/en/)
21
+ - Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable`
22
+ - Install dependencies using `pnpm install`
23
+ - Run tests using `pnpm dev` or `pnpm test`
79
24
 
80
25
  </details>
81
26
 
82
- ## Usage
83
-
84
- ```ts
85
- import { createServer } from "node:http";
86
- import { createApp, eventHandler, toNodeListener } from "h3";
87
-
88
- const app = createApp();
89
- app.use(
90
- "/",
91
- eventHandler(() => "Hello world!"),
92
- );
93
-
94
- createServer(toNodeListener(app)).listen(process.env.PORT || 3000);
95
- ```
96
-
97
- Example using <a href="https://github.com/unjs/listhen">listhen</a> for an elegant listener:
98
-
99
- ```ts
100
- import { createApp, eventHandler, toNodeListener } from "h3";
101
- import { listen } from "listhen";
102
-
103
- const app = createApp();
104
- app.use(
105
- "/",
106
- eventHandler(() => "Hello world!"),
107
- );
108
-
109
- listen(toNodeListener(app));
110
- ```
111
-
112
- ## Router
113
-
114
- 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.
115
-
116
- To opt-in using a more advanced and convenient routing system, we can create a router instance and register it to app instance.
117
-
118
- ```ts
119
- import { createApp, eventHandler, createRouter } from "h3";
120
-
121
- const app = createApp();
122
-
123
- const router = createRouter()
124
- .get(
125
- "/",
126
- eventHandler(() => "Hello World!"),
127
- )
128
- .get(
129
- "/hello/:name",
130
- eventHandler((event) => `Hello ${event.context.params.name}!`),
131
- );
132
-
133
- app.use(router);
134
- ```
135
-
136
- **Tip:** We can register the same route more than once with different methods.
137
-
138
- 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).
139
-
140
- For using nested routers, see [this example](./examples/nested-router.ts)
141
-
142
- ## More app usage examples
27
+ <!-- /automd -->
143
28
 
144
- ```js
145
- // Handle can directly return object or Promise<object> for JSON response
146
- app.use(
147
- "/api",
148
- eventHandler((event) => ({ url: event.node.req.url })),
149
- );
150
-
151
- // We can have better matching other than quick prefix match
152
- app.use(
153
- "/odd",
154
- eventHandler(() => "Is odd!"),
155
- { match: (url) => url.substr(1) % 2 },
156
- );
157
-
158
- // Handle can directly return string for HTML response
159
- app.use(eventHandler(() => "<h1>Hello world!</h1>"));
160
-
161
- // We can chain calls to .use()
162
- app
163
- .use(
164
- "/1",
165
- eventHandler(() => "<h1>Hello world!</h1>"),
166
- )
167
- .use(
168
- "/2",
169
- eventHandler(() => "<h1>Goodbye!</h1>"),
170
- );
171
-
172
- // We can proxy requests and rewrite cookie's domain and path
173
- app.use(
174
- "/api",
175
- eventHandler((event) =>
176
- proxyRequest(event, "https://example.com", {
177
- // f.e. keep one domain unchanged, rewrite one domain and remove other domains
178
- cookieDomainRewrite: {
179
- "example.com": "example.com",
180
- "example.com": "somecompany.co.uk",
181
- "*": "",
182
- },
183
- cookiePathRewrite: {
184
- "/": "/api",
185
- },
186
- }),
187
- ),
188
- );
189
-
190
- // Legacy middleware with 3rd argument are automatically promisified
191
- app.use(
192
- fromNodeMiddleware((req, res, next) => {
193
- req.setHeader("x-foo", "bar");
194
- next();
195
- }),
196
- );
197
-
198
- // Lazy loaded routes using { lazy: true }
199
- app.use("/big", () => import("./big-handler"), { lazy: true });
200
- ```
201
-
202
- ## Utilities
203
-
204
- 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.
205
-
206
- 👉 You can check list of exported built-in utils from [JSDocs Documentation](https://www.jsdocs.io/package/h3#package-functions).
207
-
208
- #### Body
209
-
210
- - `readRawBody(event, encoding?)`
211
- - `readBody(event)`
212
- - `readValidatedBody(event, validate)`
213
- - `readMultipartFormData(event)`
214
-
215
- #### Request
216
-
217
- - `getQuery(event)`
218
- - `getValidatedQuery(event, validate)`
219
- - `getRouterParams(event, { decode? })`
220
- - `getRouterParam(event, name, { decode? })`
221
- - `getValidatedRouterParams(event, validate, { decode? })`
222
- - `getMethod(event, default?)`
223
- - `isMethod(event, expected, allowHead?)`
224
- - `assertMethod(event, expected, allowHead?)`
225
- - `getRequestHeaders(event)` (alias: `getHeaders`)
226
- - `getRequestHeader(event, name)` (alias: `getHeader`)
227
- - `getRequestURL(event)`
228
- - `getRequestHost(event)`
229
- - `getRequestProtocol(event)`
230
- - `getRequestPath(event)`
231
- - `getRequestIP(event, { xForwardedFor: boolean })`
232
-
233
- #### Response
234
-
235
- - `send(event, data, type?)`
236
- - `sendNoContent(event, code = 204)`
237
- - `setResponseStatus(event, status)`
238
- - `getResponseStatus(event)`
239
- - `getResponseStatusText(event)`
240
- - `getResponseHeaders(event)`
241
- - `getResponseHeader(event, name)`
242
- - `setResponseHeaders(event, headers)` (alias: `setHeaders`)
243
- - `setResponseHeader(event, name, value)` (alias: `setHeader`)
244
- - `appendResponseHeaders(event, headers)` (alias: `appendHeaders`)
245
- - `appendResponseHeader(event, name, value)` (alias: `appendHeader`)
246
- - `defaultContentType(event, type)`
247
- - `sendRedirect(event, location, code=302)`
248
- - `isStream(data)`
249
- - `sendStream(event, data)`
250
- - `writeEarlyHints(event, links, callback)`
251
-
252
- #### Sanitize
253
-
254
- - `sanitizeStatusMessage(statusMessage)`
255
- - `sanitizeStatusCode(statusCode, default = 200)`
256
-
257
- #### Error
258
-
259
- - `sendError(event, error, debug?)`
260
- - `createError({ statusCode, statusMessage, data? })`
261
-
262
- #### Route
263
-
264
- - `useBase(base, handler)`
265
-
266
- #### Proxy
267
-
268
- - `sendProxy(event, { target, ...options })`
269
- - `proxyRequest(event, { target, ...options })`
270
- - `fetchWithEvent(event, req, init, { fetch? }?)`
271
- - `getProxyRequestHeaders(event)`
272
-
273
- #### Cookie
274
-
275
- - `parseCookies(event)`
276
- - `getCookie(event, name)`
277
- - `setCookie(event, name, value, opts?)`
278
- - `deleteCookie(event, name, opts?)`
279
- - `splitCookiesString(cookiesString)`
280
-
281
- #### Session
282
-
283
- - `useSession(event, config = { password, maxAge?, name?, cookie?, seal?, crypto? })`
284
- - `getSession(event, config)`
285
- - `updateSession(event, config, update)`
286
- - `sealSession(event, config)`
287
- - `unsealSession(event, config, sealed)`
288
- - `clearSession(event, config)`
289
-
290
- #### Cache
291
-
292
- - `handleCacheHeaders(event, opts)`
293
-
294
- #### Cors
295
-
296
- - `handleCors(options)` (see [h3-cors](https://github.com/NozomuIkuta/h3-cors) for more detail about options)
297
- - `isPreflightRequest(event)`
298
- - `isCorsOriginAllowed(event)`
299
- - `appendCorsHeaders(event, options)` (see [h3-cors](https://github.com/NozomuIkuta/h3-cors) for more detail about options)
300
- - `appendCorsPreflightHeaders(event, options)` (see [h3-cors](https://github.com/NozomuIkuta/h3-cors) for more detail about options)
301
-
302
- ## Community Packages
303
-
304
- You can use more H3 event utilities made by the community.
29
+ ## License
305
30
 
306
- Please check their READMEs for more details.
31
+ <!-- automd:contributors license=MIT author="pi0" -->
307
32
 
308
- PRs are welcome to add your packages.
33
+ Published under the [MIT](https://github.com/unjs/h3/blob/main/LICENSE) license.
34
+ Made by [@pi0](https://github.com/pi0) and [community](https://github.com/unjs/h3/graphs/contributors) 💛
35
+ <br><br>
36
+ <a href="https://github.com/unjs/h3/graphs/contributors">
37
+ <img src="https://contrib.rocks/image?repo=unjs/h3" />
38
+ </a>
309
39
 
310
- - [h3-typebox](https://github.com/kevinmarrec/h3-typebox)
311
- - `validateBody(event, schema)`
312
- - `validateQuery(event, schema)`
313
- - [h3-zod](https://github.com/wobsoriano/h3-zod)
314
- - `useValidatedBody(event, schema)`
315
- - `useValidatedQuery(event, schema)`
316
- - [h3-valibot](https://github.com/intevel/h3-valibot)
317
- - `useValidateBody(event, schema)`
318
- - `useValidateParams(event, schema)`
319
- - [h3-compression](https://github.com/CodeDredd/h3-compression)
320
- - `useGZipCompression(event, response)`
321
- - `useDeflateCompression(event, response)`
322
- - `useBrotliCompression(event, response)`
323
- - `useCompression(event, response)`
324
- - `useGZipCompressionStream(event, response)`
325
- - `useDeflateCompressionStream(event, response)`
326
- - `useCompressionStream(event, response)`
327
- - [@intlify/h3](https://github.com/intlify/h3)
328
- - `defineI18nMiddleware(options)`
329
- - `useTranslation(event)`
330
- - `getHeaderLocale(event, options)`
331
- - `getHeaderLocales(event, options)`
332
- - `getCookieLocale(event, options)`
333
- - `setCookieLocale(event, options)`
334
- - `getPathLocale(event, options)`
335
- - `getQueryLocale(event, options)`
40
+ <!-- /automd -->
336
41
 
337
- ## License
42
+ <!-- automd:with-automd -->
338
43
 
339
- MIT
44
+ ---
340
45
 
341
- <!-- Badges -->
46
+ _🤖 auto updated with [automd](https://automd.unjs.io)_
342
47
 
343
- [npm-version-src]: https://img.shields.io/npm/v/h3?style=flat&colorA=18181B&colorB=F0DB4F
344
- [npm-version-href]: https://npmjs.com/package/h3
345
- [npm-downloads-src]: https://img.shields.io/npm/dm/h3?style=flat&colorA=18181B&colorB=F0DB4F
346
- [npm-downloads-href]: https://npmjs.com/package/h3
347
- [codecov-src]: https://img.shields.io/codecov/c/gh/unjs/h3/main?style=flat&colorA=18181B&colorB=F0DB4F
348
- [codecov-href]: https://codecov.io/gh/unjs/h3
349
- [bundle-src]: https://img.shields.io/bundlephobia/minzip/h3?style=flat&colorA=18181B&colorB=F0DB4F
350
- [bundle-href]: https://bundlephobia.com/result?p=h3
351
- [license-src]: https://img.shields.io/github/license/unjs/h3.svg?style=flat&colorA=18181B&colorB=F0DB4F
352
- [license-href]: https://github.com/unjs/h3/blob/main/LICENSE
353
- [jsdocs-src]: https://img.shields.io/badge/jsDocs.io-reference-18181B?style=flat&colorA=18181B&colorB=F0DB4F
354
- [jsdocs-href]: https://www.jsdocs.io/package/h3
48
+ <!-- /automd -->