diff --git a/.config/automd.yaml b/.config/automd.yaml
new file mode 100644
index 00000000..63e39fe7
--- /dev/null
+++ b/.config/automd.yaml
@@ -0,0 +1 @@
+input: ["README.md", "docs/**/*.md"]
diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml
index 5cb2623f..55b1a12e 100644
--- a/.github/workflows/autofix.yml
+++ b/.github/workflows/autofix.yml
@@ -16,11 +16,11 @@ jobs:
- run: corepack enable
- uses: actions/setup-node@v4
with:
- node-version: 18
+ node-version: 20
cache: "pnpm"
- run: pnpm install
- - name: Fix lint issues
- run: pnpm run lint:fix
+ - run: pnpm run lint:fix
+ - run: pnpm automd
- uses: autofix-ci/action@ea32e3a12414e6d3183163c3424a7d7a8631ad84
with:
- commit-message: "chore: apply automated fixes"
+ commit-message: "chore: apply automated updates"
diff --git a/README.md b/README.md
index 2f3d0fd6..9acfb81b 100644
--- a/README.md
+++ b/README.md
@@ -1,47 +1,48 @@
# 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]
+
+
+[![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)
+
+
H3 (pronounced as /eΙͺtΚΞΈriΛ/, like h-3) is a minimal h(ttp) framework built for high performance and portability.
-π [Online Playground](https://stackblitz.com/github/unjs/h3/tree/main/playground)
+π [Documentation](https://h3.unjs.io)
-π [Online Examples Playground](https://stackblitz.com/github/unjs/h3/tree/main/examples)
+## Contribution
-## Features
+
+ Local development
-βοΈ **Portable:** Works perfectly in Serverless, Workers, and Node.js
+- 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`
-βοΈ **Minimal:** Small and tree-shakable
+
-βοΈ **Modern:** Native promise support
+
-βοΈ **Extendable:** Ships with a set of composable utilities but can be extended
+## License
-βοΈ **Router:** Super fast route matching using [unjs/radix3](https://github.com/unjs/radix3)
+
-βοΈ **Compatible:** Compatibility layer with node/connect/express middleware
+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) π
+
+
+
+
-## License
+
+
+
+
+---
+
+_π€ auto updated with [automd](https://automd.unjs.io)_
-MIT
-
-
-
-[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
+
diff --git a/docs/2.utils/1.request.md b/docs/2.utils/1.request.md
index e281454e..1dca82d5 100644
--- a/docs/2.utils/1.request.md
+++ b/docs/2.utils/1.request.md
@@ -2,7 +2,7 @@
> Utilities to access incoming request
-
+
### `assertMethod(event, expected, allowHead?)`
@@ -38,7 +38,7 @@
-
+
### `getRequestFingerprint(event, opts)`
@@ -46,7 +46,7 @@
## Body utils
-
+
### `getRequestWebStream(event)`
diff --git a/docs/2.utils/2.reponse.md b/docs/2.utils/2.reponse.md
index a8010000..a432f0a3 100644
--- a/docs/2.utils/2.reponse.md
+++ b/docs/2.utils/2.reponse.md
@@ -2,7 +2,7 @@
> Utilities to send response headers and data
-
+
### `appendHeader(event, name, value)`
diff --git a/docs/2.utils/98.advanced.md b/docs/2.utils/98.advanced.md
index fbc33f68..d9029207 100644
--- a/docs/2.utils/98.advanced.md
+++ b/docs/2.utils/98.advanced.md
@@ -4,7 +4,7 @@
## Session utils
-
+
### `clearSession(event, config)`
@@ -22,7 +22,7 @@
## Cookie utils
-
+
### `deleteCookie(event, name, serializeOptions?)`
@@ -42,13 +42,13 @@ Set a cookie value by name.
### `splitCookiesString(cookiesString)`
-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
+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
## Sanitize
-
+
### `sanitizeStatusCode(statusCode?, defaultStatusCode)`
@@ -58,7 +58,7 @@ Set-Cookie header field-values are sometimes comma joined in one string. This sp
## Route
-
+
### `useBase(base, handler)`
@@ -68,7 +68,7 @@ Prefixes and executes a handler with a base path.
## Cache
-
+
### `handleCacheHeaders(event, opts)`
@@ -78,7 +78,7 @@ Check request caching headers (`If-Modified-Since`) and add caching headers (Las
## Proxy
-
+
### `fetchWithEvent(event, req, init?, options?: { fetch: F })`
@@ -92,7 +92,7 @@ Check request caching headers (`If-Modified-Since`) and add caching headers (Las
## CORS
-
+
### `appendCorsHeaders(event, options)`
diff --git a/package.json b/package.json
index 1d3dbd6d..8b404eb0 100644
--- a/package.json
+++ b/package.json
@@ -48,6 +48,7 @@
"@types/supertest": "^6.0.2",
"@vitest/coverage-v8": "^1.3.1",
"autocannon": "^7.15.0",
+ "automd": "^0.3.5",
"changelogen": "^0.5.5",
"connect": "^3.7.0",
"eslint": "^8.56.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d1ce55ed..26ab8975 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -54,6 +54,9 @@ importers:
autocannon:
specifier: ^7.15.0
version: 7.15.0
+ automd:
+ specifier: ^0.3.5
+ version: 0.3.5
changelogen:
specifier: ^0.5.5
version: 0.5.5
@@ -339,6 +342,13 @@ packages:
'@babel/types': 7.23.9
dev: true
+ /@babel/runtime@7.23.9:
+ resolution: {integrity: sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ regenerator-runtime: 0.14.1
+ dev: true
+
/@babel/standalone@7.23.9:
resolution: {integrity: sha512-89NGhVfgKDqDQrtNPxqfnhIReKvp2CR80ofPNEAUpbtnouFelq33hQFURLralD9I+eFS7s5zVK61JRg/D1nLWg==}
engines: {node: '>=6.9.0'}
@@ -1055,6 +1065,11 @@ packages:
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
dev: true
+ /@sindresorhus/merge-streams@2.3.0:
+ resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==}
+ engines: {node: '>=18'}
+ dev: true
+
/@trysound/sax@0.2.0:
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
engines: {node: '>=10.13.0'}
@@ -1625,6 +1640,30 @@ packages:
timestring: 6.0.0
dev: true
+ /automd@0.3.5:
+ resolution: {integrity: sha512-JScZoTTu8Skf49zqFfRUJVShGfiAWDMAi7FtXyLWSo2t+bBe+zZjK+lZbYhWoBcFwH8m0oJSKT6N1SndglUJ8A==}
+ hasBin: true
+ dependencies:
+ '@parcel/watcher': 2.4.0
+ c12: 1.9.0
+ citty: 0.1.5
+ consola: 3.2.3
+ defu: 6.1.4
+ destr: 2.0.3
+ didyoumean2: 6.0.1
+ globby: 14.0.1
+ magic-string: 0.30.7
+ mlly: 1.6.0
+ ofetch: 1.3.3
+ omark: 0.1.0
+ pathe: 1.1.2
+ pkg-types: 1.0.3
+ scule: 1.3.0
+ untyped: 1.4.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/autoprefixer@10.4.17(postcss@8.4.33):
resolution: {integrity: sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==}
engines: {node: ^10 || ^12 || >=14}
@@ -1935,6 +1974,23 @@ packages:
rc9: 2.1.1
dev: true
+ /c12@1.9.0:
+ resolution: {integrity: sha512-7KTCZXdIbOA2hLRQ+1KzJ15Qp9Wn58one74dkihMVp2H6EzKTa3OYBy0BSfS1CCcmxYyqeX8L02m40zjQ+dstg==}
+ dependencies:
+ chokidar: 3.5.3
+ confbox: 0.1.3
+ defu: 6.1.4
+ dotenv: 16.4.1
+ giget: 1.2.1
+ jiti: 1.21.0
+ mlly: 1.6.0
+ ohash: 1.1.3
+ pathe: 1.1.2
+ perfect-debounce: 1.0.0
+ pkg-types: 1.0.3
+ rc9: 2.1.1
+ dev: true
+
/cac@6.7.14:
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
engines: {node: '>=8'}
@@ -2210,6 +2266,10 @@ packages:
typedarray: 0.0.6
dev: true
+ /confbox@0.1.3:
+ resolution: {integrity: sha512-eH3ZxAihl1PhKfpr4VfEN6/vUd87fmgb6JkldHgg/YR6aEBhW63qUDgzP2Y6WM0UumdsYp5H3kibalXAdHfbgg==}
+ dev: true
+
/connect@3.7.0:
resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==}
engines: {node: '>= 0.10.0'}
@@ -2730,6 +2790,15 @@ packages:
wrappy: 1.0.2
dev: true
+ /didyoumean2@6.0.1:
+ resolution: {integrity: sha512-PSy0zQwMg5O+LjT5Mz7vnKC8I7DfWLPF6M7oepqW7WP5mn2CY3hz46xZOa1GJY+KVfyXhdmz6+tdgXwrHlZc5g==}
+ engines: {node: ^16.14.0 || >=18.12.0}
+ dependencies:
+ '@babel/runtime': 7.23.9
+ fastest-levenshtein: 1.0.16
+ lodash.deburr: 4.1.0
+ dev: true
+
/diff-sequences@29.6.3:
resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -3505,6 +3574,11 @@ packages:
resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
dev: true
+ /fastest-levenshtein@1.0.16:
+ resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==}
+ engines: {node: '>= 4.9.1'}
+ dev: true
+
/fastq@1.16.0:
resolution: {integrity: sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==}
dependencies:
@@ -3826,6 +3900,18 @@ packages:
slash: 4.0.0
dev: true
+ /globby@14.0.1:
+ resolution: {integrity: sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==}
+ engines: {node: '>=18'}
+ dependencies:
+ '@sindresorhus/merge-streams': 2.3.0
+ fast-glob: 3.3.2
+ ignore: 5.3.0
+ path-type: 5.0.0
+ slash: 5.1.0
+ unicorn-magic: 0.1.0
+ dev: true
+
/gopd@1.0.1:
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
dependencies:
@@ -4605,6 +4691,10 @@ packages:
resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
dev: true
+ /lodash.deburr@4.1.0:
+ resolution: {integrity: sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==}
+ dev: true
+
/lodash.flatten@4.4.0:
resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==}
dev: true
@@ -4672,6 +4762,13 @@ packages:
'@jridgewell/sourcemap-codec': 1.4.15
dev: true
+ /magic-string@0.30.7:
+ resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==}
+ engines: {node: '>=12'}
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.4.15
+ dev: true
+
/magicast@0.3.3:
resolution: {integrity: sha512-ZbrP1Qxnpoes8sz47AM0z08U+jW6TyRgZzcWy3Ma3vDhJttwMwAFDMMQFobwdBxByBD46JYmxRzeF7w2+wJEuw==}
dependencies:
@@ -4891,6 +4988,14 @@ packages:
pkg-types: 1.0.3
ufo: 1.4.0
+ /mlly@1.6.0:
+ resolution: {integrity: sha512-YOvg9hfYQmnaB56Yb+KrJE2u0Yzz5zR+sLejEvF4fzwzV1Al6hkf2vyHTwqCRyv0hCi9rVCqVoXpyYevQIRwLQ==}
+ dependencies:
+ acorn: 8.11.3
+ pathe: 1.1.2
+ pkg-types: 1.0.3
+ ufo: 1.4.0
+
/module-deps@6.2.3:
resolution: {integrity: sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==}
engines: {node: '>= 0.8.0'}
@@ -5126,6 +5231,10 @@ packages:
/ohash@1.1.3:
resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==}
+ /omark@0.1.0:
+ resolution: {integrity: sha512-l+7hOfsjru88QuW7E937KH7BSz99NownkNTGigi+e4JzeSSCosMp2v3eVW1wdmgm99pFbzaUVg1kiT2V0QvvtQ==}
+ dev: true
+
/on-finished@2.3.0:
resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==}
engines: {node: '>= 0.8'}
@@ -5319,6 +5428,11 @@ packages:
engines: {node: '>=8'}
dev: true
+ /path-type@5.0.0:
+ resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==}
+ engines: {node: '>=12'}
+ dev: true
+
/pathe@1.1.2:
resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
@@ -5353,7 +5467,7 @@ packages:
resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==}
dependencies:
jsonc-parser: 3.2.1
- mlly: 1.5.0
+ mlly: 1.6.0
pathe: 1.1.2
/pluralize@8.0.0:
@@ -5906,6 +6020,10 @@ packages:
picomatch: 2.3.1
dev: true
+ /regenerator-runtime@0.14.1:
+ resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
+ dev: true
+
/regexp-tree@0.1.27:
resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==}
hasBin: true
@@ -6087,6 +6205,10 @@ packages:
resolution: {integrity: sha512-CRCmi5zHQnSoeCik9565PONMg0kfkvYmcSqrbOJY4txFfy1wvVULV4FDaiXhUblUgahdqz3F2NwHZ8i4eBTwUw==}
dev: true
+ /scule@1.3.0:
+ resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==}
+ dev: true
+
/semver@5.7.2:
resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
hasBin: true
@@ -6230,6 +6352,11 @@ packages:
engines: {node: '>=12'}
dev: true
+ /slash@5.1.0:
+ resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==}
+ engines: {node: '>=14.16'}
+ dev: true
+
/source-map-js@1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'}
@@ -6841,6 +6968,11 @@ packages:
node-fetch-native: 1.6.2
pathe: 1.1.2
+ /unicorn-magic@0.1.0:
+ resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
+ engines: {node: '>=18'}
+ dev: true
+
/universalify@2.0.1:
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
engines: {node: '>= 10.0.0'}